UNPKG

@metamask/delegation-toolkit

Version:

The Delegation Toolkit built on top of Viem - a library for interacting with DeleGator Smart Accounts

1 lines 19.7 kB
{"version":3,"sources":["/home/runner/work/delegation-toolkit/delegation-toolkit/packages/delegation-toolkit/dist/chunk-TJMYQ3DC.cjs","../src/actions/index.ts","../src/actions/getCaveatAvailableAmount.ts","../src/actions/isValid7702Implementation.ts"],"names":[],"mappings":"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","file":"/home/runner/work/delegation-toolkit/delegation-toolkit/packages/delegation-toolkit/dist/chunk-TJMYQ3DC.cjs","sourcesContent":[null,"/* eslint-disable */\n// experimental actions will be moved here once they have stabilized\n\n// signDelegation action will be added here\n\nexport {\n // Individual action functions\n getErc20PeriodTransferEnforcerAvailableAmount,\n getErc20StreamingEnforcerAvailableAmount,\n getMultiTokenPeriodEnforcerAvailableAmount,\n getNativeTokenPeriodTransferEnforcerAvailableAmount,\n getNativeTokenStreamingEnforcerAvailableAmount,\n // Action builder\n caveatEnforcerActions,\n // Parameter types\n type CaveatEnforcerParams,\n // Result types\n type PeriodTransferResult,\n type StreamingResult,\n} from './getCaveatAvailableAmount';\n\nexport { isValid7702Implementation } from './isValid7702Implementation';\n","import type { Address, Hex, PublicClient } from 'viem';\n\nimport { getDelegationHashOffchain } from '../delegation';\nimport * as ERC20PeriodTransferEnforcer from '../DelegationFramework/ERC20PeriodTransferEnforcer';\nimport * as ERC20StreamingEnforcer from '../DelegationFramework/ERC20StreamingEnforcer';\nimport * as MultiTokenPeriodEnforcer from '../DelegationFramework/MultiTokenPeriodEnforcer';\nimport * as NativeTokenPeriodTransferEnforcer from '../DelegationFramework/NativeTokenPeriodTransferEnforcer';\nimport * as NativeTokenStreamingEnforcer from '../DelegationFramework/NativeTokenStreamingEnforcer';\nimport type { DeleGatorEnvironment, Delegation } from '../types';\n\n/**\n * Parameters for all caveat enforcer actions.\n */\nexport type CaveatEnforcerParams = {\n delegation: Delegation;\n};\n\n/**\n * Return type for period-based transfer enforcers\n */\nexport type PeriodTransferResult = {\n availableAmount: bigint;\n isNewPeriod: boolean;\n currentPeriod: bigint;\n};\n\n/**\n * Return type for streaming enforcers\n */\nexport type StreamingResult = {\n availableAmount: bigint;\n};\n\n/**\n * Finds a caveat that matches the specified enforcer address.\n * @param config - The configuration object.\n * @param config.delegation - The delegation to search.\n * @param config.enforcerAddress - The enforcer address to match.\n * @param config.enforcerName - The name of the enforcer.\n * @returns The matching caveat.\n * @throws Error if no matching caveat is found.\n * @throws Error if multiple matching caveats are found.\n */\nfunction findMatchingCaveat({\n delegation,\n enforcerAddress,\n enforcerName,\n}: {\n delegation: Delegation;\n enforcerAddress: Address;\n enforcerName: keyof DeleGatorEnvironment['caveatEnforcers'];\n}): { terms: Hex; args: Hex } {\n const matchingCaveats = delegation.caveats.filter(\n (caveat) => caveat.enforcer.toLowerCase() === enforcerAddress.toLowerCase(),\n );\n\n if (matchingCaveats.length === 0) {\n throw new Error(`No caveat found with enforcer matching ${enforcerName}`);\n }\n\n if (matchingCaveats.length > 1) {\n throw new Error(\n `Multiple caveats found with enforcer matching ${enforcerName}`,\n );\n }\n\n const [{ terms, args }] = matchingCaveats as unknown as [\n { terms: Hex; args: Hex },\n ];\n\n return {\n terms,\n args,\n };\n}\n\n/**\n * Gets the delegation manager address from environment.\n *\n * @param environment - The delegator environment.\n * @returns The delegation manager address.\n */\nfunction getDelegationManager(environment: DeleGatorEnvironment): Address {\n if (!environment.DelegationManager) {\n throw new Error('Delegation manager address not found');\n }\n\n return environment.DelegationManager;\n}\n\n/**\n * Gets the enforcer address from environment.\n *\n * @param config - The configuration object.\n * @param config.enforcerName - The name of the enforcer.\n * @param config.environment - The delegator environment.\n * @returns The enforcer address.\n */\nfunction getEnforcerAddress({\n enforcerName,\n environment,\n}: {\n enforcerName: keyof DeleGatorEnvironment['caveatEnforcers'];\n environment: DeleGatorEnvironment;\n}): Address {\n const enforcerAddress = environment.caveatEnforcers[enforcerName];\n if (!enforcerAddress) {\n throw new Error(`${enforcerName} not found in environment`);\n }\n\n return enforcerAddress;\n}\n\n/**\n * Get available amount for ERC20 period transfer enforcer.\n *\n * @param client - The viem public client.\n * @param environment - The delegator environment.\n * @param params - The parameters for the ERC20 period transfer enforcer.\n * @returns Promise resolving to the period transfer result.\n */\nexport async function getErc20PeriodTransferEnforcerAvailableAmount(\n client: PublicClient,\n environment: DeleGatorEnvironment,\n params: CaveatEnforcerParams,\n): Promise<PeriodTransferResult> {\n const enforcerName = 'ERC20PeriodTransferEnforcer';\n\n const delegationManager = getDelegationManager(environment);\n const enforcerAddress = getEnforcerAddress({\n enforcerName,\n environment,\n });\n\n const delegationHash = getDelegationHashOffchain(params.delegation);\n const { terms } = findMatchingCaveat({\n delegation: params.delegation,\n enforcerAddress,\n enforcerName,\n });\n\n return ERC20PeriodTransferEnforcer.read.getAvailableAmount({\n client,\n contractAddress: enforcerAddress,\n delegationHash,\n delegationManager,\n terms,\n });\n}\n\n/**\n * Get available amount for ERC20 streaming enforcer.\n *\n * @param client - The viem public client.\n * @param environment - The delegator environment.\n * @param params - The parameters for the ERC20 streaming enforcer.\n * @returns Promise resolving to the streaming result.\n */\nexport async function getErc20StreamingEnforcerAvailableAmount(\n client: PublicClient,\n environment: DeleGatorEnvironment,\n params: CaveatEnforcerParams,\n): Promise<StreamingResult> {\n const enforcerName = 'ERC20StreamingEnforcer';\n const delegationManager = getDelegationManager(environment);\n const enforcerAddress = getEnforcerAddress({\n enforcerName,\n environment,\n });\n\n const delegationHash = getDelegationHashOffchain(params.delegation);\n const { terms } = findMatchingCaveat({\n delegation: params.delegation,\n enforcerAddress,\n enforcerName,\n });\n\n return ERC20StreamingEnforcer.read.getAvailableAmount({\n client,\n contractAddress: enforcerAddress,\n delegationManager,\n delegationHash,\n terms,\n });\n}\n\n/**\n * Get available amount for multi-token period enforcer.\n *\n * @param client - The viem public client.\n * @param environment - The delegator environment.\n * @param params - The parameters for the multi-token period enforcer.\n * @returns Promise resolving to the period transfer result.\n */\nexport async function getMultiTokenPeriodEnforcerAvailableAmount(\n client: PublicClient,\n environment: DeleGatorEnvironment,\n params: CaveatEnforcerParams,\n): Promise<PeriodTransferResult> {\n const enforcerName = 'MultiTokenPeriodEnforcer';\n const delegationManager = getDelegationManager(environment);\n const enforcerAddress = getEnforcerAddress({\n enforcerName,\n environment,\n });\n\n const delegationHash = getDelegationHashOffchain(params.delegation);\n const { terms, args } = findMatchingCaveat({\n delegation: params.delegation,\n enforcerAddress,\n enforcerName,\n });\n\n return MultiTokenPeriodEnforcer.read.getAvailableAmount({\n client,\n contractAddress: enforcerAddress,\n delegationHash,\n delegationManager,\n terms,\n args,\n });\n}\n\n/**\n * Get available amount for native token period transfer enforcer.\n *\n * @param client - The viem public client.\n * @param environment - The delegator environment.\n * @param params - The parameters for the native token period transfer enforcer.\n * @returns Promise resolving to the period transfer result.\n */\nexport async function getNativeTokenPeriodTransferEnforcerAvailableAmount(\n client: PublicClient,\n environment: DeleGatorEnvironment,\n params: CaveatEnforcerParams,\n): Promise<PeriodTransferResult> {\n const enforcerName = 'NativeTokenPeriodTransferEnforcer';\n const delegationManager = getDelegationManager(environment);\n const enforcerAddress = getEnforcerAddress({\n enforcerName,\n environment,\n });\n\n const delegationHash = getDelegationHashOffchain(params.delegation);\n const { terms } = findMatchingCaveat({\n delegation: params.delegation,\n enforcerAddress,\n enforcerName,\n });\n\n return NativeTokenPeriodTransferEnforcer.read.getAvailableAmount({\n client,\n contractAddress: enforcerAddress,\n delegationHash,\n delegationManager,\n terms,\n });\n}\n\n/**\n * Get available amount for native token streaming enforcer.\n *\n * @param client - The viem public client.\n * @param environment - The delegator environment.\n * @param params - The parameters for the native token streaming enforcer.\n * @returns Promise resolving to the streaming result.\n */\nexport async function getNativeTokenStreamingEnforcerAvailableAmount(\n client: PublicClient,\n environment: DeleGatorEnvironment,\n params: CaveatEnforcerParams,\n): Promise<StreamingResult> {\n const enforcerName = 'NativeTokenStreamingEnforcer';\n const delegationManager = getDelegationManager(environment);\n const enforcerAddress = getEnforcerAddress({\n enforcerName,\n environment,\n });\n\n const delegationHash = getDelegationHashOffchain(params.delegation);\n const { terms } = findMatchingCaveat({\n delegation: params.delegation,\n enforcerAddress,\n enforcerName,\n });\n\n return NativeTokenStreamingEnforcer.read.getAvailableAmount({\n client,\n contractAddress: enforcerAddress,\n delegationManager,\n delegationHash,\n terms,\n });\n}\n\n/**\n * Caveat enforcer actions for extending viem clients.\n *\n * @param params - The parameters object.\n * @param params.environment - The delegator environment.\n * @returns A function that takes a client and returns the client extension with caveat enforcer actions.\n */\nexport const caveatEnforcerActions =\n ({ environment }: { environment: DeleGatorEnvironment }) =>\n (client: PublicClient) => ({\n /**\n * Get available amount for ERC20 period transfer enforcer.\n *\n * @param params - The parameters for the ERC20 period transfer enforcer.\n * @returns Promise resolving to the period transfer result.\n */\n getErc20PeriodTransferEnforcerAvailableAmount: async (\n params: CaveatEnforcerParams,\n ): Promise<PeriodTransferResult> => {\n return getErc20PeriodTransferEnforcerAvailableAmount(\n client,\n environment,\n params,\n );\n },\n\n /**\n * Get available amount for ERC20 streaming enforcer.\n *\n * @param params - The parameters for the ERC20 streaming enforcer.\n * @returns Promise resolving to the streaming result.\n */\n getErc20StreamingEnforcerAvailableAmount: async (\n params: CaveatEnforcerParams,\n ): Promise<StreamingResult> => {\n return getErc20StreamingEnforcerAvailableAmount(\n client,\n environment,\n params,\n );\n },\n\n /**\n * Get available amount for multi-token period enforcer.\n *\n * @param params - The parameters for the multi-token period enforcer.\n * @returns Promise resolving to the period transfer result.\n */\n getMultiTokenPeriodEnforcerAvailableAmount: async (\n params: CaveatEnforcerParams,\n ): Promise<PeriodTransferResult> => {\n return getMultiTokenPeriodEnforcerAvailableAmount(\n client,\n environment,\n params,\n );\n },\n\n /**\n * Get available amount for native token period transfer enforcer.\n *\n * @param params - The parameters for the native token period transfer enforcer.\n * @returns Promise resolving to the period transfer result.\n */\n getNativeTokenPeriodTransferEnforcerAvailableAmount: async (\n params: CaveatEnforcerParams,\n ): Promise<PeriodTransferResult> => {\n return getNativeTokenPeriodTransferEnforcerAvailableAmount(\n client,\n environment,\n params,\n );\n },\n\n /**\n * Get available amount for native token streaming enforcer.\n *\n * @param params - The parameters for the native token streaming enforcer.\n * @returns Promise resolving to the streaming result.\n */\n getNativeTokenStreamingEnforcerAvailableAmount: async (\n params: CaveatEnforcerParams,\n ): Promise<StreamingResult> => {\n return getNativeTokenStreamingEnforcerAvailableAmount(\n client,\n environment,\n params,\n );\n },\n });\n","import type { Client, Address, Hex } from 'viem';\nimport { isAddressEqual } from 'viem';\nimport { getCode } from 'viem/actions';\n\nimport type { DeleGatorEnvironment } from '../types';\n\n// EIP-7702 delegation prefix (0xef0100)\nconst DELEGATION_PREFIX = '0xef0100' as const;\n\n/**\n * Parameters for checking if an account is delegated to the EIP-7702 implementation.\n */\nexport type IsValid7702ImplementationParameters = {\n /** The client to use for the query. */\n client: Client;\n /** The address to check for proper delegation. */\n accountAddress: Address;\n /** The DeleGator environment containing contract addresses. */\n environment: DeleGatorEnvironment;\n};\n\n/**\n * Extracts the delegated contract address from EIP-7702 delegation code.\n *\n * @param code - The code returned from getCode for a delegated account.\n * @returns The delegated contract address or null if not a valid delegation.\n */\nfunction extractDelegatedAddress(code: Hex | undefined): Address | null {\n if (code?.length !== 48) {\n // 0x (2 chars) + ef0100 (6 chars) + address (40 chars) = 48 chars\n return null;\n }\n\n if (!code.toLowerCase().startsWith(DELEGATION_PREFIX.toLowerCase())) {\n return null;\n }\n\n // Extract the 20-byte address after the delegation prefix\n const addressHex = code.slice(8); // Remove '0xef0100' prefix (8 chars)\n return `0x${addressHex}`;\n}\n\n/**\n * Checks if an account is properly delegated to the EIP-7702 implementation.\n *\n * This function validates EIP-7702 delegations by checking if the EOA has a 7702\n * contract assigned to it and comparing the delegated address against the 7702\n * implementation found in the environment.\n *\n * @param params - The parameters for checking the delegation.\n * @param params.client - The client to use for the query.\n * @param params.accountAddress - The address to check for proper delegation.\n * @param params.environment - The DeleGator environment containing contract addresses.\n * @returns A promise that resolves to true if the account is properly delegated to the 7702 implementation, false otherwise.\n * @example\n * ```typescript\n * const isValid = await isValid7702Implementation({\n * client: publicClient,\n * accountAddress: '0x...',\n * environment: delegatorEnvironment,\n * });\n *\n * if (isValid) {\n * console.log('Account is properly delegated to EIP-7702 implementation');\n * } else {\n * console.log('Account is not properly delegated');\n * }\n * ```\n */\nexport async function isValid7702Implementation({\n client,\n accountAddress,\n environment,\n}: IsValid7702ImplementationParameters): Promise<boolean> {\n try {\n // Get the code at the account address\n const code = await getCode(client, {\n address: accountAddress,\n });\n\n // Extract the delegated contract address from the EIP-7702 delegation code\n const delegatedAddress = extractDelegatedAddress(code);\n\n // If no valid delegation found, return false\n if (!delegatedAddress) {\n return false;\n }\n\n // Compare the delegated address with the 7702 implementation in the environment\n const expectedImplementation =\n environment.implementations.EIP7702StatelessDeleGatorImpl;\n if (!expectedImplementation) {\n return false;\n }\n\n return isAddressEqual(delegatedAddress, expectedImplementation);\n } catch (error) {\n // If the call fails (e.g., no code at address, network error),\n // then it's not properly delegated to our implementation\n return false;\n }\n}\n"]}