@metamask/delegation-toolkit
Version:
The Delegation Toolkit built on top of Viem - a library for interacting with DeleGator Smart Accounts
1 lines • 11.9 kB
Source Map (JSON)
{"version":3,"sources":["/home/runner/work/delegation-toolkit/delegation-toolkit/packages/delegation-toolkit/dist/chunk-2YEKEDAF.cjs","../src/userOp.ts"],"names":[],"mappings":"AAAA;ACAA,4BAAmE;AAEnE,8DAAsC;AACtC,yCAA8B;AAmPvB,IAAM,4BAAA,EAAyC;AAAA,EACpD,mBAAA,EAAqB;AAAA,IACnB,EAAE,IAAA,EAAM,QAAA,EAAU,IAAA,EAAM,UAAU,CAAA;AAAA,IAClC,EAAE,IAAA,EAAM,OAAA,EAAS,IAAA,EAAM,UAAU,CAAA;AAAA,IACjC,EAAE,IAAA,EAAM,UAAA,EAAY,IAAA,EAAM,QAAQ,CAAA;AAAA,IAClC,EAAE,IAAA,EAAM,UAAA,EAAY,IAAA,EAAM,QAAQ,CAAA;AAAA,IAClC,EAAE,IAAA,EAAM,kBAAA,EAAoB,IAAA,EAAM,UAAU,CAAA;AAAA,IAC5C,EAAE,IAAA,EAAM,oBAAA,EAAsB,IAAA,EAAM,UAAU,CAAA;AAAA,IAC9C,EAAE,IAAA,EAAM,SAAA,EAAW,IAAA,EAAM,UAAU,CAAA;AAAA,IACnC,EAAE,IAAA,EAAM,kBAAA,EAAoB,IAAA,EAAM,QAAQ,CAAA;AAAA,IAC1C,EAAE,IAAA,EAAM,YAAA,EAAc,IAAA,EAAM,UAAU;AAAA,EACxC;AACF,CAAA;AAgBO,IAAM,kCAAA,EAAoC,CAAC;AAAA,EAChD,aAAA;AAAA,EACA,UAAA;AAAA,EACA,OAAA;AAAA,EACA,IAAA;AAAA,EACA,OAAA;AAAA,EACA,QAAA,EAAU;AACZ,CAAA,EAAA,GAOM;AACJ,EAAA,MAAM,aAAA,EAAe,uDAAA;AAAsB,IACzC,GAAG,aAAA;AAAA,IACH,SAAA,EAAW;AAAA,EACb,CAAC,CAAA;AAED,EAAA,OAAO;AAAA,IACL,MAAA,EAAQ;AAAA,MACN,OAAA;AAAA,MACA,IAAA;AAAA,MACA,OAAA;AAAA,MACA,iBAAA,EAAmB;AAAA,IACrB,CAAA;AAAA,IACA,KAAA,EAAO,2BAAA;AAAA,IACP,WAAA,EAAa,qBAAA;AAAA,IACb,OAAA,EAAS,EAAE,GAAG,YAAA,EAAc,UAAA,EAAY,UAAA,CAAW,QAAQ;AAAA,EAC7D,CAAA;AACF,CAAA;AAeO,IAAM,kBAAA,EAAoB,MAAA,CAAO;AAAA,EACtC,UAAA;AAAA,EACA,aAAA;AAAA,EACA,UAAA;AAAA,EACA,OAAA;AAAA,EACA,IAAA;AAAA,EACA,OAAA;AAAA,EACA,QAAA,EAAU;AACZ,CAAA,EAAA,GAQM;AACJ,EAAA,MAAM,UAAA,EAAY,iCAAA,CAAkC;AAAA,IAClD,aAAA;AAAA,IACA,UAAA;AAAA,IACA,OAAA;AAAA,IACA,IAAA;AAAA,IACA,OAAA;AAAA,IACA;AAAA,EACF,CAAC,CAAA;AAED,EAAA,OAAO,qCAAA;AAAc,IACnB,UAAA;AAAA,IACA,GAAG;AAAA,EACL,CAAC,CAAA;AACH,CAAA;AD/RA;AACA;AACE;AACA;AACA;AACF,gMAAC","file":"/home/runner/work/delegation-toolkit/delegation-toolkit/packages/delegation-toolkit/dist/chunk-2YEKEDAF.cjs","sourcesContent":[null,"import { concat, encodeAbiParameters, keccak256, pad, toHex } from 'viem';\nimport type { Address, Hex, TypedData } from 'viem';\nimport { toPackedUserOperation } from 'viem/account-abstraction';\nimport { signTypedData } from 'viem/accounts';\n\nimport type { OptionalUserOpProps, PackedUserOperationStruct } from './types';\n\n// v7 off-chain user operation, hexlified incoming data from rpc call\nexport type UserOperationV07Hexlify = {\n sender: Hex;\n nonce: Hex;\n factory?: Hex;\n factoryData?: Hex;\n callData: Hex;\n callGasLimit: Hex;\n\n verificationGasLimit: Hex;\n preVerificationGas: Hex;\n maxFeePerGas: Hex;\n maxPriorityFeePerGas: Hex;\n\n paymaster?: Hex;\n paymasterVerificationGasLimit?: Hex;\n paymasterPostOpGasLimit?: Hex;\n paymasterData?: Hex;\n\n signature: Hex;\n};\n\n// v7 off-chain user operation with BigInt fields\nexport type UserOperationV07 = {\n sender: Hex;\n nonce: bigint;\n factory?: Hex;\n factoryData?: Hex;\n callData: Hex;\n\n callGasLimit: bigint;\n verificationGasLimit: bigint;\n preVerificationGas: bigint;\n maxFeePerGas: bigint;\n maxPriorityFeePerGas: bigint;\n\n paymaster?: Hex;\n paymasterVerificationGasLimit?: bigint;\n paymasterPostOpGasLimit?: bigint;\n paymasterData?: Hex;\n\n signature: Hex;\n};\n\n/**\n * Creates a raw user operation data structure.\n * @param sender - The smart account taking some action.\n * @param nonce - A nonce, ideally fetched from the Entry Point.\n * @param callData - Calldata to invoke on some contract.\n * @param signature - The signature for the user operation.\n * @param options - Optional properties for the user operation.\n * @returns The created raw user operation data structure.\n */\nexport const createRawUserOp = (\n sender: Hex,\n nonce: bigint,\n callData: Hex,\n signature: Hex = '0x',\n options?: OptionalUserOpProps,\n): UserOperationV07 => ({\n sender,\n nonce,\n callData,\n factory: options?.factory,\n factoryData: options?.factoryData,\n callGasLimit: options?.callGasLimit ?? 0n,\n verificationGasLimit: options?.verificationGasLimit ?? 0n,\n preVerificationGas: options?.preVerificationGas ?? 0n,\n maxFeePerGas: options?.maxFeePerGas ?? 0n,\n maxPriorityFeePerGas: options?.maxPriorityFeePerGas ?? 0n,\n paymaster: options?.paymaster,\n paymasterVerificationGasLimit: options?.paymasterVerificationGasLimit,\n paymasterPostOpGasLimit: options?.paymasterPostOpGasLimit,\n paymasterData: options?.paymasterData,\n signature,\n});\n\n// //////////////////////////////////////////////////////////////////////////////////////\n\n// TODO: These userOp functions are duplicated in ./apps/ew-client/src/utils/userOpBuilder.ts. We should move them to a shared location along with test(./apps/ew-client/test/UserOpBuilder.test.ts) to avoid duplication\n/**\n * Generates a salt value for address derivation.\n * @param salt - Optional salt value.\n * @returns The chosen salt value.\n */\nexport const getSalt = (salt?: Hex): Hex => {\n return salt ?? '0x0';\n};\n\nexport const getPaymasterAndData = (userOp: UserOperationV07): Hex => {\n let paymasterAndData: Hex;\n if (userOp.paymaster) {\n paymasterAndData = concat([\n userOp.paymaster,\n pad(toHex(userOp.paymasterVerificationGasLimit ?? 0n), {\n size: 16,\n }),\n pad(toHex(userOp.paymasterPostOpGasLimit ?? 0n), {\n size: 16,\n }),\n userOp.paymasterData ?? '0x',\n ]);\n } else {\n paymasterAndData = '0x';\n }\n\n return paymasterAndData;\n};\n\nexport const getInitCode = (userOp: UserOperationV07): Hex => {\n return userOp.factory\n ? concat([userOp.factory, userOp.factoryData ?? ('0x' as Hex)])\n : '0x';\n};\n\nexport const getAccountGasLimits = (userOp: UserOperationV07): Hex => {\n return concat([\n pad(toHex(userOp.verificationGasLimit), {\n size: 16,\n }),\n pad(toHex(userOp.callGasLimit), { size: 16 }),\n ]);\n};\n\nexport const getGasFees = (userOp: UserOperationV07): Hex => {\n return concat([\n pad(toHex(userOp.maxPriorityFeePerGas), {\n size: 16,\n }),\n pad(toHex(userOp.maxFeePerGas), { size: 16 }),\n ]);\n};\n\n/**\n * Packs a user operation into a `PackedUserOperationStruct` object.\n *\n * @param userOp - The user operation to pack.\n * @returns The packed user operation.\n */\nexport const packUserOp = (\n userOp: UserOperationV07,\n): PackedUserOperationStruct => {\n const packedOp = {\n sender: userOp.sender,\n nonce: BigInt(userOp.nonce),\n initCode: getInitCode(userOp),\n callData: userOp.callData,\n accountGasLimits: getAccountGasLimits(userOp),\n preVerificationGas: BigInt(userOp.preVerificationGas),\n gasFees: getGasFees(userOp),\n paymasterAndData: getPaymasterAndData(userOp),\n signature: userOp.signature,\n };\n\n return packedOp;\n};\n\n/**\n * Calculates the user operation hash for a given packed user operation.\n * @param packedOp - The packed user operation.\n * @param entryPoint - The entry point address.\n * @param chainId - The chain ID.\n * @returns The user operation hash.\n */\nexport const createUserOpHashV07 = (\n packedOp: PackedUserOperationStruct,\n entryPoint: Hex,\n chainId: bigint,\n) => {\n const hash = keccak256(\n encodeAbiParameters(\n [\n {\n name: 'sender',\n type: 'address',\n },\n {\n name: 'nonce',\n type: 'uint256',\n },\n {\n name: 'initCodeHash',\n type: 'bytes32',\n },\n {\n name: 'callDataHash',\n type: 'bytes32',\n },\n {\n name: 'accountGasLimits',\n type: 'bytes32',\n },\n {\n name: 'preVerificationGas',\n type: 'uint256',\n },\n {\n name: 'gasFees',\n type: 'bytes32',\n },\n {\n name: 'paymasterAndDataHash',\n type: 'bytes32',\n },\n ],\n [\n packedOp.sender,\n packedOp.nonce,\n keccak256(packedOp.initCode),\n keccak256(packedOp.callData),\n packedOp.accountGasLimits,\n packedOp.preVerificationGas,\n packedOp.gasFees,\n keccak256(packedOp.paymasterAndData),\n ],\n ),\n );\n\n return keccak256(\n encodeAbiParameters(\n [\n {\n name: 'userOpHash',\n type: 'bytes32',\n },\n {\n name: 'entryPointAddress',\n type: 'address',\n },\n {\n name: 'chainId',\n type: 'uint256',\n },\n ],\n [hash, entryPoint, chainId],\n ),\n );\n};\n\nexport const SIGNABLE_USER_OP_TYPED_DATA: TypedData = {\n PackedUserOperation: [\n { name: 'sender', type: 'address' },\n { name: 'nonce', type: 'uint256' },\n { name: 'initCode', type: 'bytes' },\n { name: 'callData', type: 'bytes' },\n { name: 'accountGasLimits', type: 'bytes32' },\n { name: 'preVerificationGas', type: 'uint256' },\n { name: 'gasFees', type: 'bytes32' },\n { name: 'paymasterAndData', type: 'bytes' },\n { name: 'entryPoint', type: 'address' },\n ],\n} as const;\n\n/**\n * Prepares typed data for user operation signing.\n * This is an internal helper function that's not exposed in the public API.\n *\n * @param params - The parameters for preparing the typed data.\n * @param params.userOperation - The user operation to prepare for signing.\n * @param params.entryPoint - The entry point contract address.\n * @param params.entryPoint.address - The address of the entry point contract.\n * @param params.chainId - The chain ID that the entry point is deployed on.\n * @param params.name - The name of the domain of the implementation contract.\n * @param params.version - The version of the domain of the implementation contract.\n * @param params.address - The address of the smart account.\n * @returns The prepared typed data for signing.\n */\nexport const prepareSignUserOperationTypedData = ({\n userOperation,\n entryPoint,\n chainId,\n name,\n address,\n version = '1',\n}: {\n userOperation: Omit<UserOperationV07, 'signature'>;\n entryPoint: { address: Address };\n chainId: number;\n name: 'HybridDeleGator' | 'MultiSigDeleGator';\n address: Address;\n version?: string;\n}) => {\n const packedUserOp = toPackedUserOperation({\n ...userOperation,\n signature: '0x',\n });\n\n return {\n domain: {\n chainId,\n name,\n version,\n verifyingContract: address,\n },\n types: SIGNABLE_USER_OP_TYPED_DATA,\n primaryType: 'PackedUserOperation' as const,\n message: { ...packedUserOp, entryPoint: entryPoint.address },\n };\n};\n\n/**\n * Signs a user operation using a private key.\n * @param params - The parameters for signing the user operation.\n * @param params.privateKey - The private key to use for signing.\n * @param params.userOperation - The user operation to sign.\n * @param params.entryPoint - The entry point contract address.\n * @param params.chainId - The chain ID that the entry point is deployed on.\n * @param params.name - The name of the domain of the implementation contract.\n * @param params.version - The version of the domain of the implementation contract.\n * @param params.address - The address of the smart account.\n * @param params.entryPoint.address - The address of the entry point contract.\n * @returns The signature of the user operation.\n */\nexport const signUserOperation = async ({\n privateKey,\n userOperation,\n entryPoint,\n chainId,\n name,\n address,\n version = '1',\n}: {\n privateKey: Hex;\n userOperation: Omit<UserOperationV07, 'signature'>;\n entryPoint: { address: Address };\n chainId: number;\n address: Address;\n name: 'HybridDeleGator' | 'MultiSigDeleGator';\n version?: string;\n}) => {\n const typedData = prepareSignUserOperationTypedData({\n userOperation,\n entryPoint,\n chainId,\n name,\n address,\n version,\n });\n\n return signTypedData({\n privateKey,\n ...typedData,\n });\n};\n"]}