UNPKG

@metamask/delegation-toolkit

Version:

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

1 lines 20.1 kB
{"version":3,"sources":["../src/constants.ts","../src/counterfactualAccountData.ts","../src/encodeCalls.ts","../src/webAuthn.ts"],"sourcesContent":["/**\n * To be used in sdk methods to call Implementation specific code\n * @type {Implementation}\n */\nexport enum Implementation {\n MultiSig = 'MultiSig',\n Hybrid = 'Hybrid',\n Stateless7702 = 'Stateless7702',\n}\n","import type { Address, Hex } from 'viem';\nimport { getContractAddress, pad } from 'viem';\n\nimport { Implementation } from './constants';\nimport { initializeHybridDeleGator } from './DelegationFramework/HybridDeleGator/encode';\nimport { initializeMultiSigDeleGator } from './DelegationFramework/MultiSigDeleGator/encode';\nimport { create2Deploy as encodeCreate2Deploy } from './DelegationFramework/SimpleFactory/encode';\nimport { encodeProxyCreationCode } from './DelegationFramework/utils';\nimport type {\n DeleGatorEnvironment,\n HybridDeleGatorDeployParams,\n MultiSigDeleGatorDeployParams,\n DeployParams,\n} from './types';\n\n/**\n * Infers counterfactual account data for a DeleGator smart account.\n *\n * @template TImplementation - The type of implementation, extending Implementation.\n * @template TDeployParams - The type of deployment parameters, defaults to DeployParams<Implementation>.\n * @param options - The options for generating counterfactual account data.\n * @param options.factory - The address of the SimpleFactory contract.\n * @param options.implementations - The DeleGator implementation contracts.\n * @param options.implementation - The implementation type to use.\n * @param options.deployParams - The deployment parameters for the specified implementation.\n * @param options.deploySalt - The salt to use for CREATE2 address computation.\n * @returns An object containing the counterfactual address and factory calldata.\n * @description This function calculates the address a DeleGator contract would have if deployed,\n * and provides the calldata needed to deploy it.\n */\nexport const getCounterfactualAccountData = async <\n TImplementation extends Implementation,\n>({\n factory,\n implementations,\n implementation,\n deployParams,\n deploySalt,\n}: {\n factory: Address;\n implementations: DeleGatorEnvironment['implementations'];\n implementation: TImplementation;\n deployParams: DeployParams<TImplementation>;\n deploySalt: Hex;\n}): Promise<{ factoryData: Hex; address: Address }> => {\n let implementationAddress: Address;\n let initcode: Hex;\n\n switch (implementation) {\n case Implementation.Hybrid: {\n const [owner, keyIds, xValues, yValues] =\n deployParams as HybridDeleGatorDeployParams;\n\n if (!implementations.HybridDeleGatorImpl) {\n throw new Error(\n 'HybridDeleGatorImpl address not provided in environment',\n );\n }\n\n implementationAddress = implementations.HybridDeleGatorImpl;\n\n const p256Owners = keyIds.map((keyId, index) => {\n const xValue = xValues[index];\n const yValue = yValues[index];\n\n if (!xValue || !yValue) {\n throw new Error(\n `Missing X or Y value for keyId ${keyId} at index ${index}`,\n );\n }\n\n return {\n keyId,\n x: xValue,\n y: yValue,\n };\n });\n\n initcode = initializeHybridDeleGator({ eoaOwner: owner, p256Owners });\n break;\n }\n case Implementation.MultiSig: {\n const [owners, threshold] = deployParams as MultiSigDeleGatorDeployParams;\n\n if (!implementations.MultiSigDeleGatorImpl) {\n throw new Error(\n 'MultiSigDeleGatorImpl address not provided in environment',\n );\n }\n\n implementationAddress = implementations.MultiSigDeleGatorImpl;\n initcode = initializeMultiSigDeleGator({ owners, threshold });\n break;\n }\n default:\n throw new Error(`Implementation type '${implementation}' not supported`);\n }\n\n const salt = pad(deploySalt, { dir: 'left', size: 32 });\n\n const proxyCreationCode = encodeProxyCreationCode({\n implementationAddress,\n initcode,\n });\n\n const address = getContractAddress({\n bytecode: proxyCreationCode,\n from: factory,\n opcode: 'CREATE2',\n salt,\n });\n\n const factoryData = encodeCreate2Deploy(proxyCreationCode, salt);\n\n return {\n factoryData,\n address,\n };\n};\n","import { DelegationManager } from '@metamask/delegation-abis';\nimport { encodeFunctionData } from 'viem';\nimport type { Address, Hex } from 'viem';\n\nimport {\n execute,\n executeWithMode,\n} from './DelegationFramework/DeleGatorCore/encode';\nimport {\n ExecutionMode,\n createExecution,\n encodeExecutionCalldatas,\n} from './executions';\nimport type { DelegatedCall } from './experimental/erc7710RedeemDelegationAction';\nimport type { Call } from './types';\n\n/**\n * Checks if a call is a delegated call by checking for the presence of permissionsContext and delegationManager.\n *\n * @param call - The call to check.\n * @returns True if the call is a delegated call, false otherwise.\n */\nconst isDelegatedCall = (call: Call): call is DelegatedCall => {\n return 'permissionsContext' in call && 'delegationManager' in call;\n};\n\n/**\n * If there's a single call with permissionsContext and delegationManager,\n * processes it as a delegated call.\n *\n * @param call - The call to process.\n * @returns The execution object for the delegated call.\n * @description\n * This function creates an execution that calls redeemDelegations on the delegation manager.\n */\nconst processDelegatedCall = (call: DelegatedCall) => {\n const {\n permissionsContext,\n delegationManager,\n to: target,\n value,\n data: callData,\n } = call;\n\n const callAsExecution = createExecution({ target, value, callData });\n\n if (!permissionsContext) {\n return callAsExecution;\n }\n\n const redeemCalldata = encodeFunctionData({\n abi: DelegationManager.abi,\n functionName: 'redeemDelegations',\n args: [\n [permissionsContext],\n [ExecutionMode.SingleDefault],\n encodeExecutionCalldatas([[callAsExecution]]),\n ],\n });\n\n return createExecution({\n target: delegationManager,\n callData: redeemCalldata,\n });\n};\n\n/**\n * If there's a single call, encode the shorthand `execute` function. Otherwise, encode the `executeWithMode` function. Execution type will always be \"default\".\n *\n * @param calls - The calls to execute.\n * @returns The encoded calldata for the DeleGator to execute the calls.\n * @description\n * This function supports both single and batch execution modes.\n * For single calls, it uses the gas-efficient execute function.\n */\nexport const encodeCalls = (calls: readonly Call[]) => {\n if (calls.length === 1) {\n const call = calls[0];\n if (call && !isDelegatedCall(call)) {\n const { to: target, value, data: callData } = call;\n const execution = createExecution({ target, value, callData });\n return execute({ execution });\n }\n }\n\n const executions = calls.map((call) => {\n if (isDelegatedCall(call)) {\n return processDelegatedCall(call);\n }\n const { to: target, value, data: callData } = call;\n return createExecution({ target, value, callData });\n });\n\n const mode =\n calls.length === 1\n ? ExecutionMode.SingleDefault\n : ExecutionMode.BatchDefault;\n return executeWithMode({ mode, executions });\n};\n\n/**\n * Encodes calls for execution by a DeleGator smart contract.\n *\n * @param caller - The address of the DeleGator contract.\n * @param calls - An array of Call objects, each containing 'to', optional 'data', and optional 'value'.\n * @returns A promise that resolves to the encoded function data as a hexadecimal string.\n * @description\n * - If there's a single call directly to the delegator, it returns the call data directly.\n * - For multiple calls or calls to other addresses, it creates executions and encodes them for the DeleGator's execute function.\n * - The execution mode is set to ExecutionMode.SingleDefault for a single call, or ExecutionMode.BatchDefault for multiple calls.\n *\n * todo: This doesn't fully expose the flexibility of the DeleGator's execute function, but it's a start.\n * maybe we add a mechanism where individual calls passed to this function can be encoded batches.\n */\nexport const encodeCallsForCaller = async (\n caller: Address,\n calls: readonly Call[],\n): Promise<Hex> => {\n if (calls.length === 1) {\n const call = calls[0];\n if (call && call.to === caller && !isDelegatedCall(call)) {\n // if there's a single call, and it's to the delegator, we can just return the calldata directly.\n return call.data ?? '0x';\n }\n }\n return encodeCalls(calls);\n};\n","import {\n parseAbiParameters,\n encodeAbiParameters,\n type Hex,\n encodePacked,\n keccak256,\n concat,\n} from 'viem';\nimport { parseSignature } from 'webauthn-p256';\n\nexport const FIELD_MODULUS =\n 115792089210356248762697446949407573529996955224135760342422259061068512044369n;\nexport const MALLEABILITY_THRESHOLD = FIELD_MODULUS / 2n;\n\nexport const SIGNATURE_ABI_PARAMS = parseAbiParameters(\n 'bytes32, uint256, uint256, bytes, bool, string, string, uint256',\n);\n\n/**\n * This function is used to convert the client data returned from the\n * credentials API into a format that can be consumed by the DeleGator\n * contracts. We need the flattend JSON strings before and after the\n * userOpHash/challenge. This function provides those two client data string\n * slices.\n * @param clientDataJson - The client data JSON string.\n * @returns Returns [clientDataJSONPrefix and clientDataJSONSuffix]\n * ClientDataJSONPrefix contains the client data till the challengeHash\n * ClientDataJSONSuffix contains the client data after the challengeHash.\n */\nexport const splitOnChallenge = (\n clientDataJson: string,\n): [clientDataJSONPrefix: string, clientDataJSONSuffix: string] => {\n /*\n CientData looks like this:\n {\n \"type\": \"webauthn.create\" | \"webauthn.get\",\n \"challenge\": \"{userOpHash}\",\n \"origin\": \"{Domain}\",\n \"crossOrigin\": boolean\n } \n */\n try {\n const { challenge } = JSON.parse(clientDataJson);\n if (challenge === undefined) {\n throw new Error('No \"challenge\" found in the input string');\n }\n return clientDataJson.split(challenge) as [string, string];\n } catch (error) {\n throw new Error('No \"challenge\" found in the input string', {\n cause: error,\n });\n }\n};\n\n/**\n * Returns the index of '\"type\":' in the ClientData.\n * @param clientDataJson - Stringified ClientDataJSON.\n * @returns The index of '\"type\":' in the ClientData.\n */\nexport const getResponseTypeLocation = (clientDataJson: string): bigint => {\n try {\n // Find the index of the `\"type\":` key in the JSON string directly\n const typeIndex = clientDataJson.indexOf('\"type\":');\n\n if (typeIndex === -1) {\n throw new Error('No \"type\" found in the input string');\n }\n // Return the index of the `\"type\":` key\n return BigInt(typeIndex);\n } catch (error) {\n // Handle any errors that occur during the search\n throw new Error('No \"type\" found in the input string', {\n cause: error,\n });\n }\n};\n\n/**\n * Encodes a signature to a hexadecimal signature that will be accepted\n * by the DeleGator contracts.\n * @param keyId - The key used for the signature, represented as a hexadecimal string.\n * @param signature - The signature to convert, as Hex.\n * @param clientDataJSON - The client data used in the creation of the signature.\n * @param authenticatorData - The authenticator data used in the creation of the signature.\n * @returns The signature as a valid DeleGator signature encoded as Hexadecimal string.\n */\nexport function encodeDeleGatorSignature(\n keyId: string,\n signature: Hex,\n clientDataJSON: string,\n authenticatorData: Hex,\n): Hex {\n const keyIdHash = keccak256(encodePacked(['string'], [keyId]));\n\n const parsedSignature = parseSignature(signature);\n\n let { s } = parsedSignature;\n\n while (s > MALLEABILITY_THRESHOLD) {\n s = FIELD_MODULUS - s;\n }\n\n const { r } = parsedSignature;\n\n const [clientDataComponent1, clientDataComponent2] =\n splitOnChallenge(clientDataJSON);\n\n const { userVerified } = parseAuthenticatorFlags(authenticatorData);\n\n const responseTypeLocation = getResponseTypeLocation(clientDataJSON);\n\n const encodedSignature = encodeAbiParameters(SIGNATURE_ABI_PARAMS, [\n keyIdHash,\n r,\n s,\n authenticatorData,\n userVerified,\n clientDataComponent1,\n clientDataComponent2,\n responseTypeLocation,\n ]);\n return encodedSignature;\n}\n\nconst AUTHENTICATOR_DATA_FLAGS_OFFSET = 32;\n// We have all of the flag bits defined here for completeness, even though we only extract the userVerified flag.\nenum AuthenticatorDataFlagBitIndex {\n UserPresence = 0,\n UserVerified = 2,\n BackupEligibility = 3,\n BackupState = 4,\n AttestedCredentialData = 6,\n ExtensionData = 7,\n}\n\nexport type AuthenticatorFlags = {\n userVerified: boolean;\n};\n\n/**\n * Parses the authenticator data and returns an authenticator flags object with the `userVerified` flag.\n * See https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API/Authenticator_data.\n * @param authenticatorData - The authenticator data to parse.\n * @returns An object representing the parsed authenticator flags.\n */\nexport function parseAuthenticatorFlags(\n authenticatorData: Hex,\n): AuthenticatorFlags {\n // eslint-disable-next-line no-restricted-globals\n const authenticatorDataBuffer = Buffer.from(\n authenticatorData.slice(2),\n 'hex',\n );\n const flags = authenticatorDataBuffer.readUInt8(\n AUTHENTICATOR_DATA_FLAGS_OFFSET,\n );\n\n // Bit 0 is the least significant bit in the flags byte, so we left shift 0b1 by the bit index\n // eslint-disable-next-line no-bitwise\n const bitMask = 0b1 << AuthenticatorDataFlagBitIndex.UserVerified;\n\n return {\n // eslint-disable-next-line no-bitwise\n userVerified: (flags & bitMask) !== 0x0,\n };\n}\n\n/**\n * Creates a dummy signature.\n * This must meet all early-failure conditions of the real signature, but does not need to be a valid signature.\n * @param keyId - The key ID to use for the dummy signature.\n * @returns The encoded signature.\n */\nexport const createDummyWebAuthnSignature = (keyId: Hex) => {\n // https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API/Authenticator_data#data_structure\n const rpIdHash = keccak256(encodePacked(['string'], ['AuthenticatorData']));\n const flags = '0x05';\n const signCount = '0x00000000';\n const authenticatorData = concat([rpIdHash, flags, signCount]);\n\n const keyIdHash = keccak256(encodePacked(['string'], [keyId]));\n const rs =\n 57896044605178124381348723474703786764998477612067880171211129530534256022184n;\n const userVerification = true;\n const clientDataPrefix = '{\"type\":\"webauthn.get\",\"challenge\":\"';\n const clientDataSuffix = '\",\"origin\":\"passkey-domain\",\"crossOrigin\":false}';\n const responseTypeLocation = 1n;\n\n const encodedSignature = encodeAbiParameters(SIGNATURE_ABI_PARAMS, [\n keyIdHash,\n rs,\n rs,\n authenticatorData,\n userVerification,\n clientDataPrefix,\n clientDataSuffix,\n responseTypeLocation,\n ]);\n\n return encodedSignature;\n};\n"],"mappings":"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","names":["Implementation","encode","encode"]}