@metamask/delegation-toolkit
Version:
The Delegation Toolkit built on top of Viem - a library for interacting with DeleGator Smart Accounts
1 lines • 38 kB
Source Map (JSON)
{"version":3,"sources":["/home/runner/work/delegation-toolkit/delegation-toolkit/packages/delegation-toolkit/dist/experimental/index.cjs","../../src/experimental/erc7710RedeemDelegationAction.ts","../../src/experimental/erc7715RequestExecutionPermissionsAction.ts","../../src/experimental/delegationStorage.ts","../../src/experimental/index.ts"],"names":[],"mappings":"AAAA;AACE;AACF,yDAA8B;AAC9B;AACE;AACA;AACF,yDAA8B;AAC9B;AACE;AACF,yDAA8B;AAC9B;AACA;ACXA,2DAAkC;AAYlC,4BAA2D;AAsC3D,MAAA,SAAsB,mCAAA,CAIpB,MAAA,EACA,IAAA,EACA;AACA,EAAA,GAAA,CAAI,CAAC,IAAA,CAAK,EAAA,EAAI;AACZ,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,IACF,CAAA;AAAA,EACF;AAEA,EAAA,MAAM,WAAA,EAAa;AAAA,IACjB,+CAAA;AAAgB,MACd,MAAA,EAAQ,IAAA,CAAK,EAAA;AAAA,MACb,KAAA,EAAO,IAAA,CAAK,KAAA;AAAA,MACZ,QAAA,EAAU,IAAA,CAAK;AAAA,IACjB,CAAC;AAAA,EACH,CAAA;AAEA,EAAA,MAAM,SAAA,EAAW,sCAAA;AAAmB,IAClC,GAAA,EAAK,iCAAA,CAAkB,GAAA;AAAA,IACvB,YAAA,EAAc,mBAAA;AAAA,IACd,IAAA,EAAM;AAAA,MACJ,CAAC,IAAA,CAAK,kBAAkB,CAAA;AAAA,MACxB,CAAA,wFAA4B,CAAA;AAAA,MAC5B,wDAAA,CAA0B,UAAU,CAAC;AAAA,IACvC;AAAA,EACF,CAAC,CAAA;AAED,EAAA,MAAM;AAAA,IACJ,KAAA,EAAO,MAAA;AAAA,IACP,kBAAA,EAAoB,mBAAA;AAAA,IACpB,iBAAA,EAAmB,kBAAA;AAAA,IACnB,GAAG;AAAA,EACL,EAAA,EAAI,IAAA;AAEJ,EAAA,MAAM,KAAA,EAAO,MAAM,MAAA,CAAO,eAAA,CAAgB;AAAA,IACxC,GAAG,IAAA;AAAA,IACH,EAAA,EAAI,IAAA,CAAK,iBAAA;AAAA,IACT,IAAA,EAAM;AAAA,EACR,CAAyC,CAAA;AAEzC,EAAA,OAAO,IAAA;AACT;AA2CA,MAAA,SAAsB,qCAAA,CAIpB,MAAA,EACA,UAAA,EAIA;AACA,EAAA,GAAA,CAAI,UAAA,CAAW,eAAA,EAAiB;AAC9B,IAAA,MAAM,EAAE,aAAa,EAAA,EAAI,UAAA;AAEzB,IAAA,MAAM,oBAAA,EAA4C,CAAC,CAAA;AAEnD,IAAA,MAAM,QAAA,kBAAU,YAAA,qBAAa,KAAA,6BAAO,IAAA;AAEpC,IAAA,GAAA,CAAI,CAAC,OAAA,EAAS;AACZ,MAAA,MAAM,IAAI,KAAA,CAAM,qBAAqB,CAAA;AAAA,IACvC;AAEA,IAAA,MAAM,EAAE,cAAc,EAAA,EAAI,uDAAA,OAA+B,CAAA;AAEzD,IAAA,MAAM,uBAAA,EAAyB,UAAA,CAAW,eAAA,CAAgB,MAAA;AAAA,MACxD,CAAC,eAAA,EAAA,GAAoB;AACnB,QAAA,GAAA,CAAI,CAAC,kCAAA,eAAe,CAAgB,OAAA,EAAS,aAAa,CAAA,EAAG;AAC3D,UAAA,MAAM,IAAI,KAAA;AAAA,YACR,CAAA,yBAAA,EAA4B,eAAA,CAAgB,OAAO,CAAA,gBAAA;AAAA,UACrD,CAAA;AAAA,QACF;AAGA,QAAA,MAAM,WAAA,EAAa,0BAAA;AAAO,UACxB,eAAA,CAAgB,OAAA;AAAA,UAChB,eAAA,CAAgB;AAAA,QAClB,CAAC,CAAA;AACD,QAAA,MAAM,YAAA,EAAc,mBAAA,CAAoB,UAAU,CAAA;AAElD,QAAA,mBAAA,CAAoB,UAAU,EAAA,EAAI,IAAA;AAClC,QAAA,OAAO,CAAC,WAAA;AAAA,MACV;AAAA,IACF,CAAA;AAEA,IAAA,MAAM,aAAA,EAAA,CACJ,MAAM,OAAA,CAAQ,GAAA;AAAA,MACZ,sBAAA,CAAuB,GAAA,CAAI,MAAA,CAAO,EAAE,OAAA,EAAS,YAAY,CAAA,EAAA,GAAM;AAC7D,QAAA,MAAM,WAAA,EAAa,MAAM,YAAA,CACtB,IAAA,CAAK;AAAA,UACJ,EAAA,EAAI,OAAA;AAAA,UACJ,IAAA,EAAM;AAAA,QACR,CAAC,CAAA,CACA,IAAA,CAAK,CAAA,EAAA,GAAM,KAAK,CAAA,CAChB,KAAA,CAAM,CAAA,EAAA,GAAM,IAAI,CAAA;AAEnB,QAAA,GAAA,CAAI,UAAA,EAAY;AACd,UAAA,OAAO,KAAA,CAAA;AAAA,QACT;AACA,QAAA,OAAO;AAAA,UACL,EAAA,EAAI,OAAA;AAAA,UACJ,KAAA,EAAO,EAAA;AAAA,UACP,IAAA,EAAM;AAAA,QACR,CAAA;AAAA,MACF,CAAC;AAAA,IACH,CAAA,CAAA,CACA,MAAA,CAAO,CAAC,IAAA,EAAA,GAA2B,KAAA,IAAS,KAAA,CAAS,CAAA;AAEvD,IAAA,UAAA,CAAW,MAAA,EAAQ;AAAA,MACjB,GAAI,YAAA;AAAA,MACJ,GAAG,UAAA,CAAW;AAAA,IAChB,CAAA;AAAA,EACF;AAEA,EAAA,OAAO,MAAA,CAAO,iBAAA;AAAA,IACZ;AAAA,EACF,CAAA;AACF;ADlHA;AACA;AEzFA;AA+JA,MAAA,SAAsB,wCAAA,CACpB,MAAA,EACA,UAAA,EACgD;AAChD,EAAA,MAAM,2BAAA,EAA6B,UAAA,CAAW,GAAA,CAAI,wBAAwB,CAAA;AAE1E,EAAA,MAAM,OAAA,EAAS,MAAM,MAAA,CAAO,OAAA;AAAA,IAC1B;AAAA,MACE,MAAA,EAAQ,oCAAA;AAAA,MACR,MAAA,EAAQ;AAAA,IACV,CAAA;AAAA,IACA,EAAE,UAAA,EAAY,EAAE;AAAA,EAClB,CAAA;AAEA,EAAA,GAAA,CAAI,CAAC,MAAA,EAAQ;AACX,IAAA,MAAM,IAAI,KAAA,CAAM,6BAA6B,CAAA;AAAA,EAC/C;AAEA,EAAA,OAAO,MAAA;AACT;AASA,SAAS,wBAAA,CACP,UAAA,EACmD;AACnD,EAAA,MAAM,EAAE,OAAA,EAAS,OAAA,EAAS,MAAA,EAAQ,oBAAoB,EAAA,EAAI,UAAA;AAE1D,EAAA,MAAM,oBAAA,EAAsB,sBAAA;AAAA,IAC1B,UAAA,CAAW,UAAA,CAAW;AAAA,EACxB,CAAA;AAEA,EAAA,MAAM,cAAA,EACJ,OAAO,UAAA,CAAW,OAAA,IAAW,SAAA,EACzB,UAAA,CAAW,OAAA,EACX,UAAA,CAAW,MAAA,CAAO,IAAA,CAAK,OAAA;AAE7B,EAAA,MAAM,MAAA,EAAgB;AAAA,IACpB;AAAA,MACE,IAAA,EAAM,QAAA;AAAA,MACN,mBAAA;AAAA,MACA,IAAA,EAAM;AAAA,QACJ,SAAA,EAAW;AAAA,MACb;AAAA,IACF;AAAA,EACF,CAAA;AAEA,EAAA,MAAM,eAAA,EAAiB;AAAA,IACrB,GAAI,QAAA,EAAU,EAAE,QAAQ,EAAA,EAAI,CAAC;AAAA,EAC/B,CAAA;AAEA,EAAA,OAAO;AAAA,IACL,GAAG,cAAA;AAAA,IACH,OAAA,EAAS,yBAAA,OAAa,CAAA;AAAA,IACtB,UAAA,EAAY,mBAAA,CAAoB;AAAA,MAC9B,UAAA,EAAY,UAAA,CAAW,UAAA;AAAA,MACvB;AAAA,IACF,CAAC,CAAA;AAAA,IACD,MAAA,EAAQ;AAAA;AAAA,MAEN,IAAA,EAAM,SAAA;AAAA,MACN,IAAA,EAAM;AAAA,QACJ,OAAA,EAAS;AAAA,MACX;AAAA,IACF,CAAA;AAAA,IACA;AAAA,EACF,CAAA;AACF;AAQA,SAAS,SAAA,CAAkB,KAAA,EAAmD;AAC5E,EAAA,OAAO,MAAA,IAAU,KAAA,EAAA,GAAa,MAAA,IAAU,IAAA;AAC1C;AASA,SAAS,eAAA,CACP,KAAA,EACA,OAAA,EACyB;AACzB,EAAA,GAAA,CAAI,CAAC,SAAA,CAAU,KAAK,CAAA,EAAG;AACrB,IAAA,MAAM,IAAI,KAAA,kBAAM,OAAA,UAAW,yCAAuC,CAAA;AAAA,EACpE;AACF;AASA,SAAS,YAAA,CACP,KAAA,EACA,OAAA,EACA;AACA,EAAA,eAAA,CAAgB,KAAA,EAAO,OAAO,CAAA;AAE9B,EAAA,GAAA,CAAI,OAAO,MAAA,IAAU,QAAA,EAAU;AAC7B,IAAA,GAAA,CAAI,CAAC,yBAAA,KAAW,CAAA,EAAG;AACjB,MAAA,MAAM,IAAI,KAAA,CAAM,uCAAuC,CAAA;AAAA,IACzD;AACA,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,OAAO,yBAAA,KAAW,CAAA;AACpB;AAaA,SAAS,sBAAA,CAAuB,cAAA,EAA6C;AAC3E,EAAA,OAAA,CAAQ,cAAA,EAAgB;AAAA,IACtB,KAAK,qBAAA;AACH,MAAA,OAAO,CAAC,EAAE,UAAA,EAAY,oBAAoB,CAAA,EAAA,GACxC,iCAAA,CAAkC;AAAA,QAChC,UAAA;AAAA,QACA;AAAA,MACF,CAAC,CAAA;AAAA,IACL,KAAK,oBAAA;AACH,MAAA,OAAO,CAAC,EAAE,UAAA,EAAY,oBAAoB,CAAA,EAAA,GACxC,gCAAA,CAAiC;AAAA,QAC/B,UAAA;AAAA,QACA;AAAA,MACF,CAAC,CAAA;AAAA,IAEL,KAAK,uBAAA;AACH,MAAA,OAAO,CAAC,EAAE,UAAA,EAAY,oBAAoB,CAAA,EAAA,GACxC,mCAAA,CAAoC;AAAA,QAClC,UAAA;AAAA,QACA;AAAA,MACF,CAAC,CAAA;AAAA,IACL,KAAK,sBAAA;AACH,MAAA,OAAO,CAAC,EAAE,UAAA,EAAY,oBAAoB,CAAA,EAAA,GACxC,kCAAA,CAAmC;AAAA,QACjC,UAAA;AAAA,QACA;AAAA,MACF,CAAC,CAAA;AAAA,IACL,OAAA;AACE,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,6BAAA,EAAgC,cAAc,CAAA,CAAA;AAClE,EAAA;AACF;AAU2C;AACzC,EAAA;AACA,EAAA;AAI8B;AACxB,EAAA;AACE,IAAA;AACJ,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACF,IAAA;AACE,EAAA;AAEmB,EAAA;AACW,IAAA;AACW,MAAA;AAC3C,IAAA;AAC4B,IAAA;AACO,MAAA;AACnC,IAAA;AAC4B,IAAA;AACC,MAAA;AAC7B,IAAA;AACyC,IAAA;AAC3C,EAAA;AAEO,EAAA;AACC,IAAA;AACA,IAAA;AACa,MAAA;AACf,QAAA;AACA,QAAA;AACF,MAAA;AACG,MAAA;AACL,IAAA;AACA,IAAA;AACF,EAAA;AACF;AAY0C;AACxC,EAAA;AACA,EAAA;AAI6B;AACvB,EAAA;AACE,IAAA;AACJ,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACF,IAAA;AACE,EAAA;AAEmB,EAAA;AACW,IAAA;AACW,MAAA;AAC3C,IAAA;AAC4B,IAAA;AACO,MAAA;AACnC,IAAA;AAC4B,IAAA;AACC,MAAA;AAC7B,IAAA;AACyC,IAAA;AAC3C,EAAA;AAEO,EAAA;AACC,IAAA;AACA,IAAA;AACmC,MAAA;AACM,MAAA;AAC1C,MAAA;AACL,IAAA;AACA,IAAA;AACF,EAAA;AACF;AAU6C;AAC3C,EAAA;AACA,EAAA;AAIgC;AAC1B,EAAA;AAC2D,IAAA;AAC7D,EAAA;AAEmB,EAAA;AACO,IAAA;AACC,MAAA;AAC7B,IAAA;AACyC,IAAA;AAC3C,EAAA;AAEO,EAAA;AACC,IAAA;AACA,IAAA;AACmC,MAAA;AACF,MAAA;AAClC,MAAA;AACL,IAAA;AACA,IAAA;AACF,EAAA;AACF;AAU4C;AAC1C,EAAA;AACA,EAAA;AAI+B;AACzB,EAAA;AACE,IAAA;AACJ,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACF,IAAA;AACE,EAAA;AAEmB,EAAA;AACO,IAAA;AACC,MAAA;AAC7B,IAAA;AACyC,IAAA;AAC3C,EAAA;AAEO,EAAA;AACC,IAAA;AACA,IAAA;AACmC,MAAA;AACA,MAAA;AACF,MAAA;AAClC,MAAA;AACL,IAAA;AACA,IAAA;AACF,EAAA;AACF;AFrMqE;AACA;AGlUrC;AA6CK;AACf,EAAA;AAEpB,EAAA;AAEA,EAAA;AAEA,EAAA;AAE6C,EAAA;AACjB,IAAA;AAEmB,IAAA;AAC5B,MAAA;AACV,IAAA;AACyC,MAAA;AACe,MAAA;AAC/D,IAAA;AAC8C,IAAA;AAC/B,IAAA;AACjB,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAakE,EAAA;AAC5C,IAAA;AACJ,MAAA;AACoC,IAAA;AACX,MAAA;AACzC,IAAA;AACU,IAAA;AACR,MAAA;AACF,IAAA;AACF,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAayB,EAAA;AAEd,IAAA;AAImB,IAAA;AAC4B,MAAA;AACtD,MAAA;AACU,QAAA;AACC,QAAA;AACqC,UAAA;AACf,UAAA;AAC/B,QAAA;AACF,MAAA;AACF,IAAA;AAEuE,IAAA;AAE1C,IAAA;AACjB,MAAA;AAC+C,QAAA;AACzD,MAAA;AACF,IAAA;AAEO,IAAA;AACT,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAce,EAAA;AAEe,IAAA;AAC6B,MAAA;AACvD,MAAA;AACU,QAAA;AACC,QAAA;AACqC,UAAA;AACf,UAAA;AAC/B,QAAA;AACF,MAAA;AACF,IAAA;AAEuE,IAAA;AAE1C,IAAA;AACkC,MAAA;AAC/D,IAAA;AAEO,IAAA;AACT,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQ4D,EAAA;AACE,IAAA;AACF,MAAA;AAC1D,IAAA;AAE2D,IAAA;AAEzC,IAAA;AAChB,MAAA;AACK,QAAA;AACQ,QAAA;AACb,MAAA;AAEgD,MAAA;AAGhD,MAAA;AACF,IAAA;AAEoD,IAAA;AAC1C,MAAA;AACC,MAAA;AACqC,QAAA;AACf,QAAA;AACb,QAAA;AAClB,MAAA;AACA,MAAA;AACD,IAAA;AAGqB,IAAA;AAEO,IAAA;AACO,MAAA;AACpC,IAAA;AAEoD,IAAA;AAC5C,MAAA;AACJ,QAAA;AACF,MAAA;AACF,IAAA;AAEoB,IAAA;AACtB,EAAA;AACF;AHqPqE;AACA;AI1aJ;AAG1D,EAAA;AACI,IAAA;AACL,MAAA;AACA,MAAA;AACF,IAAA;AACF,EAAA;AACF;AAEqE;AAG9D,EAAA;AACP;AAEgE;AAGzD,EAAA;AACP;AJoaqE;AACA;AACA;AACA;AACA;AACA;AACA","file":"/home/runner/work/delegation-toolkit/delegation-toolkit/packages/delegation-toolkit/dist/experimental/index.cjs","sourcesContent":[null,"import { DelegationManager } from '@metamask/delegation-abis';\nimport type {\n Account,\n Chain,\n Hex,\n OneOf,\n PublicClient,\n SendTransactionParameters,\n SendTransactionRequest,\n Transport,\n WalletClient,\n} from 'viem';\nimport { concat, encodeFunctionData, isAddressEqual } from 'viem';\nimport type {\n BundlerClient,\n SendUserOperationParameters,\n SmartAccount,\n} from 'viem/account-abstraction';\n\nimport { getDeleGatorEnvironment } from '../delegatorEnvironment';\nimport {\n createExecution,\n encodeExecutionCalldatas,\n ExecutionMode,\n} from '../executions';\nimport type { Call } from 'src/types';\n\nexport type DelegatedCall = Call &\n OneOf<{ permissionsContext: Hex; delegationManager: Hex } | object>;\n\nexport type SendTransactionWithDelegationParameters<\n TChain extends Chain | undefined = Chain | undefined,\n TAccount extends Account | undefined = Account | undefined,\n TChainOverride extends Chain | undefined = Chain | undefined,\n TRequest extends SendTransactionRequest<\n TChain,\n TChainOverride\n > = SendTransactionRequest<TChain, TChainOverride>,\n> = SendTransactionParameters<TChain, TAccount, TChainOverride, TRequest> & {\n permissionsContext: Hex;\n delegationManager: Hex;\n};\n\n/**\n * Sends a transaction using delegation to execute operations on behalf of another account.\n *\n * @param client - The wallet client to use for sending the transaction.\n * @param args - Transaction parameters with delegation details.\n * @returns Transaction hash of the executed transaction.\n */\nexport async function sendTransactionWithDelegationAction<\n TChain extends Chain | undefined,\n TAccount extends Account | undefined,\n>(\n client: WalletClient<Transport, TChain, TAccount>,\n args: SendTransactionWithDelegationParameters<TChain, TAccount>,\n) {\n if (!args.to) {\n throw new Error(\n '`to` is required. `sendTransactionWithDelegation` cannot be used to deploy contracts.',\n );\n }\n\n const executions = [\n createExecution({\n target: args.to,\n value: args.value,\n callData: args.data,\n }),\n ];\n\n const calldata = encodeFunctionData({\n abi: DelegationManager.abi,\n functionName: 'redeemDelegations',\n args: [\n [args.permissionsContext],\n [ExecutionMode.SingleDefault],\n encodeExecutionCalldatas([executions]),\n ],\n });\n\n const {\n value: _value,\n permissionsContext: _permissionsContext,\n delegationManager: _delegationManager,\n ...rest\n } = args;\n\n const hash = await client.sendTransaction({\n ...rest,\n to: args.delegationManager,\n data: calldata,\n } as unknown as SendTransactionParameters);\n\n return hash;\n}\n\nexport type SendUserOperationWithDelegationParameters<\n TAccount extends SmartAccount | undefined = SmartAccount | undefined,\n TAccountOverride extends SmartAccount | undefined = SmartAccount | undefined,\n> = SendUserOperationParameters<TAccount, TAccountOverride, DelegatedCall[]> & {\n accountMetadata?: { factory: Hex; factoryData: Hex }[];\n calls: DelegatedCall[];\n publicClient: PublicClient<Transport, Chain>;\n};\n\n/**\n * Broadcasts a User Operation with delegation to the Bundler.\n *\n * @param client - Client to use for sending the user operation.\n * @param parameters - Parameters for the user operation with delegation.\n * @returns The User Operation hash of the broadcasted operation.\n * @example\n * import { createBundlerClient, http } from 'viem'\n * import { mainnet } from 'viem/chains'\n *\n * const bundlerClient = createBundlerClient({\n * chain: mainnet,\n * transport: http(),\n * })\n *\n * const userOpHash = await sendUserOperationWithDelegationAction(bundlerClient, {\n * account: bobSmartAccount,\n * calls: [\n * {\n * to: aliceCounterContractAddress,\n * data: encodeFunctionData({\n * abi: CounterMetadata.abi,\n * functionName: 'increment',\n * }),\n * value: 0n,\n * permissionsContext: '0x...',\n * delegationManager: '0x...',\n * },\n * ],\n * accountMetadata: [{ factory: '0x...', factoryData: '0x...' }], // Optional: for deploying accounts\n * })\n */\nexport async function sendUserOperationWithDelegationAction<\n TAccount extends SmartAccount | undefined,\n TAccountOverride extends SmartAccount | undefined = undefined,\n>(\n client: BundlerClient<Transport, Chain | undefined, TAccount>,\n parameters: SendUserOperationWithDelegationParameters<\n TAccount,\n TAccountOverride\n >,\n) {\n if (parameters.accountMetadata) {\n const { publicClient } = parameters;\n\n const includedAccountKeys: Record<Hex, boolean> = {};\n\n const chainId = publicClient.chain?.id;\n\n if (!chainId) {\n throw new Error('Chain ID is not set');\n }\n\n const { SimpleFactory } = getDeleGatorEnvironment(chainId);\n\n const uniqueAccountMetadatas = parameters.accountMetadata.filter(\n (accountMetadata) => {\n if (!isAddressEqual(accountMetadata.factory, SimpleFactory)) {\n throw new Error(\n `Invalid accountMetadata: ${accountMetadata.factory} is not allowed.`,\n );\n }\n\n // ensure that factory calls are not duplicated\n const accountKey = concat([\n accountMetadata.factory,\n accountMetadata.factoryData,\n ]);\n const isDuplicate = includedAccountKeys[accountKey];\n\n includedAccountKeys[accountKey] = true;\n return !isDuplicate;\n },\n );\n\n const factoryCalls = (\n await Promise.all(\n uniqueAccountMetadatas.map(async ({ factory, factoryData }) => {\n const isDeployed = await publicClient\n .call({\n to: factory,\n data: factoryData,\n })\n .then(() => false)\n .catch(() => true);\n\n if (isDeployed) {\n return undefined;\n }\n return {\n to: factory,\n value: 0n,\n data: factoryData,\n };\n }),\n )\n ).filter((call: Call | undefined) => call !== undefined) as Call[];\n\n parameters.calls = [\n ...(factoryCalls as DelegatedCall[]),\n ...parameters.calls,\n ];\n }\n\n return client.sendUserOperation(\n parameters as unknown as SendUserOperationParameters,\n );\n}\n","import type {\n AccountSigner,\n Erc20TokenPeriodicPermission,\n Erc20TokenStreamPermission,\n NativeTokenPeriodicPermission,\n NativeTokenStreamPermission,\n PermissionRequest,\n PermissionResponse,\n PermissionTypes,\n Rule,\n} from '@metamask/7715-permission-types';\nimport { isHex, toHex } from 'viem';\nimport type {\n Client,\n Account,\n RpcSchema,\n Transport,\n Chain,\n Address,\n} from 'viem';\n\n/**\n * RPC schema for MetaMask related methods.\n *\n * Extends the base RPC schema with methods specific to interacting with EIP-7715:\n * - `wallet_invokeSnap`: Invokes a method on a specific Snap.\n */\nexport type MetaMaskExtensionSchema = RpcSchema &\n [\n {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n Method: 'wallet_requestExecutionPermissions';\n // eslint-disable-next-line @typescript-eslint/naming-convention\n Params: PermissionRequest<AccountSigner, PermissionTypes>[];\n // eslint-disable-next-line @typescript-eslint/naming-convention\n ReturnType: PermissionResponse<AccountSigner, PermissionTypes>[];\n },\n ];\n\n/**\n * A Viem client extended with MetaMask Snap-specific RPC methods.\n *\n * This client type allows for interaction with MetaMask Snaps through\n * the standard Viem client interface, with added type safety for\n * Snap-specific methods.\n */\nexport type MetaMaskExtensionClient = Client<\n Transport,\n Chain | undefined,\n Account | undefined,\n MetaMaskExtensionSchema\n>;\n\ntype PermissionParameter = {\n type: string;\n data: Record<string, unknown>;\n};\n\n/**\n * Represents a native token stream permission.\n * This allows for continuous token streaming with defined parameters.\n */\nexport type NativeTokenStreamPermissionParameter = PermissionParameter & {\n type: 'native-token-stream';\n data: {\n amountPerSecond: bigint;\n initialAmount?: bigint;\n maxAmount?: bigint;\n startTime?: number;\n justification?: string;\n };\n};\n\n/**\n * Represents an ERC-20 token stream permission.\n * This allows for continuous ERC-20 token streaming with defined parameters.\n */\nexport type Erc20TokenStreamPermissionParameter = PermissionParameter & {\n type: 'erc20-token-stream';\n data: {\n tokenAddress: Address;\n amountPerSecond: bigint;\n initialAmount?: bigint;\n maxAmount?: bigint;\n startTime?: number;\n justification?: string;\n };\n};\n\n/**\n * Represents a native token periodic permission.\n * This allows for periodic native token transfers with defined parameters.\n */\nexport type NativeTokenPeriodicPermissionParameter = PermissionParameter & {\n type: 'native-token-periodic';\n data: {\n periodAmount: bigint;\n periodDuration: number;\n startTime?: number;\n justification?: string;\n };\n};\n\n/**\n * Represents an ERC-20 token periodic permission.\n * This allows for periodic ERC-20 token transfers with defined parameters.\n */\nexport type Erc20TokenPeriodicPermissionParameter = PermissionParameter & {\n type: 'erc20-token-periodic';\n data: {\n tokenAddress: Address;\n periodAmount: bigint;\n periodDuration: number;\n startTime?: number;\n justification?: string;\n };\n};\n\nexport type SupportedPermissionParams =\n | NativeTokenStreamPermissionParameter\n | Erc20TokenStreamPermissionParameter\n | NativeTokenPeriodicPermissionParameter\n | Erc20TokenPeriodicPermissionParameter;\n\nexport type SignerParam = Address | AccountSigner;\n\n/**\n * Represents a single permission request.\n */\nexport type PermissionRequestParameter = {\n chainId: number;\n // The permission to grant to the user.\n permission: SupportedPermissionParams;\n // Whether the caller allows the permission to be adjusted.\n isAdjustmentAllowed: boolean;\n // Account to assign the permission to.\n signer: SignerParam;\n // address from which the permission should be granted.\n address?: Address;\n // Timestamp (in seconds) that specifies the time by which this permission MUST expire.\n expiry: number;\n};\n\n/**\n * Parameters for the RequestExecutionPermissions action.\n *\n * @template Signer - The type of the signer, either an Address or Account.\n */\nexport type RequestExecutionPermissionsParameters =\n PermissionRequestParameter[];\n\n/**\n * Return type for the request execution permissions action.\n */\nexport type RequestExecutionPermissionsReturnType = PermissionResponse<\n AccountSigner,\n PermissionTypes\n>[];\n\n/**\n * Grants permissions according to EIP-7715 specification.\n *\n * @template Signer - The type of the signer, either an Address or Account.\n * @param client - The client to use for the request.\n * @param parameters - The permissions requests to grant.\n * @returns A promise that resolves to the permission responses.\n * @description\n * This function formats the permissions requests and invokes the wallet method to grant permissions.\n * It will throw an error if the permissions could not be granted.\n */\nexport async function erc7715RequestExecutionPermissionsAction(\n client: MetaMaskExtensionClient,\n parameters: RequestExecutionPermissionsParameters,\n): Promise<RequestExecutionPermissionsReturnType> {\n const formattedPermissionRequest = parameters.map(formatPermissionsRequest);\n\n const result = await client.request(\n {\n method: 'wallet_requestExecutionPermissions',\n params: formattedPermissionRequest,\n },\n { retryCount: 0 },\n );\n\n if (!result) {\n throw new Error('Failed to grant permissions');\n }\n\n return result;\n}\n\n/**\n * Formats a permissions request for submission to the wallet.\n *\n * @param parameters - The permissions request to format.\n * @returns The formatted permissions request.\n * @internal\n */\nfunction formatPermissionsRequest(\n parameters: PermissionRequestParameter,\n): PermissionRequest<AccountSigner, PermissionTypes> {\n const { chainId, address, expiry, isAdjustmentAllowed } = parameters;\n\n const permissionFormatter = getPermissionFormatter(\n parameters.permission.type,\n );\n\n const signerAddress =\n typeof parameters.signer === 'string'\n ? parameters.signer\n : parameters.signer.data.address;\n\n const rules: Rule[] = [\n {\n type: 'expiry',\n isAdjustmentAllowed,\n data: {\n timestamp: expiry,\n },\n },\n ];\n\n const optionalFields = {\n ...(address ? { address } : {}),\n };\n\n return {\n ...optionalFields,\n chainId: toHex(chainId),\n permission: permissionFormatter({\n permission: parameters.permission,\n isAdjustmentAllowed,\n }),\n signer: {\n // MetaMask 7715 implementation only supports AccountSigner\n type: 'account',\n data: {\n address: signerAddress,\n },\n },\n rules,\n };\n}\n\n/**\n * Checks if a value is defined (not null or undefined).\n *\n * @param value - The value to check.\n * @returns A boolean indicating whether the value is defined.\n */\nfunction isDefined<TValue>(value: TValue | null | undefined): value is TValue {\n return value !== undefined && value !== null;\n}\n\n/**\n * Asserts that a value is defined (not null or undefined).\n *\n * @param value - The value to check.\n * @param message - Optional custom error message to throw if the value is not defined.\n * @throws {Error} If the value is null or undefined.\n */\nfunction assertIsDefined<TValue>(\n value: TValue | null | undefined,\n message?: string,\n): asserts value is TValue {\n if (!isDefined(value)) {\n throw new Error(message ?? 'Invalid parameters: value is required');\n }\n}\n\n/**\n * Converts a value to a hex string or throws an error if the value is invalid.\n *\n * @param value - The value to convert to hex.\n * @param message - Optional custom error message.\n * @returns The value as a hex string.\n */\nfunction toHexOrThrow(\n value: Parameters<typeof toHex>[0] | undefined,\n message?: string,\n) {\n assertIsDefined(value, message);\n\n if (typeof value === 'string') {\n if (!isHex(value)) {\n throw new Error('Invalid parameters: invalid hex value');\n }\n return value;\n }\n\n return toHex(value);\n}\n\ntype PermissionFormatter = (params: {\n permission: PermissionParameter;\n isAdjustmentAllowed: boolean;\n}) => PermissionTypes;\n\n/**\n * Gets the appropriate formatter function for a specific permission type.\n *\n * @param permissionType - The type of permission to format.\n * @returns A formatter function for the specified permission type.\n */\nfunction getPermissionFormatter(permissionType: string): PermissionFormatter {\n switch (permissionType) {\n case 'native-token-stream':\n return ({ permission, isAdjustmentAllowed }) =>\n formatNativeTokenStreamPermission({\n permission: permission as NativeTokenStreamPermissionParameter,\n isAdjustmentAllowed,\n });\n case 'erc20-token-stream':\n return ({ permission, isAdjustmentAllowed }) =>\n formatErc20TokenStreamPermission({\n permission: permission as Erc20TokenStreamPermissionParameter,\n isAdjustmentAllowed,\n });\n\n case 'native-token-periodic':\n return ({ permission, isAdjustmentAllowed }) =>\n formatNativeTokenPeriodicPermission({\n permission: permission as NativeTokenPeriodicPermissionParameter,\n isAdjustmentAllowed,\n });\n case 'erc20-token-periodic':\n return ({ permission, isAdjustmentAllowed }) =>\n formatErc20TokenPeriodicPermission({\n permission: permission as Erc20TokenPeriodicPermissionParameter,\n isAdjustmentAllowed,\n });\n default:\n throw new Error(`Unsupported permission type: ${permissionType}`);\n }\n}\n\n/**\n * Formats a native token stream permission for the wallet.\n *\n * @param permission - The native token stream permission to format.\n * @param permission.permission - The native token stream permission to format.\n * @param permission.isAdjustmentAllowed - Whether the permission is allowed to be adjusted.\n * @returns The formatted permission object.\n */\nfunction formatNativeTokenStreamPermission({\n permission,\n isAdjustmentAllowed,\n}: {\n permission: NativeTokenStreamPermissionParameter;\n isAdjustmentAllowed: boolean;\n}): NativeTokenStreamPermission {\n const {\n data: {\n initialAmount,\n justification,\n maxAmount,\n startTime,\n amountPerSecond,\n },\n } = permission;\n\n const optionalFields = {\n ...(isDefined(initialAmount) && {\n initialAmount: toHexOrThrow(initialAmount),\n }),\n ...(isDefined(maxAmount) && {\n maxAmount: toHexOrThrow(maxAmount),\n }),\n ...(isDefined(startTime) && {\n startTime: Number(startTime),\n }),\n ...(justification ? { justification } : {}),\n };\n\n return {\n type: 'native-token-stream',\n data: {\n amountPerSecond: toHexOrThrow(\n amountPerSecond,\n 'Invalid parameters: amountPerSecond is required',\n ),\n ...optionalFields,\n },\n isAdjustmentAllowed,\n };\n}\n\n/**\n * Formats an ERC-20 token stream permission parameter into the required\n * Erc20TokenStreamPermission object, converting numeric values to hex strings\n * and including only specified optional fields.\n *\n * @param params - The parameters for formatting the ERC-20 token stream permission.\n * @param params.permission - The ERC-20 token stream permission parameter to format.\n * @param params.isAdjustmentAllowed - Whether adjustment of the stream is allowed.\n * @returns The formatted Erc20TokenStreamPermission object.\n */\nfunction formatErc20TokenStreamPermission({\n permission,\n isAdjustmentAllowed,\n}: {\n permission: Erc20TokenStreamPermissionParameter;\n isAdjustmentAllowed: boolean;\n}): Erc20TokenStreamPermission {\n const {\n data: {\n tokenAddress,\n amountPerSecond,\n initialAmount,\n startTime,\n maxAmount,\n justification,\n },\n } = permission;\n\n const optionalFields = {\n ...(isDefined(initialAmount) && {\n initialAmount: toHexOrThrow(initialAmount),\n }),\n ...(isDefined(maxAmount) && {\n maxAmount: toHexOrThrow(maxAmount),\n }),\n ...(isDefined(startTime) && {\n startTime: Number(startTime),\n }),\n ...(justification ? { justification } : {}),\n };\n\n return {\n type: 'erc20-token-stream',\n data: {\n tokenAddress: toHexOrThrow(tokenAddress),\n amountPerSecond: toHexOrThrow(amountPerSecond),\n ...optionalFields,\n },\n isAdjustmentAllowed,\n };\n}\n\n/**\n * Formats a native token periodic permission for submission to the wallet.\n *\n * @param params - The parameters for formatting the native token periodic permission.\n * @param params.permission - The native token periodic permission parameter to format.\n * @param params.isAdjustmentAllowed - Whether the permission is allowed to be adjusted.\n * @returns The formatted NativeTokenPeriodicPermission object.\n */\nfunction formatNativeTokenPeriodicPermission({\n permission,\n isAdjustmentAllowed,\n}: {\n permission: NativeTokenPeriodicPermissionParameter;\n isAdjustmentAllowed: boolean;\n}): NativeTokenPeriodicPermission {\n const {\n data: { periodAmount, periodDuration, startTime, justification },\n } = permission;\n\n const optionalFields = {\n ...(isDefined(startTime) && {\n startTime: Number(startTime),\n }),\n ...(justification ? { justification } : {}),\n };\n\n return {\n type: 'native-token-periodic',\n data: {\n periodAmount: toHexOrThrow(periodAmount),\n periodDuration: Number(periodDuration),\n ...optionalFields,\n },\n isAdjustmentAllowed,\n };\n}\n\n/**\n * Formats an ERC20 token periodic permission for submission to the wallet.\n *\n * @param params - The parameters for formatting the ERC20 token periodic permission.\n * @param params.permission - The ERC20 token periodic permission parameter to format.\n * @param params.isAdjustmentAllowed - Whether the permission is allowed to be adjusted.\n * @returns The formatted Erc20TokenPeriodicPermission object.\n */\nfunction formatErc20TokenPeriodicPermission({\n permission,\n isAdjustmentAllowed,\n}: {\n permission: Erc20TokenPeriodicPermissionParameter;\n isAdjustmentAllowed: boolean;\n}): Erc20TokenPeriodicPermission {\n const {\n data: {\n tokenAddress,\n periodAmount,\n periodDuration,\n startTime,\n justification,\n },\n } = permission;\n\n const optionalFields = {\n ...(isDefined(startTime) && {\n startTime: Number(startTime),\n }),\n ...(justification ? { justification } : {}),\n };\n\n return {\n type: 'erc20-token-periodic',\n data: {\n tokenAddress: toHexOrThrow(tokenAddress),\n periodAmount: toHexOrThrow(periodAmount),\n periodDuration: Number(periodDuration),\n ...optionalFields,\n },\n isAdjustmentAllowed,\n };\n}\n","import { type Hex, toHex } from 'viem';\n\nimport { getDelegationHashOffchain } from '../delegation';\nimport type { Delegation } from '../types';\n\ntype ErrorResponse = {\n error: string;\n data?: any;\n};\n\nexport type APIStoreDelegationResponse = {\n delegationHash: Hex;\n};\n\n/**\n * Represents the allowed filters when querying the data store for delegations.\n */\nexport enum DelegationStoreFilter {\n Given = 'GIVEN',\n Received = 'RECEIVED',\n All = 'ALL',\n}\n\n/**\n * Public Delegation Storage Service environments. To be used in the\n * DeleGationStorageService config.\n */\nexport const DelegationStorageEnvironment: {\n [K in 'dev' | 'prod']: Environment;\n} = {\n dev: { apiUrl: 'https://passkeys.dev-api.cx.metamask.io' },\n prod: { apiUrl: 'https://passkeys.api.cx.metamask.io' },\n};\n\nexport type Environment = {\n apiUrl: string;\n};\n\nexport type DelegationStorageConfig = {\n apiKey: string;\n apiKeyId: string;\n environment: Environment;\n fetcher?: typeof fetch;\n};\n\nexport class DelegationStorageClient {\n #apiVersionPrefix = 'api/v0';\n\n #config: DelegationStorageConfig;\n\n #fetcher: typeof fetch;\n\n #apiUrl: string;\n\n constructor(config: DelegationStorageConfig) {\n const { apiUrl } = config.environment;\n\n if (apiUrl.endsWith(this.#apiVersionPrefix)) {\n this.#apiUrl = apiUrl;\n } else {\n const separator = apiUrl.endsWith('/') ? '' : '/';\n this.#apiUrl = `${apiUrl}${separator}${this.#apiVersionPrefix}`;\n }\n this.#fetcher = this.#initializeFetcher(config);\n this.#config = config;\n }\n\n /**\n * Initializes the fetch function for HTTP requests.\n *\n * - Uses `config.fetcher` if provided.\n * - Falls back to global `fetch` if available.\n * - Throws an error if no fetch function is available.\n *\n * @param config - Configuration object that may include a custom fetch function.\n * @returns The fetch function to be used for HTTP requests.\n * @throws Error if no fetch function is available in the environment.\n */\n #initializeFetcher(config: DelegationStorageConfig): typeof fetch {\n if (config.fetcher) {\n return config.fetcher;\n } else if (typeof globalThis?.fetch === 'function') {\n return globalThis.fetch.bind(globalThis);\n }\n throw new Error(\n 'Fetch API is not available in this environment. Please provide a fetch function in the config.',\n );\n }\n\n /**\n * Fetches the delegation chain from the Delegation Storage Service, ending with\n * the specified leaf delegation.\n *\n * @param leafDelegationOrDelegationHash - The leaf delegation, or the hash\n * of the leaf delegation.\n * @returns A promise that resolves to the delegation chain - empty array if the delegation\n * is not found.\n */\n async getDelegationChain(\n leafDelegationOrDelegationHash: Hex | Delegation,\n ): Promise<Delegation[]> {\n const leafDelegationHash =\n typeof leafDelegationOrDelegationHash === 'string'\n ? leafDelegationOrDelegationHash\n : getDelegationHashOffchain(leafDelegationOrDelegationHash);\n\n const response = await this.#fetcher(\n `${this.#apiUrl}/delegation/chain/${leafDelegationHash}`,\n {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${this.#config.apiKey}`,\n 'x-api-key-id': this.#config.apiKeyId,\n },\n },\n );\n\n const responseData: Delegation[] | ErrorResponse = await response.json();\n\n if ('error' in responseData) {\n throw new Error(\n `Failed to fetch delegation chain: ${responseData.error}`,\n );\n }\n\n return responseData;\n }\n\n /**\n * Fetches the delegations from the Delegation Storage Service, either `Received`\n * by, or `Given` by, (or both: `All`) the specified deleGatorAddress. Defaults\n * to `Received`.\n *\n * @param deleGatorAddress - The deleGatorAddress to retrieve the delegations for.\n * @param filterMode - The DelegationStoreFilter mode - defaults to Received.\n * @returns A promise that resolves to the list of delegations received by the deleGatorAddress,\n * empty array if the delegations are not found.\n */\n async fetchDelegations(\n deleGatorAddress: Hex,\n filterMode = DelegationStoreFilter.Received,\n ): Promise<Delegation[]> {\n const response = await this.#fetcher(\n `${this.#apiUrl}/delegation/accounts/${deleGatorAddress}?filter=${filterMode}`,\n {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${this.#config.apiKey}`,\n 'x-api-key-id': this.#config.apiKeyId,\n },\n },\n );\n\n const responseData: Delegation[] | ErrorResponse = await response.json();\n\n if ('error' in responseData) {\n throw new Error(`Failed to fetch delegations: ${responseData.error}`);\n }\n\n return responseData;\n }\n\n /**\n * Stores the specified delegation in the Delegation Storage Service.\n *\n * @param delegation - The delegation to store.\n * @returns A promise that resolves to the delegation hash indicating successful storage.\n */\n async storeDelegation(delegation: Delegation): Promise<Hex> {\n if (!delegation.signature || delegation.signature === '0x') {\n throw new Error('Delegation must be signed to be stored');\n }\n\n const delegationHash = getDelegationHashOffchain(delegation);\n\n const body = JSON.stringify(\n {\n ...delegation,\n metadata: [],\n },\n (_, value: any) =>\n typeof value === 'bigint' || typeof value === 'number'\n ? toHex(value)\n : value,\n 2,\n );\n\n const response = await this.#fetcher(`${this.#apiUrl}/delegation/store`, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${this.#config.apiKey}`,\n 'x-api-key-id': this.#config.apiKeyId,\n 'Content-Type': 'application/json',\n },\n body,\n });\n\n const responseData: APIStoreDelegationResponse | ErrorResponse =\n await response.json();\n\n if ('error' in responseData) {\n throw new Error(responseData.error);\n }\n\n if (responseData.delegationHash !== delegationHash) {\n throw Error(\n 'Failed to store the Delegation, the hash returned from the MM delegation storage API does not match the hash of the delegation',\n );\n }\n\n return responseData.delegationHash;\n }\n}\n","import type { Client, WalletClient } from 'viem';\nimport type { BundlerClient } from 'viem/account-abstraction';\n\nimport type {\n SendTransactionWithDelegationParameters,\n SendUserOperationWithDelegationParameters,\n} from './erc7710RedeemDelegationAction';\nimport {\n sendTransactionWithDelegationAction,\n sendUserOperationWithDelegationAction,\n} from './erc7710RedeemDelegationAction';\nimport { erc7715RequestExecutionPermissionsAction } from './erc7715RequestExecutionPermissionsAction';\nimport type {\n MetaMaskExtensionClient,\n RequestExecutionPermissionsParameters,\n} from './erc7715RequestExecutionPermissionsAction';\n\nexport {\n erc7715RequestExecutionPermissionsAction as requestExecutionPermissions,\n type MetaMaskExtensionClient,\n type MetaMaskExtensionSchema,\n type RequestExecutionPermissionsParameters,\n type RequestExecutionPermissionsReturnType,\n} from './erc7715RequestExecutionPermissionsAction';\n\nexport {\n DelegationStorageClient,\n type DelegationStoreFilter,\n type Environment,\n type DelegationStorageConfig,\n} from './delegationStorage';\n\nexport const erc7715ProviderActions = () => (client: Client) => ({\n requestExecutionPermissions: async (\n parameters: RequestExecutionPermissionsParameters,\n ) => {\n return erc7715RequestExecutionPermissionsAction(\n client as MetaMaskExtensionClient,\n parameters,\n );\n },\n});\n\nexport const erc7710WalletActions = () => (client: WalletClient) => ({\n sendTransactionWithDelegation: async (\n args: SendTransactionWithDelegationParameters,\n ) => sendTransactionWithDelegationAction(client, args),\n});\n\nexport const erc7710BundlerActions = () => (client: Client) => ({\n sendUserOperationWithDelegation: async (\n args: SendUserOperationWithDelegationParameters,\n ) => sendUserOperationWithDelegationAction(client as BundlerClient, args),\n});\n"]}