From c515a32a83677779efd7799ff4896579da02d0ec Mon Sep 17 00:00:00 2001 From: Garvit Khatri Date: Mon, 6 May 2024 14:31:35 +0530 Subject: [PATCH 1/7] add 7677 experimental support --- package.json | 4 +- .../src/ep-0.6/experiments.ts | 70 ++++++ packages/permissionless-test/src/utils.ts | 31 ++- .../actions/smartAccount/deployContract.ts | 27 ++- .../prepareUserOperationRequest.ts | 212 ++++++++++++++++-- .../actions/smartAccount/sendTransaction.ts | 24 +- .../actions/smartAccount/sendTransactions.ts | 23 +- .../actions/smartAccount/sendUserOperation.ts | 21 +- .../actions/smartAccount/writeContract.ts | 14 +- .../clients/createSmartAccountClient.ts | 15 +- .../clients/decorators/smartAccount.ts | 50 ++++- .../errors/sendUserOperation.ts | 2 +- .../eip7677/actions/getPaymasterData.ts | 126 +++++++++++ .../eip7677/actions/getPaymasterStubData.ts | 130 +++++++++++ .../eip7677/clients/createEip7677Client.ts | 40 ++++ .../eip7677/clients/decorators/eip7677.ts | 70 ++++++ .../experimental/eip7677/index.ts | 33 +++ .../experimental/eip7677/types/paymaster.ts | 61 +++++ packages/permissionless/experimental/index.ts | 1 + packages/permissionless/package.json | 5 + 20 files changed, 887 insertions(+), 72 deletions(-) create mode 100644 packages/permissionless-test/src/ep-0.6/experiments.ts create mode 100644 packages/permissionless/experimental/eip7677/actions/getPaymasterData.ts create mode 100644 packages/permissionless/experimental/eip7677/actions/getPaymasterStubData.ts create mode 100644 packages/permissionless/experimental/eip7677/clients/createEip7677Client.ts create mode 100644 packages/permissionless/experimental/eip7677/clients/decorators/eip7677.ts create mode 100644 packages/permissionless/experimental/eip7677/index.ts create mode 100644 packages/permissionless/experimental/eip7677/types/paymaster.ts create mode 100644 packages/permissionless/experimental/index.ts diff --git a/package.json b/package.json index 50473265..7b52d382 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,7 @@ { - "workspaces": ["packages/*"], + "workspaces": [ + "packages/*" + ], "private": true, "author": "Pimlico", "type": "module", diff --git a/packages/permissionless-test/src/ep-0.6/experiments.ts b/packages/permissionless-test/src/ep-0.6/experiments.ts new file mode 100644 index 00000000..d8c59c00 --- /dev/null +++ b/packages/permissionless-test/src/ep-0.6/experiments.ts @@ -0,0 +1,70 @@ +import { + ENTRYPOINT_ADDRESS_V06, + createSmartAccountClient +} from "permissionless" +import { privateKeyToSafeSmartAccount } from "permissionless/accounts" +import type { Eip7677Client } from "permissionless/experimental" +import type { ENTRYPOINT_ADDRESS_V06_TYPE } from "permissionless/types" +import { http, type Chain, zeroAddress } from "viem" +import { generatePrivateKey } from "viem/accounts" +import { foundry } from "viem/chains" +import { beforeAll, describe, test } from "vitest" +import type { AAParamType } from "../types" +import { + getEip7677Client, + getPimlicoPaymasterClient, + getPublicClient, + getSafeClient +} from "../utils" + +describe.each([ + { + name: "Eip 7677 client", + + getSmartAccountClient: async ( + conf: AAParamType + ) => getSafeClient(conf) + } +])("$name test", ({ name, getSmartAccountClient }) => { + let eip7677Client: Eip7677Client + + beforeAll(async () => { + eip7677Client = await getEip7677Client({ + entryPoint: ENTRYPOINT_ADDRESS_V06 + }) + }) + + test("Can get stab data", async () => { + const publicClient = getPublicClient() + + const smartAccount = await privateKeyToSafeSmartAccount(publicClient, { + safeVersion: "1.4.1", + entryPoint: ENTRYPOINT_ADDRESS_V06, + privateKey: generatePrivateKey() + }) + const ALTO_RPC = "http://localhost:4337" + + const paymasterClient = getPimlicoPaymasterClient( + ENTRYPOINT_ADDRESS_V06 + ) + + const smartAccountClient = createSmartAccountClient({ + chain: foundry, + account: smartAccount, + bundlerTransport: http(ALTO_RPC), + eip7677Client: eip7677Client + }) + + // await eip7677Client.getPaymasterStubData({ + // userOperation: await smartClient.prepareUserOperationRequest({ + // userOperation: { + // callData: await smartClient.account.encodeCallData({ + // to: zeroAddress, + // value: 0n, + // data: "0x" + // }) + // } + // }) + // }) + }) +}) diff --git a/packages/permissionless-test/src/utils.ts b/packages/permissionless-test/src/utils.ts index 6955dc34..cf7a29f3 100644 --- a/packages/permissionless-test/src/utils.ts +++ b/packages/permissionless-test/src/utils.ts @@ -22,6 +22,10 @@ import { createPimlicoBundlerClient, createPimlicoPaymasterClient } from "permissionless/clients/pimlico" +import { + type Eip7677Client, + createEip7677Client +} from "permissionless/experimental" import type { ENTRYPOINT_ADDRESS_V06_TYPE, EntryPoint @@ -207,25 +211,22 @@ export const getSimpleAccountClient = async ({ export const getLightAccountClient = async ({ entryPoint, - paymasterClient, privateKey = generatePrivateKey() }: AAParamType): Promise< SmartAccountClient> > => { - const smartAccount = await signerToLightSmartAccount( - publicClient, - { - entryPoint, - signer: privateKeyToAccount(privateKey), - lightAccountVersion: "1.1.0" - } - ) + const smartAccount = await signerToLightSmartAccount(publicClient, { + entryPoint, + signer: privateKeyToAccount(privateKey), + lightAccountVersion: "1.1.0" + }) - // @ts-ignore return createSmartAccountClient({ chain: foundry, account: smartAccount, bundlerTransport: http(ALTO_RPC), + entryPoint: entryPoint, + // eip7677Client: await getEip7677Client({ entryPoint }), middleware: { // @ts-ignore sponsorUserOperation: paymasterClient?.sponsorUserOperation @@ -316,3 +317,13 @@ export const getSafeClient = async ({ } }) } + +export const getEip7677Client = async ({ + entryPoint +}: { entryPoint: TEntryPoint }) => { + return createEip7677Client({ + chain: foundry, + entryPoint, + transport: http(PAYMASTER_RPC) + }) +} diff --git a/packages/permissionless/actions/smartAccount/deployContract.ts b/packages/permissionless/actions/smartAccount/deployContract.ts index 8539e873..0d4fb1bc 100644 --- a/packages/permissionless/actions/smartAccount/deployContract.ts +++ b/packages/permissionless/actions/smartAccount/deployContract.ts @@ -9,24 +9,28 @@ import type { } from "viem" import { getAction } from "viem/utils" import type { SmartAccount } from "../../accounts/types" +import type { Eip7677Client } from "../../experimental" import type { Prettify } from "../../types/" import type { EntryPoint } from "../../types/entrypoint" import { parseAccount } from "../../utils/" import { AccountOrClientNotFoundError } from "../../utils/signUserOperationHashWithECDSA" import { waitForUserOperationReceipt } from "../bundler/waitForUserOperationReceipt" -import { type Middleware } from "./prepareUserOperationRequest" +import type { Middleware } from "./prepareUserOperationRequest" import { sendUserOperation } from "./sendUserOperation" export type DeployContractParametersWithPaymaster< entryPoint extends EntryPoint, - TAbi extends Abi | readonly unknown[] = Abi | readonly unknown[], - TChain extends Chain | undefined = Chain | undefined, TAccount extends SmartAccount | undefined = | SmartAccount | undefined, + TEip7677Client extends Eip7677Client | undefined = + | Eip7677Client + | undefined, + TAbi extends Abi | readonly unknown[] = Abi | readonly unknown[], + TChain extends Chain | undefined = Chain | undefined, TChainOverride extends Chain | undefined = Chain | undefined > = DeployContractParameters & - Middleware + Middleware /** * Deploys a contract to the network, given bytecode and constructor arguments. @@ -59,16 +63,26 @@ export type DeployContractParametersWithPaymaster< export async function deployContract< entryPoint extends EntryPoint, TChain extends Chain | undefined, - TAccount extends SmartAccount | undefined + TAccount extends SmartAccount | undefined, + TEip7677Client extends Eip7677Client | undefined = + | Eip7677Client + | undefined >( client: Client, - args: Prettify> + args: Prettify< + DeployContractParametersWithPaymaster< + entryPoint, + TAccount, + TEip7677Client + > + > ): Promise { const { abi, args: constructorArgs, bytecode, middleware, + eip7677Client, ...request } = args @@ -98,6 +112,7 @@ export async function deployContract< } as EncodeDeployDataParameters) }, account: account, + eip7677Client, middleware }) diff --git a/packages/permissionless/actions/smartAccount/prepareUserOperationRequest.ts b/packages/permissionless/actions/smartAccount/prepareUserOperationRequest.ts index 483cbdab..e3b641ad 100644 --- a/packages/permissionless/actions/smartAccount/prepareUserOperationRequest.ts +++ b/packages/permissionless/actions/smartAccount/prepareUserOperationRequest.ts @@ -1,7 +1,13 @@ import type { Chain, Client, Transport } from "viem" import { estimateFeesPerGas } from "viem/actions" +import type { IsUndefined } from "viem/types/utils" import { getAction } from "viem/utils" import type { SmartAccount } from "../../accounts/types" +import { + type Eip7677Client, + getPaymasterData, + getPaymasterStubData +} from "../../experimental" import type { PartialPick } from "../../types" import type { GetAccountParameter, @@ -52,28 +58,56 @@ export type SponsorUserOperationReturnType = > > -export type Middleware = { - middleware?: - | ((args: { - userOperation: UserOperation> - entryPoint: entryPoint - }) => Promise>>) - | { - gasPrice?: () => Promise<{ - maxFeePerGas: bigint - maxPriorityFeePerGas: bigint - }> - sponsorUserOperation?: (args: { - userOperation: UserOperation> - entryPoint: entryPoint - }) => Promise> - } +type MiddlewareFunction = (args: { + userOperation: UserOperation> + entryPoint: entryPoint +}) => Promise>> + +type MiddlewareObject< + entryPoint extends EntryPoint, + TEip7677Client extends Eip7677Client | undefined +> = IsUndefined extends true + ? + | MiddlewareFunction + | { + gasPrice?: () => Promise<{ + maxFeePerGas: bigint + maxPriorityFeePerGas: bigint + }> + sponsorUserOperation?: (args: { + userOperation: UserOperation< + GetEntryPointVersion + > + entryPoint: entryPoint + }) => Promise> + } + : + | MiddlewareFunction + | { + gasPrice?: () => Promise<{ + maxFeePerGas: bigint + maxPriorityFeePerGas: bigint + }> + sponsorUserOperation: never + } + +export type Middleware< + entryPoint extends EntryPoint, + TEip7677Client extends Eip7677Client | undefined = + | Eip7677Client + | undefined +> = { + eip7677Client?: TEip7677Client + middleware?: MiddlewareObject } export type PrepareUserOperationRequestParameters< entryPoint extends EntryPoint, TAccount extends SmartAccount | undefined = | SmartAccount + | undefined, + TEip7677Client extends Eip7677Client | undefined = + | Eip7677Client | undefined > = { userOperation: entryPoint extends ENTRYPOINT_ADDRESS_V06_TYPE @@ -108,7 +142,7 @@ export type PrepareUserOperationRequestParameters< | "signature" > } & GetAccountParameter & - Middleware + Middleware export type PrepareUserOperationRequestReturnType< entryPoint extends EntryPoint @@ -120,16 +154,26 @@ async function prepareUserOperationRequestForEntryPointV06< TChain extends Chain | undefined = Chain | undefined, TAccount extends SmartAccount | undefined = | SmartAccount + | undefined, + TEip7677Client extends Eip7677Client | undefined = + | Eip7677Client | undefined >( client: Client, - args: Prettify>, + args: Prettify< + PrepareUserOperationRequestParameters< + entryPoint, + TAccount, + TEip7677Client + > + >, stateOverrides?: StateOverrides ): Promise>> { const { account: account_ = client.account, userOperation: partialUserOperation, - middleware + middleware, + eip7677Client } = args if (!account_) throw new AccountOrClientNotFoundError() @@ -189,6 +233,54 @@ async function prepareUserOperationRequestForEntryPointV06< estimateGas.maxPriorityFeePerGas } + if (eip7677Client) { + const stubPaymasterData = await getAction( + eip7677Client, + getPaymasterStubData, + "getPaymasterStubData" + )({ + userOperation, + entryPoint: account.entryPoint + }) + + userOperation.paymasterAndData = stubPaymasterData.paymasterAndData + + const gasParameters = await getAction( + client, + estimateUserOperationGas, + "estimateUserOperationGas" + )( + { + userOperation, + entryPoint: account.entryPoint + } as { + userOperation: UserOperation> + entryPoint: entryPoint + }, + // @ts-ignore getAction takes only two params but when compiled this will work + stateOverrides + ) + + userOperation.callGasLimit |= gasParameters.callGasLimit + userOperation.verificationGasLimit = + userOperation.verificationGasLimit || + gasParameters.verificationGasLimit + userOperation.preVerificationGas = + userOperation.preVerificationGas || gasParameters.preVerificationGas + + const { paymasterAndData } = await getAction( + eip7677Client, + getPaymasterData, + "getPaymasterData" + )({ + userOperation, + entryPoint: account.entryPoint + }) + + userOperation.paymasterAndData = paymasterAndData + return userOperation as PrepareUserOperationRequestReturnType + } + if ( middleware && typeof middleware !== "function" && @@ -257,16 +349,26 @@ async function prepareUserOperationRequestEntryPointV07< TChain extends Chain | undefined = Chain | undefined, TAccount extends SmartAccount | undefined = | SmartAccount + | undefined, + TEip7677Client extends Eip7677Client | undefined = + | Eip7677Client | undefined >( client: Client, - args: Prettify>, + args: Prettify< + PrepareUserOperationRequestParameters< + entryPoint, + TAccount, + TEip7677Client + > + >, stateOverrides?: StateOverrides ): Promise>> { const { account: account_ = client.account, userOperation: partialUserOperation, - middleware + middleware, + eip7677Client } = args if (!account_) throw new AccountOrClientNotFoundError() @@ -338,6 +440,63 @@ async function prepareUserOperationRequestEntryPointV07< estimateGas.maxPriorityFeePerGas } + if (eip7677Client) { + const stubPaymasterData = await getAction( + eip7677Client, + getPaymasterStubData, + "getPaymasterStubData" + )({ + userOperation, + entryPoint: account.entryPoint + }) + userOperation.paymaster = stubPaymasterData.paymaster + userOperation.paymasterData = stubPaymasterData.paymasterData + userOperation.paymasterVerificationGasLimit = + stubPaymasterData.paymasterVerificationGasLimit + userOperation.paymasterPostOpGasLimit = + stubPaymasterData.paymasterPostOpGasLimit + + const gasParameters = await getAction( + client, + estimateUserOperationGas, + "estimateUserOperationGas" + )( + { + userOperation, + entryPoint: account.entryPoint + }, + // @ts-ignore getAction takes only two params but when compiled this will work + stateOverrides + ) + + userOperation.callGasLimit |= gasParameters.callGasLimit + userOperation.verificationGasLimit = + userOperation.verificationGasLimit || + gasParameters.verificationGasLimit + userOperation.preVerificationGas = + userOperation.preVerificationGas || gasParameters.preVerificationGas + + userOperation.paymasterPostOpGasLimit = + userOperation.paymasterPostOpGasLimit || + gasParameters.paymasterPostOpGasLimit + userOperation.paymasterPostOpGasLimit = + userOperation.paymasterPostOpGasLimit || + gasParameters.paymasterPostOpGasLimit + + const { paymasterData, paymaster } = await getAction( + eip7677Client, + getPaymasterData, + "getPaymasterData" + )({ + userOperation, + entryPoint: account.entryPoint + }) + + userOperation.paymaster = paymaster + userOperation.paymasterData = paymasterData + return userOperation as PrepareUserOperationRequestReturnType + } + if ( middleware && typeof middleware !== "function" && @@ -415,10 +574,19 @@ export async function prepareUserOperationRequest< TChain extends Chain | undefined = Chain | undefined, TAccount extends SmartAccount | undefined = | SmartAccount + | undefined, + TEip7677Client extends Eip7677Client | undefined = + | Eip7677Client | undefined >( client: Client, - args: Prettify>, + args: Prettify< + PrepareUserOperationRequestParameters< + entryPoint, + TAccount, + TEip7677Client + > + >, stateOverrides?: StateOverrides ): Promise>> { const { account: account_ = client.account } = args diff --git a/packages/permissionless/actions/smartAccount/sendTransaction.ts b/packages/permissionless/actions/smartAccount/sendTransaction.ts index a3a415f4..1d617c96 100644 --- a/packages/permissionless/actions/smartAccount/sendTransaction.ts +++ b/packages/permissionless/actions/smartAccount/sendTransaction.ts @@ -6,12 +6,13 @@ import type { Transport } from "viem" import { getAction } from "viem/utils" -import { type SmartAccount } from "../../accounts/types" +import type { SmartAccount } from "../../accounts/types" +import type { Eip7677Client } from "../../experimental" import type { Prettify } from "../../types/" import type { EntryPoint } from "../../types/entrypoint" import { AccountOrClientNotFoundError, parseAccount } from "../../utils/" import { waitForUserOperationReceipt } from "../bundler/waitForUserOperationReceipt" -import { type Middleware } from "./prepareUserOperationRequest" +import type { Middleware } from "./prepareUserOperationRequest" import { sendUserOperation } from "./sendUserOperation" export type SendTransactionWithPaymasterParameters< @@ -20,9 +21,12 @@ export type SendTransactionWithPaymasterParameters< TAccount extends SmartAccount | undefined = | SmartAccount | undefined, - TChainOverride extends Chain | undefined = Chain | undefined + TChainOverride extends Chain | undefined = Chain | undefined, + TEip7677Client extends Eip7677Client | undefined = + | Eip7677Client + | undefined > = SendTransactionParameters & - Middleware + Middleware /** * Creates, signs, and sends a new transaction to the network. @@ -74,7 +78,10 @@ export async function sendTransaction< TChain extends Chain | undefined, TAccount extends SmartAccount | undefined, entryPoint extends EntryPoint, - TChainOverride extends Chain | undefined = Chain | undefined + TChainOverride extends Chain | undefined = Chain | undefined, + TEip7677Client extends Eip7677Client | undefined = + | Eip7677Client + | undefined >( client: Client, args: Prettify< @@ -82,7 +89,8 @@ export async function sendTransaction< entryPoint, TChain, TAccount, - TChainOverride + TChainOverride, + TEip7677Client > > ): Promise { @@ -94,7 +102,8 @@ export async function sendTransaction< to, value, nonce, - middleware + middleware, + eip7677Client } = args if (!account_) { @@ -130,6 +139,7 @@ export async function sendTransaction< nonce: nonce ? BigInt(nonce) : undefined }, account: account, + eip7677Client, middleware }) diff --git a/packages/permissionless/actions/smartAccount/sendTransactions.ts b/packages/permissionless/actions/smartAccount/sendTransactions.ts index 7189c3af..2f6a623b 100644 --- a/packages/permissionless/actions/smartAccount/sendTransactions.ts +++ b/packages/permissionless/actions/smartAccount/sendTransactions.ts @@ -8,23 +8,27 @@ import type { Transport } from "viem" import { getAction } from "viem/utils" -import { type SmartAccount } from "../../accounts/types" +import type { SmartAccount } from "../../accounts/types" +import type { Eip7677Client } from "../../experimental" import type { GetAccountParameter, Prettify } from "../../types/" import type { EntryPoint } from "../../types/entrypoint" import { AccountOrClientNotFoundError, parseAccount } from "../../utils/" import { waitForUserOperationReceipt } from "../bundler/waitForUserOperationReceipt" -import { type Middleware } from "./prepareUserOperationRequest" +import type { Middleware } from "./prepareUserOperationRequest" import { sendUserOperation } from "./sendUserOperation" export type SendTransactionsWithPaymasterParameters< entryPoint extends EntryPoint, TAccount extends SmartAccount | undefined = | SmartAccount + | undefined, + TEip7677Client extends Eip7677Client | undefined = + | Eip7677Client | undefined > = { transactions: { to: Address; value: bigint; data: Hex }[] } & GetAccountParameter & - Middleware & { + Middleware & { maxFeePerGas?: bigint maxPriorityFeePerGas?: bigint nonce?: bigint @@ -79,17 +83,25 @@ export type SendTransactionsWithPaymasterParameters< export async function sendTransactions< TChain extends Chain | undefined, TAccount extends SmartAccount | undefined, - entryPoint extends EntryPoint + entryPoint extends EntryPoint, + TEip7677Client extends Eip7677Client | undefined = + | Eip7677Client + | undefined >( client: Client, args: Prettify< - SendTransactionsWithPaymasterParameters + SendTransactionsWithPaymasterParameters< + entryPoint, + TAccount, + TEip7677Client + > > ): Promise { const { account: account_ = client.account, transactions, middleware, + eip7677Client, maxFeePerGas, maxPriorityFeePerGas, nonce @@ -131,6 +143,7 @@ export async function sendTransactions< nonce: nonce }, account: account, + eip7677Client, middleware }) diff --git a/packages/permissionless/actions/smartAccount/sendUserOperation.ts b/packages/permissionless/actions/smartAccount/sendUserOperation.ts index 84e9afc5..9259118d 100644 --- a/packages/permissionless/actions/smartAccount/sendUserOperation.ts +++ b/packages/permissionless/actions/smartAccount/sendUserOperation.ts @@ -1,6 +1,7 @@ import type { Chain, Client, Hash, Transport } from "viem" import { getAction } from "viem/utils" import type { SmartAccount } from "../../accounts/types" +import type { Eip7677Client } from "../../experimental" import type { GetAccountParameter, PartialBy, @@ -23,6 +24,9 @@ export type SendUserOperationParameters< entryPoint extends EntryPoint, TAccount extends SmartAccount | undefined = | SmartAccount + | undefined, + TEip7677Client extends Eip7677Client | undefined = + | Eip7677Client | undefined > = { userOperation: entryPoint extends ENTRYPOINT_ADDRESS_V06_TYPE @@ -57,7 +61,7 @@ export type SendUserOperationParameters< | "signature" > } & GetAccountParameter & - Middleware + Middleware export async function sendUserOperation< entryPoint extends EntryPoint, @@ -65,10 +69,15 @@ export async function sendUserOperation< TChain extends Chain | undefined = Chain | undefined, TAccount extends SmartAccount | undefined = | SmartAccount + | undefined, + TEip7677Client extends Eip7677Client | undefined = + | Eip7677Client | undefined >( client: Client, - args: Prettify> + args: Prettify< + SendUserOperationParameters + > ): Promise { const { account: account_ = client.account } = args if (!account_) throw new AccountOrClientNotFoundError() @@ -77,7 +86,13 @@ export async function sendUserOperation< const userOperation = await getAction( client, - prepareUserOperationRequest, + prepareUserOperationRequest< + entryPoint, + TTransport, + TChain, + TAccount, + TEip7677Client + >, "prepareUserOperationRequest" )(args) diff --git a/packages/permissionless/actions/smartAccount/writeContract.ts b/packages/permissionless/actions/smartAccount/writeContract.ts index 8e29d521..1852da94 100644 --- a/packages/permissionless/actions/smartAccount/writeContract.ts +++ b/packages/permissionless/actions/smartAccount/writeContract.ts @@ -11,9 +11,10 @@ import { encodeFunctionData } from "viem" import { getAction } from "viem/utils" -import { type SmartAccount } from "../../accounts/types" +import type { SmartAccount } from "../../accounts/types" +import type { Eip7677Client } from "../../experimental" import type { EntryPoint } from "../../types/entrypoint" -import { type Middleware } from "./prepareUserOperationRequest" +import type { Middleware } from "./prepareUserOperationRequest" import { type SendTransactionWithPaymasterParameters, sendTransaction @@ -76,6 +77,9 @@ export type WriteContractWithPaymasterParameters< TAccount extends SmartAccount | undefined = | SmartAccount | undefined, + TEip7677Client extends Eip7677Client | undefined = + | Eip7677Client + | undefined, TAbi extends Abi | readonly unknown[] = Abi | readonly unknown[], TFunctionName extends ContractFunctionName< TAbi, @@ -95,13 +99,16 @@ export type WriteContractWithPaymasterParameters< TAccount, TChainOverride > & - Middleware + Middleware export async function writeContract< entryPoint extends EntryPoint, TChain extends Chain | undefined, TAccount extends SmartAccount | undefined, const TAbi extends Abi | readonly unknown[], + TEip7677Client extends Eip7677Client | undefined = + | Eip7677Client + | undefined, TFunctionName extends ContractFunctionName< TAbi, "nonpayable" | "payable" @@ -125,6 +132,7 @@ export async function writeContract< entryPoint, TChain, TAccount, + TEip7677Client, TAbi, TFunctionName, TArgs, diff --git a/packages/permissionless/clients/createSmartAccountClient.ts b/packages/permissionless/clients/createSmartAccountClient.ts index 9d05170e..b31c4a5d 100644 --- a/packages/permissionless/clients/createSmartAccountClient.ts +++ b/packages/permissionless/clients/createSmartAccountClient.ts @@ -8,6 +8,7 @@ import type { import { createClient } from "viem" import { type SmartAccount } from "../accounts/types" import { type Middleware } from "../actions/smartAccount/prepareUserOperationRequest" +import { type Eip7677Client } from "../experimental" import type { Prettify } from "../types/" import { type BundlerRpcSchema } from "../types/bundler" import type { EntryPoint } from "../types/entrypoint" @@ -44,13 +45,16 @@ export type SmartAccountClientConfig< chain extends Chain | undefined = Chain | undefined, account extends SmartAccount | undefined = | SmartAccount + | undefined, + TEip7677Client extends Eip7677Client | undefined = + | Eip7677Client | undefined > = Prettify< Pick< ClientConfig, "cacheTime" | "chain" | "key" | "name" | "pollingInterval" > & - Middleware & { + Middleware & { account: account bundlerTransport: Transport } & { @@ -84,13 +88,17 @@ export function createSmartAccountClient< TChain extends Chain | undefined = undefined, TEntryPoint extends EntryPoint = TSmartAccount extends SmartAccount ? U - : never + : never, + TEip7677Client extends Eip7677Client | undefined = + | Eip7677Client + | undefined >( parameters: SmartAccountClientConfig< TEntryPoint, TTransport, TChain, - TSmartAccount + TSmartAccount, + TEip7677Client > ): SmartAccountClient { const { @@ -108,6 +116,7 @@ export function createSmartAccountClient< return client.extend( smartAccountActions({ + eip7677Client: parameters.eip7677Client, middleware: parameters.middleware }) ) as SmartAccountClient diff --git a/packages/permissionless/clients/decorators/smartAccount.ts b/packages/permissionless/clients/decorators/smartAccount.ts index 86b849a3..b01e97d8 100644 --- a/packages/permissionless/clients/decorators/smartAccount.ts +++ b/packages/permissionless/clients/decorators/smartAccount.ts @@ -39,6 +39,7 @@ import { type WriteContractWithPaymasterParameters, writeContract } from "../../actions/smartAccount/writeContract" +import type { Eip7677Client } from "../../experimental" import type { Prettify } from "../../types/" import type { StateOverrides } from "../../types/bundler" import type { EntryPoint } from "../../types/entrypoint" @@ -48,6 +49,9 @@ export type SmartAccountActions< TChain extends Chain | undefined = Chain | undefined, TSmartAccount extends SmartAccount | undefined = | SmartAccount + | undefined, + TEip7677Client extends Eip7677Client | undefined = + | Eip7677Client | undefined > = { /** @@ -300,7 +304,7 @@ export type SmartAccountActions< TChainOverride > > - ) => ReturnType> + ) => Promise /** * Executes a write function on a contract. * This function also allows you to sponsor this transaction if sender is a smartAccount @@ -376,6 +380,7 @@ export type SmartAccountActions< TChain, TSmartAccount, TAbi, + TEip7677Client, TFunctionName, TArgs, TChainOverride @@ -388,7 +393,8 @@ export type SmartAccountActions< entryPoint, TTransport, TChain, - TSmartAccount + TSmartAccount, + TEip7677Client > >[1] >, @@ -401,7 +407,8 @@ export type SmartAccountActions< entryPoint, TTransport, TChain, - TSmartAccount + TSmartAccount, + TEip7677Client > >[1] > @@ -457,14 +464,21 @@ export type SmartAccountActions< */ sendTransactions: ( args: Prettify< - SendTransactionsWithPaymasterParameters + SendTransactionsWithPaymasterParameters< + entryPoint, + TSmartAccount, + TEip7677Client + > > ) => ReturnType> } -export function smartAccountActions({ - middleware -}: Middleware) { +export function smartAccountActions< + entryPoint extends EntryPoint, + TEip7677Client extends Eip7677Client | undefined = + | Eip7677Client + | undefined +>({ eip7677Client, middleware }: Middleware) { return < TTransport extends Transport, TChain extends Chain | undefined = Chain | undefined, @@ -479,18 +493,28 @@ export function smartAccountActions({ client, { ...args, + eip7677Client, middleware }, stateOverrides ), deployContract: (args) => - deployContract(client, { - ...args, - middleware - } as DeployContractParametersWithPaymaster), + deployContract( + client, + { + ...args, + eip7677Client, + middleware + } as unknown as DeployContractParametersWithPaymaster< + entryPoint, + TSmartAccount, + TEip7677Client + > + ), sendTransaction: (args) => sendTransaction(client, { ...args, + eip7677Client, middleware } as SendTransactionWithPaymasterParameters< entryPoint, @@ -500,6 +524,7 @@ export function smartAccountActions({ sendTransactions: (args) => sendTransactions(client, { ...args, + eip7677Client, middleware }), sendUserOperation: (args) => @@ -507,6 +532,7 @@ export function smartAccountActions({ client, { ...args, + eip7677Client, middleware } as SendUserOperationParameters ), @@ -561,11 +587,13 @@ export function smartAccountActions({ ) => writeContract(client, { ...args, + eip7677Client, middleware } as WriteContractWithPaymasterParameters< entryPoint, TChain, TSmartAccount, + TEip7677Client, TAbi >) }) diff --git a/packages/permissionless/errors/sendUserOperation.ts b/packages/permissionless/errors/sendUserOperation.ts index c28bb9e4..9d0fcc02 100644 --- a/packages/permissionless/errors/sendUserOperation.ts +++ b/packages/permissionless/errors/sendUserOperation.ts @@ -1,5 +1,5 @@ import { BaseError } from "viem" -import { type SendUserOperationParameters } from "../actions/bundler/sendUserOperation" +import type { SendUserOperationParameters } from "../actions/bundler/sendUserOperation" import type { EntryPoint } from "../types/entrypoint" import { prettyPrint } from "./utils" diff --git a/packages/permissionless/experimental/eip7677/actions/getPaymasterData.ts b/packages/permissionless/experimental/eip7677/actions/getPaymasterData.ts new file mode 100644 index 00000000..1dc0f368 --- /dev/null +++ b/packages/permissionless/experimental/eip7677/actions/getPaymasterData.ts @@ -0,0 +1,126 @@ +import { + type Chain, + ChainNotFoundError, + type Client, + type GetChainParameter, + type Hex, + type Transport, + toHex +} from "viem" +import type { + ENTRYPOINT_ADDRESS_V06_TYPE, + ENTRYPOINT_ADDRESS_V07_TYPE, + EntryPoint, + GetEntryPointVersion +} from "../../../types/entrypoint" +import type { + UserOperation, + UserOperationWithBigIntAsHex +} from "../../../types/userOperation" +import { deepHexlify, getEntryPointVersion } from "../../../utils" +import type { + Eip7677RpcSchema, + GetRpcPaymasterDataReturnType +} from "../types/paymaster" + +export type GetPaymasterDataParameters< + TEntryPoint extends EntryPoint, + TChain extends Chain | undefined = Chain | undefined, + TChainOverride extends Chain | undefined = Chain | undefined +> = { + userOperation: UserOperation> + entryPoint: TEntryPoint + context?: Record +} & GetChainParameter + +export type GetPaymasterDataReturnType = + GetEntryPointVersion extends "v0.6" + ? { + sponsor?: { name: string; icon: string } + paymasterAndData: Hex + } + : { + sponsor?: { name: string; icon: string } + paymaster: Hex + paymasterData: Hex + } + +export async function getPaymasterData< + TEntryPoint extends EntryPoint, + TChain extends Chain | undefined, + TTransport extends Transport = Transport, + TChainOverride extends Chain | undefined = Chain | undefined +>( + client: Client< + TTransport, + TChain, + undefined, + Eip7677RpcSchema + >, + { + userOperation, + entryPoint, + context, + chain + }: GetPaymasterDataParameters +): Promise> { + const chainId = chain?.id ?? client.chain?.id + + if (!chainId) { + throw new ChainNotFoundError() + } + + const params: + | [ + UserOperationWithBigIntAsHex>, + TEntryPoint, + Hex, + Record + ] + | [ + UserOperationWithBigIntAsHex>, + TEntryPoint, + Hex + ] = context + ? [ + deepHexlify(userOperation) as UserOperationWithBigIntAsHex< + GetEntryPointVersion + >, + entryPoint, + toHex(chainId), + context + ] + : [ + deepHexlify(userOperation) as UserOperationWithBigIntAsHex< + GetEntryPointVersion + >, + entryPoint, + toHex(chainId) + ] + + const response = await client.request({ + method: "pm_getPaymasterData", + params + }) + + const entryPointVersion = getEntryPointVersion(entryPoint) + + if (entryPointVersion === "v0.6") { + const responseV06 = + response as GetRpcPaymasterDataReturnType + + return { + sponsor: responseV06.sponsor, + paymasterAndData: responseV06.paymasterAndData + } as GetPaymasterDataReturnType + } + + const responseV07 = + response as GetRpcPaymasterDataReturnType + + return { + sponsor: responseV07.sponsor, + paymaster: responseV07.paymaster, + paymasterData: responseV07.paymasterData + } as GetPaymasterDataReturnType +} diff --git a/packages/permissionless/experimental/eip7677/actions/getPaymasterStubData.ts b/packages/permissionless/experimental/eip7677/actions/getPaymasterStubData.ts new file mode 100644 index 00000000..48b8d244 --- /dev/null +++ b/packages/permissionless/experimental/eip7677/actions/getPaymasterStubData.ts @@ -0,0 +1,130 @@ +import { + type Chain, + ChainNotFoundError, + type Client, + type GetChainParameter, + type Hex, + type Transport, + toHex +} from "viem" +import type { + ENTRYPOINT_ADDRESS_V06_TYPE, + ENTRYPOINT_ADDRESS_V07_TYPE, + EntryPoint, + GetEntryPointVersion +} from "../../../types/entrypoint" +import type { + UserOperation, + UserOperationWithBigIntAsHex +} from "../../../types/userOperation" +import { deepHexlify, getEntryPointVersion } from "../../../utils" +import type { + Eip7677RpcSchema, + GetRpcPaymasterStubDataReturnType +} from "../types/paymaster" + +export type GetPaymasterStubDataParameters< + TEntryPoint extends EntryPoint, + TChain extends Chain | undefined, + TChainOverride extends Chain | undefined = Chain | undefined +> = { + userOperation: UserOperation> + entryPoint: TEntryPoint + context?: Record +} & GetChainParameter + +export type GetPaymasterStubDataReturnType = + GetEntryPointVersion extends "v0.6" + ? { + paymasterAndData: Hex + } + : { + paymaster: Hex + paymasterData: Hex + paymasterVerificationGasLimit?: bigint + paymasterPostOpGasLimit?: bigint + } + +export async function getPaymasterStubData< + TEntryPoint extends EntryPoint, + TChain extends Chain | undefined, + TTransport extends Transport = Transport, + TChainOverride extends Chain | undefined = Chain | undefined +>( + client: Client< + TTransport, + TChain, + undefined, + Eip7677RpcSchema + >, + { + userOperation, + entryPoint, + context, + chain + }: GetPaymasterStubDataParameters +): Promise> { + const chainId = chain?.id ?? client.chain?.id + + if (!chainId) { + throw new ChainNotFoundError() + } + + const params: + | [ + UserOperationWithBigIntAsHex>, + TEntryPoint, + Hex, + Record + ] + | [ + UserOperationWithBigIntAsHex>, + TEntryPoint, + Hex + ] = context + ? [ + deepHexlify(userOperation) as UserOperationWithBigIntAsHex< + GetEntryPointVersion + >, + entryPoint, + toHex(chainId), + context + ] + : [ + deepHexlify(userOperation) as UserOperationWithBigIntAsHex< + GetEntryPointVersion + >, + entryPoint, + toHex(chainId) + ] + + const response = await client.request({ + method: "pm_getPaymasterStubData", + params + }) + + const entryPointVersion = getEntryPointVersion(entryPoint) + + if (entryPointVersion === "v0.6") { + const responseV06 = + response as GetRpcPaymasterStubDataReturnType + + return { + paymasterAndData: responseV06.paymasterAndData + } as GetPaymasterStubDataReturnType + } + + const responseV07 = + response as GetRpcPaymasterStubDataReturnType + + return { + paymaster: responseV07.paymaster, + paymasterData: responseV07.paymasterData, + paymasterVerificationGasLimit: responseV07.paymasterVerificationGasLimit + ? BigInt(responseV07.paymasterVerificationGasLimit) + : undefined, + paymasterPostOpGasLimit: responseV07.paymasterPostOpGasLimit + ? BigInt(responseV07.paymasterPostOpGasLimit) + : undefined + } as GetPaymasterStubDataReturnType +} diff --git a/packages/permissionless/experimental/eip7677/clients/createEip7677Client.ts b/packages/permissionless/experimental/eip7677/clients/createEip7677Client.ts new file mode 100644 index 00000000..b89ba8b3 --- /dev/null +++ b/packages/permissionless/experimental/eip7677/clients/createEip7677Client.ts @@ -0,0 +1,40 @@ +import { + type Chain, + type Client, + type PublicClientConfig, + type Transport, + createClient +} from "viem" +import type { EntryPoint } from "../../../types/entrypoint" +import type { Eip7677RpcSchema } from "../types/paymaster" +import { type Eip7677Actions, eip7677Actions } from "./decorators/eip7677" + +export type Eip7677Client< + TEntryPoint extends EntryPoint, + TChain extends Chain | undefined = Chain | undefined +> = Client< + Transport, + TChain, + undefined, + Eip7677RpcSchema, + Eip7677Actions +> + +export const createEip7677Client = < + TEntryPoint extends EntryPoint, + TTransport extends Transport = Transport, + TChain extends Chain | undefined = Chain | undefined +>( + parameters: PublicClientConfig & { + entryPoint: TEntryPoint + } +): Eip7677Client => { + const { key = "public", name = "EIP 7677 paymaster client" } = parameters + const client = createClient({ + ...parameters, + key, + name, + type: "bundlerClient" + }) + return client.extend(eip7677Actions({ entryPoint: parameters.entryPoint })) +} diff --git a/packages/permissionless/experimental/eip7677/clients/decorators/eip7677.ts b/packages/permissionless/experimental/eip7677/clients/decorators/eip7677.ts new file mode 100644 index 00000000..f63bd444 --- /dev/null +++ b/packages/permissionless/experimental/eip7677/clients/decorators/eip7677.ts @@ -0,0 +1,70 @@ +import type { Chain, Client, Transport } from "viem" +import type { Prettify } from "viem/types/utils" +import type { EntryPoint } from "../../../../types/entrypoint" +import { + type GetPaymasterDataParameters, + type GetPaymasterDataReturnType, + getPaymasterData +} from "../../actions/getPaymasterData" +import { + type GetPaymasterStubDataParameters, + type GetPaymasterStubDataReturnType, + getPaymasterStubData +} from "../../actions/getPaymasterStubData" +import type { Eip7677Client } from "../createEip7677Client" + +export type Eip7677Actions< + TEntryPoint extends EntryPoint, + TChain extends Chain | undefined = Chain | undefined +> = { + getPaymasterData: < + TChainOverride extends Chain | undefined = Chain | undefined + >( + args: Omit< + GetPaymasterDataParameters, + "entryPoint" + > + ) => Promise> + getPaymasterStubData: < + TChainOverride extends Chain | undefined = Chain | undefined + >( + args: Prettify< + Omit< + GetPaymasterStubDataParameters< + TEntryPoint, + TChain, + TChainOverride + >, + "entryPoint" + > + > + ) => Promise> +} + +const eip7677Actions = + ({ + entryPoint + }: { entryPoint: TEntryPoint }) => + < + TTransport extends Transport, + TChain extends Chain | undefined = Chain | undefined + >( + client: Client + ): Eip7677Actions => ({ + getPaymasterData: (args) => + getPaymasterData(client as Eip7677Client, { + userOperation: args.userOperation, + context: args.context, + chain: args.chain, + entryPoint + }), + getPaymasterStubData: async (args) => + getPaymasterStubData(client as Eip7677Client, { + userOperation: args.userOperation, + context: args.context, + chain: args.chain, + entryPoint + }) + }) + +export { eip7677Actions } diff --git a/packages/permissionless/experimental/eip7677/index.ts b/packages/permissionless/experimental/eip7677/index.ts new file mode 100644 index 00000000..03c33b30 --- /dev/null +++ b/packages/permissionless/experimental/eip7677/index.ts @@ -0,0 +1,33 @@ +import { + type GetPaymasterDataParameters, + type GetPaymasterDataReturnType, + getPaymasterData +} from "./actions/getPaymasterData" +import { + type GetPaymasterStubDataParameters, + type GetPaymasterStubDataReturnType, + getPaymasterStubData +} from "./actions/getPaymasterStubData" +import { + type Eip7677Client, + createEip7677Client +} from "./clients/createEip7677Client" +import { + type Eip7677Actions, + eip7677Actions +} from "./clients/decorators/eip7677" +import type { Eip7677RpcSchema } from "./types/paymaster" + +export { + type GetPaymasterStubDataParameters, + type GetPaymasterStubDataReturnType, + getPaymasterStubData, + type GetPaymasterDataReturnType, + type GetPaymasterDataParameters, + getPaymasterData, + type Eip7677Client, + createEip7677Client, + type Eip7677Actions, + eip7677Actions, + type Eip7677RpcSchema +} diff --git a/packages/permissionless/experimental/eip7677/types/paymaster.ts b/packages/permissionless/experimental/eip7677/types/paymaster.ts new file mode 100644 index 00000000..31ac958d --- /dev/null +++ b/packages/permissionless/experimental/eip7677/types/paymaster.ts @@ -0,0 +1,61 @@ +import type { Hex } from "viem" +import type { + EntryPoint, + GetEntryPointVersion +} from "../../../types/entrypoint" +import type { UserOperationWithBigIntAsHex } from "../../../types/userOperation" + +export type GetRpcPaymasterStubDataParameters = [ + userOperation: UserOperationWithBigIntAsHex< + GetEntryPointVersion + >, + entryPoint: entryPoint, + chainId: Hex, + context?: Record +] + +export type GetRpcPaymasterStubDataReturnType = + GetEntryPointVersion extends "v0.6" + ? { + paymasterAndData: Hex + } + : { + paymaster: Hex + paymasterData: Hex + paymasterVerificationGasLimit?: Hex | null + paymasterPostOpGasLimit?: Hex | null + } + +export type GetRpcPaymasterDataParameters = [ + userOperation: UserOperationWithBigIntAsHex< + GetEntryPointVersion + >, + entryPoint: entryPoint, + chainId: Hex, + context?: Record +] + +export type GetRpcPaymasterDataReturnType = + GetEntryPointVersion extends "v0.6" + ? { + sponsor?: { name: string; icon: string } + paymasterAndData: Hex + } + : { + sponsor?: { name: string; icon: string } + paymaster: Hex + paymasterData: Hex + } + +export type Eip7677RpcSchema = [ + { + Method: "pm_getPaymasterStubData" + Parameters: GetRpcPaymasterStubDataParameters + ReturnType: GetRpcPaymasterStubDataReturnType + }, + { + Method: "pm_getPaymasterData" + Paremeters: GetRpcPaymasterDataParameters + ReturnType: GetRpcPaymasterDataReturnType + } +] diff --git a/packages/permissionless/experimental/index.ts b/packages/permissionless/experimental/index.ts new file mode 100644 index 00000000..4952309b --- /dev/null +++ b/packages/permissionless/experimental/index.ts @@ -0,0 +1 @@ +export * from "./eip7677" diff --git a/packages/permissionless/package.json b/packages/permissionless/package.json index fe9e0bf8..741b6df4 100644 --- a/packages/permissionless/package.json +++ b/packages/permissionless/package.json @@ -79,6 +79,11 @@ "types": "./_types/types/index.d.ts", "import": "./_esm/types/index.js", "default": "./_cjs/types/index.js" + }, + "./experimental/": { + "types": "./_types/experimental/index.d.ts", + "import": "./_esm/experimental/index.js", + "default": "./_cjs/experimental/index.js" } }, "peerDependencies": { From f2e797c0b3c2dbf8db630246c44cbd9a375a236c Mon Sep 17 00:00:00 2001 From: Garvit Khatri Date: Mon, 6 May 2024 15:27:06 +0530 Subject: [PATCH 2/7] remove the complexities for now --- .../src/ep-0.6/experiments.ts | 43 +++- packages/permissionless-test/src/utils.ts | 15 +- .../actions/smartAccount/deployContract.ts | 27 +-- .../prepareUserOperationRequest.ts | 212 ++---------------- .../actions/smartAccount/sendTransaction.ts | 20 +- .../actions/smartAccount/sendTransactions.ts | 19 +- .../actions/smartAccount/sendUserOperation.ts | 21 +- .../actions/smartAccount/writeContract.ts | 10 +- .../clients/createSmartAccountClient.ts | 15 +- .../clients/decorators/smartAccount.ts | 48 +--- .../eip7677/clients/createEip7677Client.ts | 40 ---- .../eip7677/clients/decorators/eip7677.ts | 42 ++-- .../experimental/eip7677/index.ts | 6 - 13 files changed, 120 insertions(+), 398 deletions(-) delete mode 100644 packages/permissionless/experimental/eip7677/clients/createEip7677Client.ts diff --git a/packages/permissionless-test/src/ep-0.6/experiments.ts b/packages/permissionless-test/src/ep-0.6/experiments.ts index d8c59c00..95b9545c 100644 --- a/packages/permissionless-test/src/ep-0.6/experiments.ts +++ b/packages/permissionless-test/src/ep-0.6/experiments.ts @@ -3,14 +3,22 @@ import { createSmartAccountClient } from "permissionless" import { privateKeyToSafeSmartAccount } from "permissionless/accounts" -import type { Eip7677Client } from "permissionless/experimental" +import { Eip7677Actions, eip7677Actions } from "permissionless/experimental" import type { ENTRYPOINT_ADDRESS_V06_TYPE } from "permissionless/types" -import { http, type Chain, zeroAddress } from "viem" +import { + http, + type Chain, + Client, + Transport, + createClient, + zeroAddress +} from "viem" import { generatePrivateKey } from "viem/accounts" import { foundry } from "viem/chains" import { beforeAll, describe, test } from "vitest" import type { AAParamType } from "../types" import { + PAYMASTER_RPC, getEip7677Client, getPimlicoPaymasterClient, getPublicClient, @@ -26,14 +34,6 @@ describe.each([ ) => getSafeClient(conf) } ])("$name test", ({ name, getSmartAccountClient }) => { - let eip7677Client: Eip7677Client - - beforeAll(async () => { - eip7677Client = await getEip7677Client({ - entryPoint: ENTRYPOINT_ADDRESS_V06 - }) - }) - test("Can get stab data", async () => { const publicClient = getPublicClient() @@ -51,8 +51,27 @@ describe.each([ const smartAccountClient = createSmartAccountClient({ chain: foundry, account: smartAccount, - bundlerTransport: http(ALTO_RPC), - eip7677Client: eip7677Client + bundlerTransport: http(ALTO_RPC) + }) + + const userOperaton = + await smartAccountClient.prepareUserOperationRequest({ + userOperation: { + callData: await smartAccountClient.account.encodeCallData({ + to: zeroAddress, + value: 0n, + data: "0x" + }) + } + }) + + const eip7677Client = createClient({ + chain: foundry, + transport: http(PAYMASTER_RPC) + }).extend(eip7677Actions({ entryPoint: ENTRYPOINT_ADDRESS_V06 })) + + const response = await eip7677Client.getPaymasterData({ + userOperation: userOperaton }) // await eip7677Client.getPaymasterStubData({ diff --git a/packages/permissionless-test/src/utils.ts b/packages/permissionless-test/src/utils.ts index cf7a29f3..8a3aee36 100644 --- a/packages/permissionless-test/src/utils.ts +++ b/packages/permissionless-test/src/utils.ts @@ -22,10 +22,7 @@ import { createPimlicoBundlerClient, createPimlicoPaymasterClient } from "permissionless/clients/pimlico" -import { - type Eip7677Client, - createEip7677Client -} from "permissionless/experimental" +import { type Eip7677Client, eip7677Actions } from "permissionless/experimental" import type { ENTRYPOINT_ADDRESS_V06_TYPE, EntryPoint @@ -38,6 +35,7 @@ import { type Hex, type Transport, type WalletClient, + createClient, createPublicClient, createWalletClient, parseEther @@ -56,7 +54,7 @@ import type { AAParamType } from "./types" export const ALTO_RPC = "http://localhost:4337" const ANVIL_RPC = "http://localhost:8545" -const PAYMASTER_RPC = "http://localhost:3000" +export const PAYMASTER_RPC = "http://localhost:3000" export const ensureBundlerIsReady = async () => { const bundlerClient = getBundlerClient(ENTRYPOINT_ADDRESS_V06) @@ -321,9 +319,10 @@ export const getSafeClient = async ({ export const getEip7677Client = async ({ entryPoint }: { entryPoint: TEntryPoint }) => { - return createEip7677Client({ + const client = createClient({ chain: foundry, - entryPoint, transport: http(PAYMASTER_RPC) - }) + }).extend(eip7677Actions({ entryPoint })) + + return client } diff --git a/packages/permissionless/actions/smartAccount/deployContract.ts b/packages/permissionless/actions/smartAccount/deployContract.ts index 0d4fb1bc..8539e873 100644 --- a/packages/permissionless/actions/smartAccount/deployContract.ts +++ b/packages/permissionless/actions/smartAccount/deployContract.ts @@ -9,28 +9,24 @@ import type { } from "viem" import { getAction } from "viem/utils" import type { SmartAccount } from "../../accounts/types" -import type { Eip7677Client } from "../../experimental" import type { Prettify } from "../../types/" import type { EntryPoint } from "../../types/entrypoint" import { parseAccount } from "../../utils/" import { AccountOrClientNotFoundError } from "../../utils/signUserOperationHashWithECDSA" import { waitForUserOperationReceipt } from "../bundler/waitForUserOperationReceipt" -import type { Middleware } from "./prepareUserOperationRequest" +import { type Middleware } from "./prepareUserOperationRequest" import { sendUserOperation } from "./sendUserOperation" export type DeployContractParametersWithPaymaster< entryPoint extends EntryPoint, + TAbi extends Abi | readonly unknown[] = Abi | readonly unknown[], + TChain extends Chain | undefined = Chain | undefined, TAccount extends SmartAccount | undefined = | SmartAccount | undefined, - TEip7677Client extends Eip7677Client | undefined = - | Eip7677Client - | undefined, - TAbi extends Abi | readonly unknown[] = Abi | readonly unknown[], - TChain extends Chain | undefined = Chain | undefined, TChainOverride extends Chain | undefined = Chain | undefined > = DeployContractParameters & - Middleware + Middleware /** * Deploys a contract to the network, given bytecode and constructor arguments. @@ -63,26 +59,16 @@ export type DeployContractParametersWithPaymaster< export async function deployContract< entryPoint extends EntryPoint, TChain extends Chain | undefined, - TAccount extends SmartAccount | undefined, - TEip7677Client extends Eip7677Client | undefined = - | Eip7677Client - | undefined + TAccount extends SmartAccount | undefined >( client: Client, - args: Prettify< - DeployContractParametersWithPaymaster< - entryPoint, - TAccount, - TEip7677Client - > - > + args: Prettify> ): Promise { const { abi, args: constructorArgs, bytecode, middleware, - eip7677Client, ...request } = args @@ -112,7 +98,6 @@ export async function deployContract< } as EncodeDeployDataParameters) }, account: account, - eip7677Client, middleware }) diff --git a/packages/permissionless/actions/smartAccount/prepareUserOperationRequest.ts b/packages/permissionless/actions/smartAccount/prepareUserOperationRequest.ts index e3b641ad..483cbdab 100644 --- a/packages/permissionless/actions/smartAccount/prepareUserOperationRequest.ts +++ b/packages/permissionless/actions/smartAccount/prepareUserOperationRequest.ts @@ -1,13 +1,7 @@ import type { Chain, Client, Transport } from "viem" import { estimateFeesPerGas } from "viem/actions" -import type { IsUndefined } from "viem/types/utils" import { getAction } from "viem/utils" import type { SmartAccount } from "../../accounts/types" -import { - type Eip7677Client, - getPaymasterData, - getPaymasterStubData -} from "../../experimental" import type { PartialPick } from "../../types" import type { GetAccountParameter, @@ -58,56 +52,28 @@ export type SponsorUserOperationReturnType = > > -type MiddlewareFunction = (args: { - userOperation: UserOperation> - entryPoint: entryPoint -}) => Promise>> - -type MiddlewareObject< - entryPoint extends EntryPoint, - TEip7677Client extends Eip7677Client | undefined -> = IsUndefined extends true - ? - | MiddlewareFunction - | { - gasPrice?: () => Promise<{ - maxFeePerGas: bigint - maxPriorityFeePerGas: bigint - }> - sponsorUserOperation?: (args: { - userOperation: UserOperation< - GetEntryPointVersion - > - entryPoint: entryPoint - }) => Promise> - } - : - | MiddlewareFunction - | { - gasPrice?: () => Promise<{ - maxFeePerGas: bigint - maxPriorityFeePerGas: bigint - }> - sponsorUserOperation: never - } - -export type Middleware< - entryPoint extends EntryPoint, - TEip7677Client extends Eip7677Client | undefined = - | Eip7677Client - | undefined -> = { - eip7677Client?: TEip7677Client - middleware?: MiddlewareObject +export type Middleware = { + middleware?: + | ((args: { + userOperation: UserOperation> + entryPoint: entryPoint + }) => Promise>>) + | { + gasPrice?: () => Promise<{ + maxFeePerGas: bigint + maxPriorityFeePerGas: bigint + }> + sponsorUserOperation?: (args: { + userOperation: UserOperation> + entryPoint: entryPoint + }) => Promise> + } } export type PrepareUserOperationRequestParameters< entryPoint extends EntryPoint, TAccount extends SmartAccount | undefined = | SmartAccount - | undefined, - TEip7677Client extends Eip7677Client | undefined = - | Eip7677Client | undefined > = { userOperation: entryPoint extends ENTRYPOINT_ADDRESS_V06_TYPE @@ -142,7 +108,7 @@ export type PrepareUserOperationRequestParameters< | "signature" > } & GetAccountParameter & - Middleware + Middleware export type PrepareUserOperationRequestReturnType< entryPoint extends EntryPoint @@ -154,26 +120,16 @@ async function prepareUserOperationRequestForEntryPointV06< TChain extends Chain | undefined = Chain | undefined, TAccount extends SmartAccount | undefined = | SmartAccount - | undefined, - TEip7677Client extends Eip7677Client | undefined = - | Eip7677Client | undefined >( client: Client, - args: Prettify< - PrepareUserOperationRequestParameters< - entryPoint, - TAccount, - TEip7677Client - > - >, + args: Prettify>, stateOverrides?: StateOverrides ): Promise>> { const { account: account_ = client.account, userOperation: partialUserOperation, - middleware, - eip7677Client + middleware } = args if (!account_) throw new AccountOrClientNotFoundError() @@ -233,54 +189,6 @@ async function prepareUserOperationRequestForEntryPointV06< estimateGas.maxPriorityFeePerGas } - if (eip7677Client) { - const stubPaymasterData = await getAction( - eip7677Client, - getPaymasterStubData, - "getPaymasterStubData" - )({ - userOperation, - entryPoint: account.entryPoint - }) - - userOperation.paymasterAndData = stubPaymasterData.paymasterAndData - - const gasParameters = await getAction( - client, - estimateUserOperationGas, - "estimateUserOperationGas" - )( - { - userOperation, - entryPoint: account.entryPoint - } as { - userOperation: UserOperation> - entryPoint: entryPoint - }, - // @ts-ignore getAction takes only two params but when compiled this will work - stateOverrides - ) - - userOperation.callGasLimit |= gasParameters.callGasLimit - userOperation.verificationGasLimit = - userOperation.verificationGasLimit || - gasParameters.verificationGasLimit - userOperation.preVerificationGas = - userOperation.preVerificationGas || gasParameters.preVerificationGas - - const { paymasterAndData } = await getAction( - eip7677Client, - getPaymasterData, - "getPaymasterData" - )({ - userOperation, - entryPoint: account.entryPoint - }) - - userOperation.paymasterAndData = paymasterAndData - return userOperation as PrepareUserOperationRequestReturnType - } - if ( middleware && typeof middleware !== "function" && @@ -349,26 +257,16 @@ async function prepareUserOperationRequestEntryPointV07< TChain extends Chain | undefined = Chain | undefined, TAccount extends SmartAccount | undefined = | SmartAccount - | undefined, - TEip7677Client extends Eip7677Client | undefined = - | Eip7677Client | undefined >( client: Client, - args: Prettify< - PrepareUserOperationRequestParameters< - entryPoint, - TAccount, - TEip7677Client - > - >, + args: Prettify>, stateOverrides?: StateOverrides ): Promise>> { const { account: account_ = client.account, userOperation: partialUserOperation, - middleware, - eip7677Client + middleware } = args if (!account_) throw new AccountOrClientNotFoundError() @@ -440,63 +338,6 @@ async function prepareUserOperationRequestEntryPointV07< estimateGas.maxPriorityFeePerGas } - if (eip7677Client) { - const stubPaymasterData = await getAction( - eip7677Client, - getPaymasterStubData, - "getPaymasterStubData" - )({ - userOperation, - entryPoint: account.entryPoint - }) - userOperation.paymaster = stubPaymasterData.paymaster - userOperation.paymasterData = stubPaymasterData.paymasterData - userOperation.paymasterVerificationGasLimit = - stubPaymasterData.paymasterVerificationGasLimit - userOperation.paymasterPostOpGasLimit = - stubPaymasterData.paymasterPostOpGasLimit - - const gasParameters = await getAction( - client, - estimateUserOperationGas, - "estimateUserOperationGas" - )( - { - userOperation, - entryPoint: account.entryPoint - }, - // @ts-ignore getAction takes only two params but when compiled this will work - stateOverrides - ) - - userOperation.callGasLimit |= gasParameters.callGasLimit - userOperation.verificationGasLimit = - userOperation.verificationGasLimit || - gasParameters.verificationGasLimit - userOperation.preVerificationGas = - userOperation.preVerificationGas || gasParameters.preVerificationGas - - userOperation.paymasterPostOpGasLimit = - userOperation.paymasterPostOpGasLimit || - gasParameters.paymasterPostOpGasLimit - userOperation.paymasterPostOpGasLimit = - userOperation.paymasterPostOpGasLimit || - gasParameters.paymasterPostOpGasLimit - - const { paymasterData, paymaster } = await getAction( - eip7677Client, - getPaymasterData, - "getPaymasterData" - )({ - userOperation, - entryPoint: account.entryPoint - }) - - userOperation.paymaster = paymaster - userOperation.paymasterData = paymasterData - return userOperation as PrepareUserOperationRequestReturnType - } - if ( middleware && typeof middleware !== "function" && @@ -574,19 +415,10 @@ export async function prepareUserOperationRequest< TChain extends Chain | undefined = Chain | undefined, TAccount extends SmartAccount | undefined = | SmartAccount - | undefined, - TEip7677Client extends Eip7677Client | undefined = - | Eip7677Client | undefined >( client: Client, - args: Prettify< - PrepareUserOperationRequestParameters< - entryPoint, - TAccount, - TEip7677Client - > - >, + args: Prettify>, stateOverrides?: StateOverrides ): Promise>> { const { account: account_ = client.account } = args diff --git a/packages/permissionless/actions/smartAccount/sendTransaction.ts b/packages/permissionless/actions/smartAccount/sendTransaction.ts index 1d617c96..f87c7243 100644 --- a/packages/permissionless/actions/smartAccount/sendTransaction.ts +++ b/packages/permissionless/actions/smartAccount/sendTransaction.ts @@ -7,7 +7,6 @@ import type { } from "viem" import { getAction } from "viem/utils" import type { SmartAccount } from "../../accounts/types" -import type { Eip7677Client } from "../../experimental" import type { Prettify } from "../../types/" import type { EntryPoint } from "../../types/entrypoint" import { AccountOrClientNotFoundError, parseAccount } from "../../utils/" @@ -21,12 +20,9 @@ export type SendTransactionWithPaymasterParameters< TAccount extends SmartAccount | undefined = | SmartAccount | undefined, - TChainOverride extends Chain | undefined = Chain | undefined, - TEip7677Client extends Eip7677Client | undefined = - | Eip7677Client - | undefined + TChainOverride extends Chain | undefined = Chain | undefined > = SendTransactionParameters & - Middleware + Middleware /** * Creates, signs, and sends a new transaction to the network. @@ -78,10 +74,7 @@ export async function sendTransaction< TChain extends Chain | undefined, TAccount extends SmartAccount | undefined, entryPoint extends EntryPoint, - TChainOverride extends Chain | undefined = Chain | undefined, - TEip7677Client extends Eip7677Client | undefined = - | Eip7677Client - | undefined + TChainOverride extends Chain | undefined = Chain | undefined >( client: Client, args: Prettify< @@ -89,8 +82,7 @@ export async function sendTransaction< entryPoint, TChain, TAccount, - TChainOverride, - TEip7677Client + TChainOverride > > ): Promise { @@ -102,8 +94,7 @@ export async function sendTransaction< to, value, nonce, - middleware, - eip7677Client + middleware } = args if (!account_) { @@ -139,7 +130,6 @@ export async function sendTransaction< nonce: nonce ? BigInt(nonce) : undefined }, account: account, - eip7677Client, middleware }) diff --git a/packages/permissionless/actions/smartAccount/sendTransactions.ts b/packages/permissionless/actions/smartAccount/sendTransactions.ts index 2f6a623b..d8f8829e 100644 --- a/packages/permissionless/actions/smartAccount/sendTransactions.ts +++ b/packages/permissionless/actions/smartAccount/sendTransactions.ts @@ -9,7 +9,6 @@ import type { } from "viem" import { getAction } from "viem/utils" import type { SmartAccount } from "../../accounts/types" -import type { Eip7677Client } from "../../experimental" import type { GetAccountParameter, Prettify } from "../../types/" import type { EntryPoint } from "../../types/entrypoint" import { AccountOrClientNotFoundError, parseAccount } from "../../utils/" @@ -21,14 +20,11 @@ export type SendTransactionsWithPaymasterParameters< entryPoint extends EntryPoint, TAccount extends SmartAccount | undefined = | SmartAccount - | undefined, - TEip7677Client extends Eip7677Client | undefined = - | Eip7677Client | undefined > = { transactions: { to: Address; value: bigint; data: Hex }[] } & GetAccountParameter & - Middleware & { + Middleware & { maxFeePerGas?: bigint maxPriorityFeePerGas?: bigint nonce?: bigint @@ -83,25 +79,17 @@ export type SendTransactionsWithPaymasterParameters< export async function sendTransactions< TChain extends Chain | undefined, TAccount extends SmartAccount | undefined, - entryPoint extends EntryPoint, - TEip7677Client extends Eip7677Client | undefined = - | Eip7677Client - | undefined + entryPoint extends EntryPoint >( client: Client, args: Prettify< - SendTransactionsWithPaymasterParameters< - entryPoint, - TAccount, - TEip7677Client - > + SendTransactionsWithPaymasterParameters > ): Promise { const { account: account_ = client.account, transactions, middleware, - eip7677Client, maxFeePerGas, maxPriorityFeePerGas, nonce @@ -143,7 +131,6 @@ export async function sendTransactions< nonce: nonce }, account: account, - eip7677Client, middleware }) diff --git a/packages/permissionless/actions/smartAccount/sendUserOperation.ts b/packages/permissionless/actions/smartAccount/sendUserOperation.ts index 9259118d..84e9afc5 100644 --- a/packages/permissionless/actions/smartAccount/sendUserOperation.ts +++ b/packages/permissionless/actions/smartAccount/sendUserOperation.ts @@ -1,7 +1,6 @@ import type { Chain, Client, Hash, Transport } from "viem" import { getAction } from "viem/utils" import type { SmartAccount } from "../../accounts/types" -import type { Eip7677Client } from "../../experimental" import type { GetAccountParameter, PartialBy, @@ -24,9 +23,6 @@ export type SendUserOperationParameters< entryPoint extends EntryPoint, TAccount extends SmartAccount | undefined = | SmartAccount - | undefined, - TEip7677Client extends Eip7677Client | undefined = - | Eip7677Client | undefined > = { userOperation: entryPoint extends ENTRYPOINT_ADDRESS_V06_TYPE @@ -61,7 +57,7 @@ export type SendUserOperationParameters< | "signature" > } & GetAccountParameter & - Middleware + Middleware export async function sendUserOperation< entryPoint extends EntryPoint, @@ -69,15 +65,10 @@ export async function sendUserOperation< TChain extends Chain | undefined = Chain | undefined, TAccount extends SmartAccount | undefined = | SmartAccount - | undefined, - TEip7677Client extends Eip7677Client | undefined = - | Eip7677Client | undefined >( client: Client, - args: Prettify< - SendUserOperationParameters - > + args: Prettify> ): Promise { const { account: account_ = client.account } = args if (!account_) throw new AccountOrClientNotFoundError() @@ -86,13 +77,7 @@ export async function sendUserOperation< const userOperation = await getAction( client, - prepareUserOperationRequest< - entryPoint, - TTransport, - TChain, - TAccount, - TEip7677Client - >, + prepareUserOperationRequest, "prepareUserOperationRequest" )(args) diff --git a/packages/permissionless/actions/smartAccount/writeContract.ts b/packages/permissionless/actions/smartAccount/writeContract.ts index 1852da94..bb86bc25 100644 --- a/packages/permissionless/actions/smartAccount/writeContract.ts +++ b/packages/permissionless/actions/smartAccount/writeContract.ts @@ -12,7 +12,6 @@ import { } from "viem" import { getAction } from "viem/utils" import type { SmartAccount } from "../../accounts/types" -import type { Eip7677Client } from "../../experimental" import type { EntryPoint } from "../../types/entrypoint" import type { Middleware } from "./prepareUserOperationRequest" import { @@ -77,9 +76,6 @@ export type WriteContractWithPaymasterParameters< TAccount extends SmartAccount | undefined = | SmartAccount | undefined, - TEip7677Client extends Eip7677Client | undefined = - | Eip7677Client - | undefined, TAbi extends Abi | readonly unknown[] = Abi | readonly unknown[], TFunctionName extends ContractFunctionName< TAbi, @@ -99,16 +95,13 @@ export type WriteContractWithPaymasterParameters< TAccount, TChainOverride > & - Middleware + Middleware export async function writeContract< entryPoint extends EntryPoint, TChain extends Chain | undefined, TAccount extends SmartAccount | undefined, const TAbi extends Abi | readonly unknown[], - TEip7677Client extends Eip7677Client | undefined = - | Eip7677Client - | undefined, TFunctionName extends ContractFunctionName< TAbi, "nonpayable" | "payable" @@ -132,7 +125,6 @@ export async function writeContract< entryPoint, TChain, TAccount, - TEip7677Client, TAbi, TFunctionName, TArgs, diff --git a/packages/permissionless/clients/createSmartAccountClient.ts b/packages/permissionless/clients/createSmartAccountClient.ts index b31c4a5d..9d05170e 100644 --- a/packages/permissionless/clients/createSmartAccountClient.ts +++ b/packages/permissionless/clients/createSmartAccountClient.ts @@ -8,7 +8,6 @@ import type { import { createClient } from "viem" import { type SmartAccount } from "../accounts/types" import { type Middleware } from "../actions/smartAccount/prepareUserOperationRequest" -import { type Eip7677Client } from "../experimental" import type { Prettify } from "../types/" import { type BundlerRpcSchema } from "../types/bundler" import type { EntryPoint } from "../types/entrypoint" @@ -45,16 +44,13 @@ export type SmartAccountClientConfig< chain extends Chain | undefined = Chain | undefined, account extends SmartAccount | undefined = | SmartAccount - | undefined, - TEip7677Client extends Eip7677Client | undefined = - | Eip7677Client | undefined > = Prettify< Pick< ClientConfig, "cacheTime" | "chain" | "key" | "name" | "pollingInterval" > & - Middleware & { + Middleware & { account: account bundlerTransport: Transport } & { @@ -88,17 +84,13 @@ export function createSmartAccountClient< TChain extends Chain | undefined = undefined, TEntryPoint extends EntryPoint = TSmartAccount extends SmartAccount ? U - : never, - TEip7677Client extends Eip7677Client | undefined = - | Eip7677Client - | undefined + : never >( parameters: SmartAccountClientConfig< TEntryPoint, TTransport, TChain, - TSmartAccount, - TEip7677Client + TSmartAccount > ): SmartAccountClient { const { @@ -116,7 +108,6 @@ export function createSmartAccountClient< return client.extend( smartAccountActions({ - eip7677Client: parameters.eip7677Client, middleware: parameters.middleware }) ) as SmartAccountClient diff --git a/packages/permissionless/clients/decorators/smartAccount.ts b/packages/permissionless/clients/decorators/smartAccount.ts index b01e97d8..933b4cdd 100644 --- a/packages/permissionless/clients/decorators/smartAccount.ts +++ b/packages/permissionless/clients/decorators/smartAccount.ts @@ -39,7 +39,6 @@ import { type WriteContractWithPaymasterParameters, writeContract } from "../../actions/smartAccount/writeContract" -import type { Eip7677Client } from "../../experimental" import type { Prettify } from "../../types/" import type { StateOverrides } from "../../types/bundler" import type { EntryPoint } from "../../types/entrypoint" @@ -49,9 +48,6 @@ export type SmartAccountActions< TChain extends Chain | undefined = Chain | undefined, TSmartAccount extends SmartAccount | undefined = | SmartAccount - | undefined, - TEip7677Client extends Eip7677Client | undefined = - | Eip7677Client | undefined > = { /** @@ -380,7 +376,6 @@ export type SmartAccountActions< TChain, TSmartAccount, TAbi, - TEip7677Client, TFunctionName, TArgs, TChainOverride @@ -393,8 +388,7 @@ export type SmartAccountActions< entryPoint, TTransport, TChain, - TSmartAccount, - TEip7677Client + TSmartAccount > >[1] >, @@ -407,8 +401,7 @@ export type SmartAccountActions< entryPoint, TTransport, TChain, - TSmartAccount, - TEip7677Client + TSmartAccount > >[1] > @@ -464,21 +457,14 @@ export type SmartAccountActions< */ sendTransactions: ( args: Prettify< - SendTransactionsWithPaymasterParameters< - entryPoint, - TSmartAccount, - TEip7677Client - > + SendTransactionsWithPaymasterParameters > ) => ReturnType> } -export function smartAccountActions< - entryPoint extends EntryPoint, - TEip7677Client extends Eip7677Client | undefined = - | Eip7677Client - | undefined ->({ eip7677Client, middleware }: Middleware) { +export function smartAccountActions({ + middleware +}: Middleware) { return < TTransport extends Transport, TChain extends Chain | undefined = Chain | undefined, @@ -493,28 +479,18 @@ export function smartAccountActions< client, { ...args, - eip7677Client, middleware }, stateOverrides ), deployContract: (args) => - deployContract( - client, - { - ...args, - eip7677Client, - middleware - } as unknown as DeployContractParametersWithPaymaster< - entryPoint, - TSmartAccount, - TEip7677Client - > - ), + deployContract(client, { + ...args, + middleware + } as DeployContractParametersWithPaymaster), sendTransaction: (args) => sendTransaction(client, { ...args, - eip7677Client, middleware } as SendTransactionWithPaymasterParameters< entryPoint, @@ -524,7 +500,6 @@ export function smartAccountActions< sendTransactions: (args) => sendTransactions(client, { ...args, - eip7677Client, middleware }), sendUserOperation: (args) => @@ -532,7 +507,6 @@ export function smartAccountActions< client, { ...args, - eip7677Client, middleware } as SendUserOperationParameters ), @@ -587,13 +561,11 @@ export function smartAccountActions< ) => writeContract(client, { ...args, - eip7677Client, middleware } as WriteContractWithPaymasterParameters< entryPoint, TChain, TSmartAccount, - TEip7677Client, TAbi >) }) diff --git a/packages/permissionless/experimental/eip7677/clients/createEip7677Client.ts b/packages/permissionless/experimental/eip7677/clients/createEip7677Client.ts deleted file mode 100644 index b89ba8b3..00000000 --- a/packages/permissionless/experimental/eip7677/clients/createEip7677Client.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { - type Chain, - type Client, - type PublicClientConfig, - type Transport, - createClient -} from "viem" -import type { EntryPoint } from "../../../types/entrypoint" -import type { Eip7677RpcSchema } from "../types/paymaster" -import { type Eip7677Actions, eip7677Actions } from "./decorators/eip7677" - -export type Eip7677Client< - TEntryPoint extends EntryPoint, - TChain extends Chain | undefined = Chain | undefined -> = Client< - Transport, - TChain, - undefined, - Eip7677RpcSchema, - Eip7677Actions -> - -export const createEip7677Client = < - TEntryPoint extends EntryPoint, - TTransport extends Transport = Transport, - TChain extends Chain | undefined = Chain | undefined ->( - parameters: PublicClientConfig & { - entryPoint: TEntryPoint - } -): Eip7677Client => { - const { key = "public", name = "EIP 7677 paymaster client" } = parameters - const client = createClient({ - ...parameters, - key, - name, - type: "bundlerClient" - }) - return client.extend(eip7677Actions({ entryPoint: parameters.entryPoint })) -} diff --git a/packages/permissionless/experimental/eip7677/clients/decorators/eip7677.ts b/packages/permissionless/experimental/eip7677/clients/decorators/eip7677.ts index f63bd444..837366c4 100644 --- a/packages/permissionless/experimental/eip7677/clients/decorators/eip7677.ts +++ b/packages/permissionless/experimental/eip7677/clients/decorators/eip7677.ts @@ -11,7 +11,7 @@ import { type GetPaymasterStubDataReturnType, getPaymasterStubData } from "../../actions/getPaymasterStubData" -import type { Eip7677Client } from "../createEip7677Client" +import type { Eip7677RpcSchema } from "../../types/paymaster" export type Eip7677Actions< TEntryPoint extends EntryPoint, @@ -52,19 +52,35 @@ const eip7677Actions = client: Client ): Eip7677Actions => ({ getPaymasterData: (args) => - getPaymasterData(client as Eip7677Client, { - userOperation: args.userOperation, - context: args.context, - chain: args.chain, - entryPoint - }), + getPaymasterData( + client as Client< + TTransport, + TChain, + undefined, + Eip7677RpcSchema + >, + { + userOperation: args.userOperation, + context: args.context, + chain: args.chain, + entryPoint + } + ), getPaymasterStubData: async (args) => - getPaymasterStubData(client as Eip7677Client, { - userOperation: args.userOperation, - context: args.context, - chain: args.chain, - entryPoint - }) + getPaymasterStubData( + client as Client< + TTransport, + TChain, + undefined, + Eip7677RpcSchema + >, + { + userOperation: args.userOperation, + context: args.context, + chain: args.chain, + entryPoint + } + ) }) export { eip7677Actions } diff --git a/packages/permissionless/experimental/eip7677/index.ts b/packages/permissionless/experimental/eip7677/index.ts index 03c33b30..250dc14f 100644 --- a/packages/permissionless/experimental/eip7677/index.ts +++ b/packages/permissionless/experimental/eip7677/index.ts @@ -8,10 +8,6 @@ import { type GetPaymasterStubDataReturnType, getPaymasterStubData } from "./actions/getPaymasterStubData" -import { - type Eip7677Client, - createEip7677Client -} from "./clients/createEip7677Client" import { type Eip7677Actions, eip7677Actions @@ -25,8 +21,6 @@ export { type GetPaymasterDataReturnType, type GetPaymasterDataParameters, getPaymasterData, - type Eip7677Client, - createEip7677Client, type Eip7677Actions, eip7677Actions, type Eip7677RpcSchema From 669afaa497aa9c20ef2e1ce2c97737b5038b4068 Mon Sep 17 00:00:00 2001 From: Garvit Khatri Date: Mon, 6 May 2024 15:53:15 +0530 Subject: [PATCH 3/7] rename to paymasterActionsEip7677 --- .../src/ep-0.6/experiments.ts | 18 ++++++------------ packages/permissionless-test/src/utils.ts | 4 ++-- .../{eip7677.ts => paymasterActionsEip7677.ts} | 8 ++++---- .../experimental/eip7677/index.ts | 10 +++++----- 4 files changed, 17 insertions(+), 23 deletions(-) rename packages/permissionless/experimental/eip7677/clients/decorators/{eip7677.ts => paymasterActionsEip7677.ts} (94%) diff --git a/packages/permissionless-test/src/ep-0.6/experiments.ts b/packages/permissionless-test/src/ep-0.6/experiments.ts index 95b9545c..5227544f 100644 --- a/packages/permissionless-test/src/ep-0.6/experiments.ts +++ b/packages/permissionless-test/src/ep-0.6/experiments.ts @@ -3,23 +3,15 @@ import { createSmartAccountClient } from "permissionless" import { privateKeyToSafeSmartAccount } from "permissionless/accounts" -import { Eip7677Actions, eip7677Actions } from "permissionless/experimental" +import { paymasterActionsEip7677 } from "permissionless/experimental" import type { ENTRYPOINT_ADDRESS_V06_TYPE } from "permissionless/types" -import { - http, - type Chain, - Client, - Transport, - createClient, - zeroAddress -} from "viem" +import { http, createClient, zeroAddress } from "viem" import { generatePrivateKey } from "viem/accounts" import { foundry } from "viem/chains" -import { beforeAll, describe, test } from "vitest" +import { describe, test } from "vitest" import type { AAParamType } from "../types" import { PAYMASTER_RPC, - getEip7677Client, getPimlicoPaymasterClient, getPublicClient, getSafeClient @@ -68,7 +60,9 @@ describe.each([ const eip7677Client = createClient({ chain: foundry, transport: http(PAYMASTER_RPC) - }).extend(eip7677Actions({ entryPoint: ENTRYPOINT_ADDRESS_V06 })) + }).extend( + paymasterActionsEip7677({ entryPoint: ENTRYPOINT_ADDRESS_V06 }) + ) const response = await eip7677Client.getPaymasterData({ userOperation: userOperaton diff --git a/packages/permissionless-test/src/utils.ts b/packages/permissionless-test/src/utils.ts index 8a3aee36..152bb072 100644 --- a/packages/permissionless-test/src/utils.ts +++ b/packages/permissionless-test/src/utils.ts @@ -22,7 +22,7 @@ import { createPimlicoBundlerClient, createPimlicoPaymasterClient } from "permissionless/clients/pimlico" -import { type Eip7677Client, eip7677Actions } from "permissionless/experimental" +import { paymasterActionsEip7677 } from "permissionless/experimental" import type { ENTRYPOINT_ADDRESS_V06_TYPE, EntryPoint @@ -322,7 +322,7 @@ export const getEip7677Client = async ({ const client = createClient({ chain: foundry, transport: http(PAYMASTER_RPC) - }).extend(eip7677Actions({ entryPoint })) + }).extend(paymasterActionsEip7677({ entryPoint })) return client } diff --git a/packages/permissionless/experimental/eip7677/clients/decorators/eip7677.ts b/packages/permissionless/experimental/eip7677/clients/decorators/paymasterActionsEip7677.ts similarity index 94% rename from packages/permissionless/experimental/eip7677/clients/decorators/eip7677.ts rename to packages/permissionless/experimental/eip7677/clients/decorators/paymasterActionsEip7677.ts index 837366c4..406e1f62 100644 --- a/packages/permissionless/experimental/eip7677/clients/decorators/eip7677.ts +++ b/packages/permissionless/experimental/eip7677/clients/decorators/paymasterActionsEip7677.ts @@ -13,7 +13,7 @@ import { } from "../../actions/getPaymasterStubData" import type { Eip7677RpcSchema } from "../../types/paymaster" -export type Eip7677Actions< +export type PaymasterActionsEip7677< TEntryPoint extends EntryPoint, TChain extends Chain | undefined = Chain | undefined > = { @@ -41,7 +41,7 @@ export type Eip7677Actions< ) => Promise> } -const eip7677Actions = +const paymasterActionsEip7677 = ({ entryPoint }: { entryPoint: TEntryPoint }) => @@ -50,7 +50,7 @@ const eip7677Actions = TChain extends Chain | undefined = Chain | undefined >( client: Client - ): Eip7677Actions => ({ + ): PaymasterActionsEip7677 => ({ getPaymasterData: (args) => getPaymasterData( client as Client< @@ -83,4 +83,4 @@ const eip7677Actions = ) }) -export { eip7677Actions } +export { paymasterActionsEip7677 } diff --git a/packages/permissionless/experimental/eip7677/index.ts b/packages/permissionless/experimental/eip7677/index.ts index 250dc14f..60669669 100644 --- a/packages/permissionless/experimental/eip7677/index.ts +++ b/packages/permissionless/experimental/eip7677/index.ts @@ -9,9 +9,9 @@ import { getPaymasterStubData } from "./actions/getPaymasterStubData" import { - type Eip7677Actions, - eip7677Actions -} from "./clients/decorators/eip7677" + type PaymasterActionsEip7677, + paymasterActionsEip7677 +} from "./clients/decorators/paymasterActionsEip7677" import type { Eip7677RpcSchema } from "./types/paymaster" export { @@ -21,7 +21,7 @@ export { type GetPaymasterDataReturnType, type GetPaymasterDataParameters, getPaymasterData, - type Eip7677Actions, - eip7677Actions, + type PaymasterActionsEip7677, + paymasterActionsEip7677, type Eip7677RpcSchema } From 91701f52b1fb173b89e78235e2e393fb63052e67 Mon Sep 17 00:00:00 2001 From: Garvit Khatri Date: Mon, 6 May 2024 15:56:17 +0530 Subject: [PATCH 4/7] remove sponsore as it may break soon --- .../experimental/eip7677/actions/getPaymasterData.ts | 4 ---- .../permissionless/experimental/eip7677/types/paymaster.ts | 2 -- 2 files changed, 6 deletions(-) diff --git a/packages/permissionless/experimental/eip7677/actions/getPaymasterData.ts b/packages/permissionless/experimental/eip7677/actions/getPaymasterData.ts index 1dc0f368..e6089a1a 100644 --- a/packages/permissionless/experimental/eip7677/actions/getPaymasterData.ts +++ b/packages/permissionless/experimental/eip7677/actions/getPaymasterData.ts @@ -36,11 +36,9 @@ export type GetPaymasterDataParameters< export type GetPaymasterDataReturnType = GetEntryPointVersion extends "v0.6" ? { - sponsor?: { name: string; icon: string } paymasterAndData: Hex } : { - sponsor?: { name: string; icon: string } paymaster: Hex paymasterData: Hex } @@ -110,7 +108,6 @@ export async function getPaymasterData< response as GetRpcPaymasterDataReturnType return { - sponsor: responseV06.sponsor, paymasterAndData: responseV06.paymasterAndData } as GetPaymasterDataReturnType } @@ -119,7 +116,6 @@ export async function getPaymasterData< response as GetRpcPaymasterDataReturnType return { - sponsor: responseV07.sponsor, paymaster: responseV07.paymaster, paymasterData: responseV07.paymasterData } as GetPaymasterDataReturnType diff --git a/packages/permissionless/experimental/eip7677/types/paymaster.ts b/packages/permissionless/experimental/eip7677/types/paymaster.ts index 31ac958d..de1342f0 100644 --- a/packages/permissionless/experimental/eip7677/types/paymaster.ts +++ b/packages/permissionless/experimental/eip7677/types/paymaster.ts @@ -38,11 +38,9 @@ export type GetRpcPaymasterDataParameters = [ export type GetRpcPaymasterDataReturnType = GetEntryPointVersion extends "v0.6" ? { - sponsor?: { name: string; icon: string } paymasterAndData: Hex } : { - sponsor?: { name: string; icon: string } paymaster: Hex paymasterData: Hex } From be6d2a3d4b394939e3601f12a075bdfe16276dde Mon Sep 17 00:00:00 2001 From: Garvit Khatri Date: Mon, 6 May 2024 16:18:18 +0530 Subject: [PATCH 5/7] add changeset --- .changeset/mean-otters-arrive.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/mean-otters-arrive.md diff --git a/.changeset/mean-otters-arrive.md b/.changeset/mean-otters-arrive.md new file mode 100644 index 00000000..dab8cb3b --- /dev/null +++ b/.changeset/mean-otters-arrive.md @@ -0,0 +1,5 @@ +--- +"permissionless": patch +--- + +Added experimental EIP 7677 support From fb64098eb6583ab2401237c9461c7ba9a494873d Mon Sep 17 00:00:00 2001 From: Garvit Khatri Date: Mon, 6 May 2024 16:22:46 +0530 Subject: [PATCH 6/7] fix export --- packages/permissionless/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/permissionless/package.json b/packages/permissionless/package.json index 741b6df4..e4b25db1 100644 --- a/packages/permissionless/package.json +++ b/packages/permissionless/package.json @@ -80,7 +80,7 @@ "import": "./_esm/types/index.js", "default": "./_cjs/types/index.js" }, - "./experimental/": { + "./experimental": { "types": "./_types/experimental/index.d.ts", "import": "./_esm/experimental/index.js", "default": "./_cjs/experimental/index.js" From 95f71fe6199e85e2904066a1277fdd4ffd46d72b Mon Sep 17 00:00:00 2001 From: Garvit Khatri Date: Mon, 6 May 2024 16:27:43 +0530 Subject: [PATCH 7/7] fix test --- packages/permissionless-test/src/utils.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/permissionless-test/src/utils.ts b/packages/permissionless-test/src/utils.ts index 152bb072..073fad39 100644 --- a/packages/permissionless-test/src/utils.ts +++ b/packages/permissionless-test/src/utils.ts @@ -209,6 +209,7 @@ export const getSimpleAccountClient = async ({ export const getLightAccountClient = async ({ entryPoint, + paymasterClient, privateKey = generatePrivateKey() }: AAParamType): Promise< SmartAccountClient>