@metamask/delegation-toolkit
Version:
The Delegation Toolkit built on top of Viem - a library for interacting with DeleGator Smart Accounts
1 lines • 43.7 kB
Source Map (JSON)
{"version":3,"sources":["../../src/experimental/erc7710RedeemDelegationAction.ts","../../src/experimental/erc7715RequestExecutionPermissionsAction.ts","../../src/experimental/snapsAuthorization.ts","../../src/experimental/delegationStorage.ts","../../src/experimental/index.ts"],"sourcesContent":["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, type Address } from 'viem';\n\nimport type { SnapClient } from './snapsAuthorization.js';\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 * @param kernelSnapId - The ID of the kernel snap to invoke, defaults to 'npm:@metamask/permissions-kernel-snap'.\n * @returns A promise that resolves to the permission responses.\n * @description\n * This function formats the permissions requests and invokes the wallet snap to grant permissions.\n * It will throw an error if the permissions could not be granted.\n */\nexport async function erc7715RequestExecutionPermissionsAction(\n client: SnapClient,\n parameters: RequestExecutionPermissionsParameters,\n kernelSnapId = 'npm:@metamask/permissions-kernel-snap',\n): Promise<RequestExecutionPermissionsReturnType> {\n const formattedParameters = parameters.map(formatPermissionsRequest);\n\n const result = await client.request(\n {\n method: 'wallet_invokeSnap',\n params: {\n snapId: kernelSnapId,\n request: {\n method: 'wallet_requestExecutionPermissions',\n params: formattedParameters,\n },\n },\n },\n { retryCount: 0 },\n );\n\n if (result === null) {\n throw new Error('Failed to grant permissions');\n }\n\n return result as any as RequestExecutionPermissionsReturnType;\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 { Account, Chain, Client, RpcSchema, Transport } from 'viem';\n\n/**\n * Represents the authorization status of installed MetaMask Snaps.\n *\n * @property {string} version - The version of the installed Snap.\n * @property {string} id - The unique identifier of the Snap.\n * @property {boolean} enabled - Whether the Snap is currently enabled.\n * @property {boolean} blocked - Whether the Snap is currently blocked.\n */\nexport type SnapAuthorizations = Record<\n string,\n { version: string; id: string; enabled: boolean; blocked: boolean }\n>;\n\n/**\n * RPC schema for MetaMask Snap-related methods.\n *\n * Extends the base RPC schema with methods specific to interacting with Snaps:\n * - `wallet_invokeSnap`: Invokes a method on a specific Snap.\n * - `wallet_getSnaps`: Retrieves all installed Snaps and their authorization status.\n * - `wallet_requestSnaps`: Requests permission to use specific Snaps.\n */\nexport type SnapRpcSchema = RpcSchema &\n [\n {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n Method: 'wallet_invokeSnap';\n // eslint-disable-next-line @typescript-eslint/naming-convention\n Params: {\n snapId: string;\n request: {\n method: string;\n params: unknown[];\n };\n };\n // eslint-disable-next-line @typescript-eslint/naming-convention\n ReturnType: unknown;\n },\n {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n Method: 'wallet_getSnaps';\n // eslint-disable-next-line @typescript-eslint/naming-convention\n Params: Record<string, unknown>;\n // eslint-disable-next-line @typescript-eslint/naming-convention\n ReturnType: SnapAuthorizations;\n },\n {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n Method: 'wallet_requestSnaps';\n // eslint-disable-next-line @typescript-eslint/naming-convention\n Params: Record<string, unknown>;\n // eslint-disable-next-line @typescript-eslint/naming-convention\n ReturnType: SnapAuthorizations;\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 SnapClient = Client<\n Transport,\n Chain | undefined,\n Account | undefined,\n SnapRpcSchema\n>;\n\n/**\n * Checks if a specific snap is authorized, within the specified authorizations object..\n *\n * @param authorizations - The SnapAuthorizations object containing installed Snaps and their authorization status.\n * @param snapId - The ID of the snap to check.\n * @returns A boolean indicating whether the snap is authorized.\n */\nconst isSnapAuthorized = (\n authorizations: SnapAuthorizations,\n snapId: string,\n) => {\n const authorization = authorizations[snapId];\n const isAuthorized =\n (authorization?.enabled && !authorization?.blocked) || false;\n\n return isAuthorized;\n};\n\n/**\n * Requests re-authorization of a specific snap.\n *\n * @param client - The SnapClient instance used to interact with MetaMask Snaps.\n * @param snapId - The ID of the snap to re-authorize.\n * @returns A promise that resolves to a boolean indicating whether the snap was re-authorized.\n */\nconst reAuthorize = async (client: SnapClient, snapId: string) => {\n const newAuthorizations = await client.request({\n method: 'wallet_requestSnaps',\n params: {\n [snapId]: {} as Record<string, unknown>,\n },\n });\n\n return isSnapAuthorized(newAuthorizations, snapId);\n};\n\n/**\n * Ensures that the required MetaMask Snaps for ERC-7715 permissions are authorized.\n *\n * @param client - The SnapClient instance used to interact with MetaMask Snaps.\n * @param snapIds - Optional object containing custom snap IDs to use.\n * @param snapIds.kernelSnapId - Custom ID for the permissions kernel snap (defaults to 'npm:@metamask/permissions-kernel-snap').\n * @param snapIds.providerSnapId - Custom ID for the permissions provider snap (defaults to 'npm:@metamask/gator-permissions-snap').\n * @returns A promise that resolves to a boolean indicating whether both snaps are authorized.\n * @description\n * This function attempts to authorize both the kernel and provider snaps required for ERC-7715 permissions.\n * It returns true only if both snaps are successfully authorized.\n */\nexport async function ensureSnapsAuthorized(\n client: SnapClient,\n snapIds?: { kernelSnapId: string; providerSnapId: string },\n) {\n const kernelSnapId =\n snapIds?.kernelSnapId ?? 'npm:@metamask/permissions-kernel-snap';\n const providerSnapId =\n snapIds?.providerSnapId ?? 'npm:@metamask/gator-permissions-snap';\n\n const existingAuthorizations = await client.request({\n method: 'wallet_getSnaps',\n params: {} as Record<string, never>,\n });\n\n if (\n !isSnapAuthorized(existingAuthorizations, kernelSnapId) &&\n !(await reAuthorize(client, kernelSnapId))\n ) {\n return false;\n }\n\n if (\n !isSnapAuthorized(existingAuthorizations, providerSnapId) &&\n !(await reAuthorize(client, providerSnapId))\n ) {\n return false;\n }\n\n return true;\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 { RequestExecutionPermissionsParameters } from './erc7715RequestExecutionPermissionsAction';\nimport { ensureSnapsAuthorized } from './snapsAuthorization';\nimport type { SnapClient } from './snapsAuthorization';\n\nexport {\n erc7715RequestExecutionPermissionsAction as requestExecutionPermissions,\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 =\n (snapIds?: { kernelSnapId: string; providerSnapId: string }) =>\n (client: Client) => ({\n requestExecutionPermissions: async (\n parameters: RequestExecutionPermissionsParameters,\n ) => {\n if (!(await ensureSnapsAuthorized(client as SnapClient, snapIds))) {\n throw new Error('Snaps not authorized');\n }\n\n return erc7715RequestExecutionPermissionsAction(\n client as SnapClient,\n parameters,\n snapIds?.kernelSnapId,\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"],"mappings":"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","names":["toHex","toHex"]}