@x402/evm 2.7.0 → 2.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -43
- package/dist/cjs/exact/client/index.d.ts +3 -2
- package/dist/cjs/exact/client/index.js +173 -194
- package/dist/cjs/exact/client/index.js.map +1 -1
- package/dist/cjs/exact/facilitator/index.js +199 -185
- package/dist/cjs/exact/facilitator/index.js.map +1 -1
- package/dist/cjs/exact/server/index.d.ts +18 -17
- package/dist/cjs/exact/server/index.js +100 -55
- package/dist/cjs/exact/server/index.js.map +1 -1
- package/dist/cjs/exact/v1/client/index.js +3 -1
- package/dist/cjs/exact/v1/client/index.js.map +1 -1
- package/dist/cjs/exact/v1/facilitator/index.js +3 -1
- package/dist/cjs/exact/v1/facilitator/index.js.map +1 -1
- package/dist/cjs/index.d.ts +38 -2
- package/dist/cjs/index.js +441 -191
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/{permit2-U9Zolx3O.d.ts → permit2-CyZxwngN.d.ts} +278 -87
- package/dist/cjs/scheme-CXDF0D2A.d.ts +47 -0
- package/dist/cjs/upto/client/index.d.ts +32 -0
- package/dist/cjs/upto/client/index.js +507 -0
- package/dist/cjs/upto/client/index.js.map +1 -0
- package/dist/cjs/upto/facilitator/index.d.ts +52 -0
- package/dist/cjs/upto/facilitator/index.js +1233 -0
- package/dist/cjs/upto/facilitator/index.js.map +1 -0
- package/dist/cjs/upto/server/index.d.ts +77 -0
- package/dist/cjs/upto/server/index.js +246 -0
- package/dist/cjs/upto/server/index.js.map +1 -0
- package/dist/cjs/v1/index.d.ts +2 -0
- package/dist/cjs/v1/index.js +3 -1
- package/dist/cjs/v1/index.js.map +1 -1
- package/dist/esm/chunk-C4ZQMS77.mjs +629 -0
- package/dist/esm/chunk-C4ZQMS77.mjs.map +1 -0
- package/dist/esm/chunk-CRT6YNY5.mjs +529 -0
- package/dist/esm/chunk-CRT6YNY5.mjs.map +1 -0
- package/dist/esm/chunk-GJ57SZGI.mjs +121 -0
- package/dist/esm/chunk-GJ57SZGI.mjs.map +1 -0
- package/dist/esm/chunk-JII456TS.mjs +34 -0
- package/dist/esm/chunk-JII456TS.mjs.map +1 -0
- package/dist/esm/chunk-NSFLAANF.mjs +80 -0
- package/dist/esm/chunk-NSFLAANF.mjs.map +1 -0
- package/dist/esm/chunk-RN3WQM6A.mjs +158 -0
- package/dist/esm/chunk-RN3WQM6A.mjs.map +1 -0
- package/dist/esm/chunk-WKBC5YMI.mjs +291 -0
- package/dist/esm/chunk-WKBC5YMI.mjs.map +1 -0
- package/dist/esm/{chunk-IZEI7JTG.mjs → chunk-YUJQ7TLD.mjs} +29 -501
- package/dist/esm/chunk-YUJQ7TLD.mjs.map +1 -0
- package/dist/esm/exact/client/index.d.mts +3 -2
- package/dist/esm/exact/client/index.mjs +8 -5
- package/dist/esm/exact/facilitator/index.mjs +84 -430
- package/dist/esm/exact/facilitator/index.mjs.map +1 -1
- package/dist/esm/exact/server/index.d.mts +18 -17
- package/dist/esm/exact/server/index.mjs +28 -55
- package/dist/esm/exact/server/index.mjs.map +1 -1
- package/dist/esm/exact/v1/client/index.mjs +2 -1
- package/dist/esm/exact/v1/facilitator/index.mjs +2 -1
- package/dist/esm/index.d.mts +38 -2
- package/dist/esm/index.mjs +21 -8
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/{permit2-Bbh3a8_h.d.mts → permit2-CyZxwngN.d.mts} +278 -87
- package/dist/esm/scheme-DCR7hsa3.d.mts +47 -0
- package/dist/esm/upto/client/index.d.mts +32 -0
- package/dist/esm/upto/client/index.mjs +18 -0
- package/dist/esm/upto/client/index.mjs.map +1 -0
- package/dist/esm/upto/facilitator/index.d.mts +52 -0
- package/dist/esm/upto/facilitator/index.mjs +473 -0
- package/dist/esm/upto/facilitator/index.mjs.map +1 -0
- package/dist/esm/upto/server/index.d.mts +77 -0
- package/dist/esm/upto/server/index.mjs +145 -0
- package/dist/esm/upto/server/index.mjs.map +1 -0
- package/dist/esm/v1/index.d.mts +2 -0
- package/dist/esm/v1/index.mjs +2 -1
- package/package.json +34 -4
- package/dist/esm/chunk-GD4MKCN7.mjs +0 -57
- package/dist/esm/chunk-GD4MKCN7.mjs.map +0 -1
- package/dist/esm/chunk-IZEI7JTG.mjs.map +0 -1
- package/dist/esm/chunk-TKN5V2BV.mjs +0 -13
- package/dist/esm/chunk-TKN5V2BV.mjs.map +0 -1
- package/dist/esm/chunk-WJWNS4G4.mjs +0 -518
- package/dist/esm/chunk-WJWNS4G4.mjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/exact/facilitator/eip3009.ts","../../../../src/exact/facilitator/permit2.ts","../../../../src/exact/facilitator/erc20approval.ts","../../../../src/exact/facilitator/permit2-utils.ts","../../../../src/exact/facilitator/scheme.ts","../../../../src/exact/facilitator/register.ts"],"sourcesContent":["import {\n PaymentPayload,\n PaymentRequirements,\n SettleResponse,\n VerifyResponse,\n} from \"@x402/core/types\";\nimport { getAddress, Hex, isAddressEqual, parseErc6492Signature } from \"viem\";\nimport { authorizationTypes } from \"../../constants\";\nimport { FacilitatorEvmSigner } from \"../../signer\";\nimport { getEvmChainId } from \"../../utils\";\nimport { ExactEIP3009Payload } from \"../../types\";\nimport * as Errors from \"./errors\";\nimport {\n diagnoseEip3009SimulationFailure,\n executeTransferWithAuthorization,\n simulateEip3009Transfer,\n} from \"./eip3009-utils\";\n\nexport interface VerifyEIP3009Options {\n /** Run onchain simulation. Defaults to true. */\n simulate?: boolean;\n}\n\nexport interface EIP3009FacilitatorConfig {\n /**\n * If enabled, the facilitator will deploy ERC-4337 smart wallets\n * via EIP-6492 when encountering undeployed contract signatures.\n *\n * @default false\n */\n deployERC4337WithEIP6492: boolean;\n /**\n * If enabled, simulates transaction before settling. Defaults to false, ie only simulate during verify.\n *\n * @default false\n */\n simulateInSettle?: boolean;\n}\n\n/**\n * Verifies an EIP-3009 payment payload.\n *\n * @param signer - The facilitator signer for contract reads\n * @param payload - The payment payload to verify\n * @param requirements - The payment requirements\n * @param eip3009Payload - The EIP-3009 specific payload\n * @param options - Optional verification options\n * @returns Promise resolving to verification response\n */\nexport async function verifyEIP3009(\n signer: FacilitatorEvmSigner,\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n eip3009Payload: ExactEIP3009Payload,\n options?: VerifyEIP3009Options,\n): Promise<VerifyResponse> {\n const payer = eip3009Payload.authorization.from;\n let eip6492Deployment:\n | { factoryAddress: `0x${string}`; factoryCalldata: `0x${string}` }\n | undefined;\n\n // Verify scheme matches\n if (payload.accepted.scheme !== \"exact\" || requirements.scheme !== \"exact\") {\n return {\n isValid: false,\n invalidReason: Errors.ErrInvalidScheme,\n payer,\n };\n }\n\n // Get chain configuration\n if (!requirements.extra?.name || !requirements.extra?.version) {\n return {\n isValid: false,\n invalidReason: Errors.ErrMissingEip712Domain,\n payer,\n };\n }\n\n const { name, version } = requirements.extra;\n const erc20Address = getAddress(requirements.asset);\n\n // Verify network matches\n if (payload.accepted.network !== requirements.network) {\n return {\n isValid: false,\n invalidReason: Errors.ErrNetworkMismatch,\n payer,\n };\n }\n\n // Build typed data for signature verification\n const permitTypedData = {\n types: authorizationTypes,\n primaryType: \"TransferWithAuthorization\" as const,\n domain: {\n name,\n version,\n chainId: getEvmChainId(requirements.network),\n verifyingContract: erc20Address,\n },\n message: {\n from: eip3009Payload.authorization.from,\n to: eip3009Payload.authorization.to,\n value: BigInt(eip3009Payload.authorization.value),\n validAfter: BigInt(eip3009Payload.authorization.validAfter),\n validBefore: BigInt(eip3009Payload.authorization.validBefore),\n nonce: eip3009Payload.authorization.nonce,\n },\n };\n\n // Verify signature\n // Note: verifyTypedData is implementation-dependent and pluggable on FacilitatorEvmSigner\n // Some implementations only do EOA-style ECDSA recovery (e.g. viem/utils verifyTypedData, ethers.verifyTypedData)\n // Viem's publicClient.verifyTypedData supports EOA and Smart Contract Account (ERC-1271 / ERC-6492) signature verification\n let isValid = false;\n try {\n isValid = await signer.verifyTypedData({\n address: eip3009Payload.authorization.from,\n ...permitTypedData,\n signature: eip3009Payload.signature!,\n });\n } catch {\n isValid = false;\n }\n const signature = eip3009Payload.signature!;\n const sigLen = signature.startsWith(\"0x\") ? signature.length - 2 : signature.length;\n\n // Extract EIP-6492 deployment info (factory address + calldata) if present\n const erc6492Data = parseErc6492Signature(signature);\n const hasDeploymentInfo =\n erc6492Data.address &&\n erc6492Data.data &&\n !isAddressEqual(erc6492Data.address, \"0x0000000000000000000000000000000000000000\");\n\n if (hasDeploymentInfo) {\n eip6492Deployment = {\n factoryAddress: erc6492Data.address!,\n factoryCalldata: erc6492Data.data!,\n };\n }\n\n if (!isValid) {\n // Check if signature is from a smart wallet\n const isSmartWallet = sigLen > 130; // 65 bytes = 130 hex chars for EOA\n\n // EOA signature that failed verification — definitely invalid\n if (!isSmartWallet) {\n return {\n isValid: false,\n invalidReason: Errors.ErrInvalidSignature,\n payer,\n };\n }\n\n // Smart wallet signature: check if deployed or has ERC-6492 deployment info\n const bytecode = await signer.getCode({ address: payer });\n const isDeployed = bytecode && bytecode !== \"0x\";\n\n if (!isDeployed && !hasDeploymentInfo) {\n // Undeployed smart wallet with no factory info\n return {\n isValid: false,\n invalidReason: Errors.ErrUndeployedSmartWallet,\n payer,\n };\n }\n // Deployed smart wallet or undeployed with ERC-6492 factory info\n // fall through to remaining field checks and onchain simulation\n }\n\n // Verify payment recipient matches\n if (getAddress(eip3009Payload.authorization.to) !== getAddress(requirements.payTo)) {\n return {\n isValid: false,\n invalidReason: Errors.ErrRecipientMismatch,\n payer,\n };\n }\n\n // Verify validBefore is in the future (with 6 second buffer for block time)\n const now = Math.floor(Date.now() / 1000);\n if (BigInt(eip3009Payload.authorization.validBefore) < BigInt(now + 6)) {\n return {\n isValid: false,\n invalidReason: Errors.ErrValidBeforeExpired,\n payer,\n };\n }\n\n // Verify validAfter is not in the future\n if (BigInt(eip3009Payload.authorization.validAfter) > BigInt(now)) {\n return {\n isValid: false,\n invalidReason: Errors.ErrValidAfterInFuture,\n payer,\n };\n }\n\n // Verify amount exactly matches requirements\n if (BigInt(eip3009Payload.authorization.value) !== BigInt(requirements.amount)) {\n return {\n isValid: false,\n invalidReason: Errors.ErrInvalidAuthorizationValue,\n payer,\n };\n }\n\n // Transaction simulation\n if (options?.simulate !== false) {\n const simulationSucceeded = await simulateEip3009Transfer(\n signer,\n erc20Address,\n eip3009Payload,\n eip6492Deployment,\n );\n if (!simulationSucceeded) {\n return diagnoseEip3009SimulationFailure(\n signer,\n erc20Address,\n eip3009Payload,\n requirements,\n requirements.amount,\n );\n }\n }\n\n return {\n isValid: true,\n invalidReason: undefined,\n payer,\n };\n}\n\n/**\n * Settles an EIP-3009 payment by executing transferWithAuthorization.\n *\n * @param signer - The facilitator signer for contract writes\n * @param payload - The payment payload to settle\n * @param requirements - The payment requirements\n * @param eip3009Payload - The EIP-3009 specific payload\n * @param config - Facilitator configuration\n * @returns Promise resolving to settlement response\n */\nexport async function settleEIP3009(\n signer: FacilitatorEvmSigner,\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n eip3009Payload: ExactEIP3009Payload,\n config: EIP3009FacilitatorConfig,\n): Promise<SettleResponse> {\n const payer = eip3009Payload.authorization.from;\n\n // Re-verify before settling\n const valid = await verifyEIP3009(signer, payload, requirements, eip3009Payload, {\n simulate: config.simulateInSettle ?? false,\n });\n if (!valid.isValid) {\n return {\n success: false,\n network: payload.accepted.network,\n transaction: \"\",\n errorReason: valid.invalidReason ?? Errors.ErrInvalidScheme,\n payer,\n };\n }\n\n try {\n // Parse ERC-6492 signature if applicable (for optional deployment)\n const { address: factoryAddress, data: factoryCalldata } = parseErc6492Signature(\n eip3009Payload.signature!,\n );\n\n // Deploy ERC-4337 smart wallet via EIP-6492 if configured and needed\n if (\n config.deployERC4337WithEIP6492 &&\n factoryAddress &&\n factoryCalldata &&\n !isAddressEqual(factoryAddress, \"0x0000000000000000000000000000000000000000\")\n ) {\n // Check if smart wallet is already deployed\n const bytecode = await signer.getCode({ address: payer });\n\n if (!bytecode || bytecode === \"0x\") {\n // Wallet not deployed - attempt deployment\n const deployTx = await signer.sendTransaction({\n to: factoryAddress as Hex,\n data: factoryCalldata as Hex,\n });\n\n // Wait for deployment transaction\n await signer.waitForTransactionReceipt({ hash: deployTx });\n }\n }\n\n const tx = await executeTransferWithAuthorization(\n signer,\n getAddress(requirements.asset),\n eip3009Payload,\n );\n\n // Wait for transaction confirmation\n const receipt = await signer.waitForTransactionReceipt({ hash: tx });\n\n if (receipt.status !== \"success\") {\n return {\n success: false,\n errorReason: Errors.ErrTransactionFailed,\n transaction: tx,\n network: payload.accepted.network,\n payer,\n };\n }\n\n return {\n success: true,\n transaction: tx,\n network: payload.accepted.network,\n payer,\n };\n } catch {\n return {\n success: false,\n errorReason: Errors.ErrTransactionFailed,\n transaction: \"\",\n network: payload.accepted.network,\n payer,\n };\n }\n}\n","import {\n PaymentPayload,\n PaymentRequirements,\n FacilitatorContext,\n SettleResponse,\n VerifyResponse,\n} from \"@x402/core/types\";\nimport {\n extractEip2612GasSponsoringInfo,\n extractErc20ApprovalGasSponsoringInfo,\n ERC20_APPROVAL_GAS_SPONSORING_KEY,\n resolveErc20ApprovalExtensionSigner,\n type Eip2612GasSponsoringInfo,\n type Erc20ApprovalGasSponsoringFacilitatorExtension,\n type Erc20ApprovalGasSponsoringSigner,\n} from \"../extensions\";\nimport { getAddress } from \"viem\";\nimport {\n PERMIT2_ADDRESS,\n permit2WitnessTypes,\n x402ExactPermit2ProxyABI,\n x402ExactPermit2ProxyAddress,\n} from \"../../constants\";\nimport * as Errors from \"./errors\";\nimport { FacilitatorEvmSigner } from \"../../signer\";\nimport { ExactPermit2Payload } from \"../../types\";\nimport { getEvmChainId } from \"../../utils\";\nimport { validateErc20ApprovalForPayment } from \"./erc20approval\";\nimport {\n simulatePermit2Settle,\n simulatePermit2SettleWithPermit,\n simulatePermit2SettleWithErc20Approval,\n diagnosePermit2SimulationFailure,\n checkPermit2Prerequisites,\n splitEip2612Signature,\n buildPermit2SettleArgs,\n encodePermit2SettleCalldata,\n waitAndReturn,\n mapSettleError,\n validateEip2612PermitForPayment,\n} from \"./permit2-utils\";\n\nexport interface VerifyPermit2Options {\n /** Run onchain simulation. Defaults to true. */\n simulate?: boolean;\n}\n\nexport interface Permit2FacilitatorConfig {\n /**\n * If enabled, simulates transaction before settling. Defaults to false,\n * i.e. only simulate during verify.\n *\n * @default false\n */\n simulateInSettle?: boolean;\n}\n\n/**\n * Verifies a Permit2 payment payload.\n *\n * Handles all Permit2 verification paths:\n * - Standard: checks on-chain Permit2 allowance\n * - EIP-2612: validates the EIP-2612 permit extension when allowance is insufficient\n * - ERC-20 approval: validates the pre-signed approve tx extension when allowance is insufficient\n *\n * @param signer - The facilitator signer for contract reads\n * @param payload - The payment payload to verify\n * @param requirements - The payment requirements\n * @param permit2Payload - The Permit2 specific payload\n * @param context - Optional facilitator context for extension-provided capabilities\n * @param options - Optional verification options (e.g. simulate)\n * @returns Promise resolving to verification response\n */\nexport async function verifyPermit2(\n signer: FacilitatorEvmSigner,\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n permit2Payload: ExactPermit2Payload,\n context?: FacilitatorContext,\n options?: VerifyPermit2Options,\n): Promise<VerifyResponse> {\n const payer = permit2Payload.permit2Authorization.from;\n\n if (payload.accepted.scheme !== \"exact\" || requirements.scheme !== \"exact\") {\n return {\n isValid: false,\n invalidReason: Errors.ErrUnsupportedPayloadType,\n payer,\n };\n }\n\n if (payload.accepted.network !== requirements.network) {\n return {\n isValid: false,\n invalidReason: Errors.ErrNetworkMismatch,\n payer,\n };\n }\n\n const chainId = getEvmChainId(requirements.network);\n const tokenAddress = getAddress(requirements.asset);\n\n if (\n getAddress(permit2Payload.permit2Authorization.spender) !==\n getAddress(x402ExactPermit2ProxyAddress)\n ) {\n return {\n isValid: false,\n invalidReason: Errors.ErrPermit2InvalidSpender,\n payer,\n };\n }\n\n if (\n getAddress(permit2Payload.permit2Authorization.witness.to) !== getAddress(requirements.payTo)\n ) {\n return {\n isValid: false,\n invalidReason: Errors.ErrPermit2RecipientMismatch,\n payer,\n };\n }\n\n const now = Math.floor(Date.now() / 1000);\n if (BigInt(permit2Payload.permit2Authorization.deadline) < BigInt(now + 6)) {\n return {\n isValid: false,\n invalidReason: Errors.ErrPermit2DeadlineExpired,\n payer,\n };\n }\n\n if (BigInt(permit2Payload.permit2Authorization.witness.validAfter) > BigInt(now)) {\n return {\n isValid: false,\n invalidReason: Errors.ErrPermit2NotYetValid,\n payer,\n };\n }\n\n // Verify amount exactly matches requirements\n if (\n BigInt(permit2Payload.permit2Authorization.permitted.amount) !== BigInt(requirements.amount)\n ) {\n return {\n isValid: false,\n invalidReason: Errors.ErrPermit2AmountMismatch,\n payer,\n };\n }\n\n if (getAddress(permit2Payload.permit2Authorization.permitted.token) !== tokenAddress) {\n return {\n isValid: false,\n invalidReason: Errors.ErrPermit2TokenMismatch,\n payer,\n };\n }\n\n const permit2TypedData = {\n types: permit2WitnessTypes,\n primaryType: \"PermitWitnessTransferFrom\" as const,\n domain: {\n name: \"Permit2\",\n chainId,\n verifyingContract: PERMIT2_ADDRESS,\n },\n message: {\n permitted: {\n token: getAddress(permit2Payload.permit2Authorization.permitted.token),\n amount: BigInt(permit2Payload.permit2Authorization.permitted.amount),\n },\n spender: getAddress(permit2Payload.permit2Authorization.spender),\n nonce: BigInt(permit2Payload.permit2Authorization.nonce),\n deadline: BigInt(permit2Payload.permit2Authorization.deadline),\n witness: {\n to: getAddress(permit2Payload.permit2Authorization.witness.to),\n validAfter: BigInt(permit2Payload.permit2Authorization.witness.validAfter),\n },\n },\n };\n\n // Verify signature\n // Note: verifyTypedData is implementation-dependent and pluggable on FacilitatorEvmSigner\n // Some implementations only do EOA-style ECDSA recovery (e.g. viem/utils verifyTypedData, ethers.verifyTypedData)\n // Viem's publicClient.verifyTypedData supports EOA and Smart Contract Account (ERC-1271 / ERC-6492) signature verification\n let signatureValid = false;\n try {\n signatureValid = await signer.verifyTypedData({\n address: payer,\n ...permit2TypedData,\n signature: permit2Payload.signature,\n });\n } catch {\n signatureValid = false;\n }\n\n if (!signatureValid) {\n // Check if the payer is a deployed smart contract\n const bytecode = await signer.getCode({ address: payer });\n const isDeployedContract = bytecode && bytecode !== \"0x\";\n\n if (!isDeployedContract) {\n return {\n isValid: false,\n invalidReason: Errors.ErrPermit2InvalidSignature,\n payer,\n };\n }\n // Deployed smart contract: fall through to simulation\n }\n\n // If simulation is disabled, return early\n if (options?.simulate === false) {\n return { isValid: true, invalidReason: undefined, payer };\n }\n\n // Branch: EIP-2612 gas sponsoring (atomic settleWithPermit via contract)\n const eip2612Info = extractEip2612GasSponsoringInfo(payload);\n if (eip2612Info) {\n const fieldResult = validateEip2612PermitForPayment(eip2612Info, payer, tokenAddress);\n if (!fieldResult.isValid) {\n return { isValid: false, invalidReason: fieldResult.invalidReason!, payer };\n }\n\n const simOk = await simulatePermit2SettleWithPermit(signer, permit2Payload, eip2612Info);\n if (!simOk) {\n return diagnosePermit2SimulationFailure(\n signer,\n tokenAddress,\n permit2Payload,\n requirements.amount,\n );\n }\n\n return { isValid: true, invalidReason: undefined, payer };\n }\n\n // Branch: ERC-20 approval gas sponsoring (broadcast approval + settle via extension signer)\n const erc20GasSponsorshipExtension =\n context?.getExtension<Erc20ApprovalGasSponsoringFacilitatorExtension>(\n ERC20_APPROVAL_GAS_SPONSORING_KEY,\n );\n if (erc20GasSponsorshipExtension) {\n const erc20Info = extractErc20ApprovalGasSponsoringInfo(payload);\n if (erc20Info) {\n const fieldResult = await validateErc20ApprovalForPayment(erc20Info, payer, tokenAddress);\n if (!fieldResult.isValid) {\n return { isValid: false, invalidReason: fieldResult.invalidReason!, payer };\n }\n\n const extensionSigner = resolveErc20ApprovalExtensionSigner(\n erc20GasSponsorshipExtension,\n requirements.network,\n );\n\n if (extensionSigner?.simulateTransactions) {\n const simOk = await simulatePermit2SettleWithErc20Approval(\n extensionSigner,\n permit2Payload,\n erc20Info,\n );\n if (!simOk) {\n return diagnosePermit2SimulationFailure(\n signer,\n tokenAddress,\n permit2Payload,\n requirements.amount,\n );\n }\n return { isValid: true, invalidReason: undefined, payer };\n }\n\n // Fallback to prerequisite-only check if simulateTransactions is not available\n return checkPermit2Prerequisites(signer, tokenAddress, payer, requirements.amount);\n }\n }\n\n // Branch: standard settle (allowance already on-chain)\n const simOk = await simulatePermit2Settle(signer, permit2Payload);\n if (!simOk) {\n return diagnosePermit2SimulationFailure(\n signer,\n tokenAddress,\n permit2Payload,\n requirements.amount,\n );\n }\n\n return { isValid: true, invalidReason: undefined, payer };\n}\n\n/**\n * Settles a Permit2 payment. Single entry point for all Permit2 settlement paths:\n *\n * 1. EIP-2612 extension present -> settleWithPermit (atomic single tx via contract)\n * 2. ERC-20 approval extension present + extension signer -> broadcast approval + settle (via extension signer)\n * 3. Standard -> settle directly (allowance already on-chain)\n *\n * @param signer - The base facilitator signer for contract writes\n * @param payload - The payment payload to settle\n * @param requirements - The payment requirements\n * @param permit2Payload - The Permit2 specific payload\n * @param context - Optional facilitator context for extension-provided capabilities\n * @param config - Optional facilitator config (simulateInSettle)\n * @returns Promise resolving to settlement response\n */\nexport async function settlePermit2(\n signer: FacilitatorEvmSigner,\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n permit2Payload: ExactPermit2Payload,\n context?: FacilitatorContext,\n config?: Permit2FacilitatorConfig,\n): Promise<SettleResponse> {\n const payer = permit2Payload.permit2Authorization.from;\n\n const valid = await verifyPermit2(signer, payload, requirements, permit2Payload, context, {\n simulate: config?.simulateInSettle ?? false,\n });\n if (!valid.isValid) {\n return {\n success: false,\n network: payload.accepted.network,\n transaction: \"\",\n errorReason: valid.invalidReason ?? Errors.ErrInvalidScheme,\n payer,\n };\n }\n\n // Branch: EIP-2612 gas sponsoring (atomic settleWithPermit via contract)\n const eip2612Info = extractEip2612GasSponsoringInfo(payload);\n if (eip2612Info) {\n return _settlePermit2WithEIP2612(signer, payload, permit2Payload, eip2612Info);\n }\n\n // Branch: ERC-20 approval gas sponsoring (broadcast approval + settle via extension signer)\n const erc20Info = extractErc20ApprovalGasSponsoringInfo(payload);\n if (erc20Info) {\n const erc20GasSponsorshipExtension =\n context?.getExtension<Erc20ApprovalGasSponsoringFacilitatorExtension>(\n ERC20_APPROVAL_GAS_SPONSORING_KEY,\n );\n const extensionSigner = resolveErc20ApprovalExtensionSigner(\n erc20GasSponsorshipExtension,\n payload.accepted.network,\n );\n if (extensionSigner) {\n return _settlePermit2WithERC20Approval(extensionSigner, payload, permit2Payload, erc20Info);\n }\n }\n\n // Branch: standard settle (allowance already on-chain)\n return _settlePermit2Direct(signer, payload, permit2Payload);\n}\n\n/**\n * Settles via settleWithPermit — includes the EIP-2612 permit atomically in one tx.\n *\n * @param signer - The base facilitator signer\n * @param payload - The payment payload\n * @param permit2Payload - The Permit2 specific payload\n * @param eip2612Info - The EIP-2612 gas sponsoring info from the payload extension\n * @returns Promise resolving to settlement response\n */\nasync function _settlePermit2WithEIP2612(\n signer: FacilitatorEvmSigner,\n payload: PaymentPayload,\n permit2Payload: ExactPermit2Payload,\n eip2612Info: Eip2612GasSponsoringInfo,\n): Promise<SettleResponse> {\n const payer = permit2Payload.permit2Authorization.from;\n try {\n const { v, r, s } = splitEip2612Signature(eip2612Info.signature);\n\n const tx = await signer.writeContract({\n address: x402ExactPermit2ProxyAddress,\n abi: x402ExactPermit2ProxyABI,\n functionName: \"settleWithPermit\",\n args: [\n {\n value: BigInt(eip2612Info.amount),\n deadline: BigInt(eip2612Info.deadline),\n r,\n s,\n v,\n },\n ...buildPermit2SettleArgs(permit2Payload),\n ],\n });\n\n return waitAndReturn(signer, tx, payload, payer);\n } catch (error) {\n return mapSettleError(error, payload, payer);\n }\n}\n\n/**\n * Delegates the full approve+settle flow to the extension signer via sendTransactions.\n * The signer owns execution strategy (sequential, batched, or atomic bundling).\n *\n * @param extensionSigner - The extension signer with sendTransactions\n * @param payload - The payment payload\n * @param permit2Payload - The Permit2 specific payload\n * @param erc20Info - Object containing the signed approval transaction\n * @param erc20Info.signedTransaction - The RLP-encoded signed ERC-20 approve transaction hex string\n * @returns Promise resolving to settlement response\n */\nasync function _settlePermit2WithERC20Approval(\n extensionSigner: Erc20ApprovalGasSponsoringSigner,\n payload: PaymentPayload,\n permit2Payload: ExactPermit2Payload,\n erc20Info: { signedTransaction: string },\n): Promise<SettleResponse> {\n const payer = permit2Payload.permit2Authorization.from;\n\n try {\n const settleData = encodePermit2SettleCalldata(permit2Payload);\n\n const txHashes = await extensionSigner.sendTransactions([\n erc20Info.signedTransaction as `0x${string}`,\n { to: x402ExactPermit2ProxyAddress, data: settleData, gas: BigInt(300_000) },\n ]);\n\n const settleTxHash = txHashes[txHashes.length - 1];\n return waitAndReturn(extensionSigner, settleTxHash, payload, payer);\n } catch (error) {\n return mapSettleError(error, payload, payer);\n }\n}\n\n/**\n * Standard Permit2 settle — allowance is already on-chain.\n *\n * @param signer - The base facilitator signer\n * @param payload - The payment payload\n * @param permit2Payload - The Permit2 specific payload\n * @returns Promise resolving to settlement response\n */\nasync function _settlePermit2Direct(\n signer: FacilitatorEvmSigner,\n payload: PaymentPayload,\n permit2Payload: ExactPermit2Payload,\n): Promise<SettleResponse> {\n const payer = permit2Payload.permit2Authorization.from;\n try {\n const tx = await signer.writeContract({\n address: x402ExactPermit2ProxyAddress,\n abi: x402ExactPermit2ProxyABI,\n functionName: \"settle\",\n args: buildPermit2SettleArgs(permit2Payload),\n });\n\n return waitAndReturn(signer, tx, payload, payer);\n } catch (error) {\n return mapSettleError(error, payload, payer);\n }\n}\n","import {\n getAddress,\n parseTransaction,\n decodeFunctionData,\n recoverTransactionAddress,\n type TransactionSerialized,\n} from \"viem\";\nimport type { VerifyResponse } from \"@x402/core/types\";\nimport {\n validateErc20ApprovalGasSponsoringInfo,\n type Erc20ApprovalGasSponsoringInfo,\n} from \"../extensions\";\nimport { PERMIT2_ADDRESS, erc20ApproveAbi } from \"../../constants\";\nimport {\n ErrErc20ApprovalInvalidFormat,\n ErrErc20ApprovalFromMismatch,\n ErrErc20ApprovalAssetMismatch,\n ErrErc20ApprovalSpenderNotPermit2,\n ErrErc20ApprovalTxWrongTarget,\n ErrErc20ApprovalTxWrongSelector,\n ErrErc20ApprovalTxWrongSpender,\n ErrErc20ApprovalTxInvalidCalldata,\n ErrErc20ApprovalTxSignerMismatch,\n ErrErc20ApprovalTxInvalidSignature,\n ErrErc20ApprovalTxParseFailed,\n} from \"./errors\";\n\n/** The approve(address,uint256) function selector */\nconst APPROVE_SELECTOR = \"0x095ea7b3\";\n\n/**\n * Validates ERC-20 approval extension data for a Permit2 payment.\n *\n * Performs comprehensive validation:\n * - Format validation via validateErc20ApprovalGasSponsoringInfo (JSON Schema)\n * - `from` matches payer\n * - `asset` matches token\n * - `spender` is PERMIT2_ADDRESS\n * - Transaction `to` matches token address\n * - Transaction calldata is a valid approve(PERMIT2_ADDRESS, ...) call\n * - Recovered transaction signer matches `from`\n *\n * @param info - The ERC-20 approval gas sponsoring info\n * @param payer - The expected payer address\n * @param tokenAddress - The expected token address\n * @returns Validation result with invalidReason and invalidMessage on failure\n */\nexport async function validateErc20ApprovalForPayment(\n info: Erc20ApprovalGasSponsoringInfo,\n payer: `0x${string}`,\n tokenAddress: `0x${string}`,\n): Promise<Pick<VerifyResponse, \"isValid\" | \"invalidReason\" | \"invalidMessage\">> {\n if (!validateErc20ApprovalGasSponsoringInfo(info)) {\n return {\n isValid: false,\n invalidReason: ErrErc20ApprovalInvalidFormat,\n invalidMessage: \"ERC-20 approval extension info failed schema validation\",\n };\n }\n\n if (getAddress(info.from) !== getAddress(payer)) {\n return {\n isValid: false,\n invalidReason: ErrErc20ApprovalFromMismatch,\n invalidMessage: `Expected from=${payer}, got ${info.from}`,\n };\n }\n\n if (getAddress(info.asset) !== tokenAddress) {\n return {\n isValid: false,\n invalidReason: ErrErc20ApprovalAssetMismatch,\n invalidMessage: `Expected asset=${tokenAddress}, got ${info.asset}`,\n };\n }\n\n if (getAddress(info.spender) !== getAddress(PERMIT2_ADDRESS)) {\n return {\n isValid: false,\n invalidReason: ErrErc20ApprovalSpenderNotPermit2,\n invalidMessage: `Expected spender=${PERMIT2_ADDRESS}, got ${info.spender}`,\n };\n }\n\n try {\n const serializedTx = info.signedTransaction as TransactionSerialized;\n const tx = parseTransaction(serializedTx);\n\n if (!tx.to || getAddress(tx.to) !== tokenAddress) {\n return {\n isValid: false,\n invalidReason: ErrErc20ApprovalTxWrongTarget,\n invalidMessage: `Transaction targets ${tx.to ?? \"null\"}, expected ${tokenAddress}`,\n };\n }\n\n const data = tx.data ?? \"0x\";\n if (!data.startsWith(APPROVE_SELECTOR)) {\n return {\n isValid: false,\n invalidReason: ErrErc20ApprovalTxWrongSelector,\n invalidMessage: `Transaction calldata does not start with approve() selector ${APPROVE_SELECTOR}`,\n };\n }\n\n try {\n const decoded = decodeFunctionData({\n abi: erc20ApproveAbi,\n data: data as `0x${string}`,\n });\n const calldataSpender = getAddress(decoded.args[0] as `0x${string}`);\n if (calldataSpender !== getAddress(PERMIT2_ADDRESS)) {\n return {\n isValid: false,\n invalidReason: ErrErc20ApprovalTxWrongSpender,\n invalidMessage: `approve() spender is ${calldataSpender}, expected Permit2 ${PERMIT2_ADDRESS}`,\n };\n }\n } catch {\n return {\n isValid: false,\n invalidReason: ErrErc20ApprovalTxInvalidCalldata,\n invalidMessage: \"Failed to decode approve() calldata from the signed transaction\",\n };\n }\n\n try {\n const recoveredAddress = await recoverTransactionAddress({\n serializedTransaction: serializedTx,\n });\n if (getAddress(recoveredAddress) !== getAddress(payer)) {\n return {\n isValid: false,\n invalidReason: ErrErc20ApprovalTxSignerMismatch,\n invalidMessage: `Transaction signed by ${recoveredAddress}, expected payer ${payer}`,\n };\n }\n } catch {\n return {\n isValid: false,\n invalidReason: ErrErc20ApprovalTxInvalidSignature,\n invalidMessage: \"Failed to recover signer from the signed transaction\",\n };\n }\n } catch {\n return {\n isValid: false,\n invalidReason: ErrErc20ApprovalTxParseFailed,\n invalidMessage: \"Failed to parse the signed transaction\",\n };\n }\n\n return { isValid: true };\n}\n","import { PaymentPayload, SettleResponse, VerifyResponse } from \"@x402/core/types\";\nimport { encodeFunctionData, getAddress } from \"viem\";\nimport {\n eip3009ABI,\n erc20AllowanceAbi,\n ERC20_APPROVE_GAS_LIMIT,\n DEFAULT_MAX_FEE_PER_GAS,\n PERMIT2_ADDRESS,\n x402ExactPermit2ProxyABI,\n x402ExactPermit2ProxyAddress,\n} from \"../../constants\";\nimport {\n multicall,\n ContractCall,\n MULTICALL3_ADDRESS,\n multicall3GetEthBalanceAbi,\n} from \"../../multicall\";\nimport { FacilitatorEvmSigner } from \"../../signer\";\nimport { ExactPermit2Payload } from \"../../types\";\nimport {\n validateEip2612GasSponsoringInfo,\n type Eip2612GasSponsoringInfo,\n type Erc20ApprovalGasSponsoringSigner,\n} from \"../extensions\";\nimport * as Errors from \"./errors\";\n\n/**\n * Simulates settle() via eth_call (readContract).\n * Returns true if simulation succeeded, false if it failed.\n *\n * @param signer - EVM signer for contract reads\n * @param permit2Payload - Permit2 payload with authorization and signature\n * @returns true if simulation succeeded, false if it failed\n */\nexport async function simulatePermit2Settle(\n signer: FacilitatorEvmSigner,\n permit2Payload: ExactPermit2Payload,\n): Promise<boolean> {\n try {\n await signer.readContract({\n address: x402ExactPermit2ProxyAddress,\n abi: x402ExactPermit2ProxyABI,\n functionName: \"settle\",\n args: buildPermit2SettleArgs(permit2Payload),\n });\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Splits a 65-byte EIP-2612 signature into v, r, s components for contract calls.\n * Validates length and throws if invalid.\n *\n * @param signature - The hex-encoded 65-byte signature\n * @returns Object with v (uint8), r (bytes32), s (bytes32)\n */\nexport function splitEip2612Signature(signature: string): {\n v: number;\n r: `0x${string}`;\n s: `0x${string}`;\n} {\n const sig = signature.startsWith(\"0x\") ? signature.slice(2) : signature;\n\n if (sig.length !== 130) {\n throw new Error(\n `invalid EIP-2612 signature length: expected 65 bytes (130 hex chars), got ${sig.length / 2} bytes`,\n );\n }\n\n const r = `0x${sig.slice(0, 64)}` as `0x${string}`;\n const s = `0x${sig.slice(64, 128)}` as `0x${string}`;\n const v = parseInt(sig.slice(128, 130), 16);\n\n return { v, r, s };\n}\n\n/**\n * Builds the args array for settle() and settleWithPermit() Permit2 calls.\n * Shared by simulation and settlement to keep contract ABI shape in one place.\n *\n * @param permit2Payload - The Permit2 authorization payload\n * @returns The args tuple for settle(permit, owner, witness, signature)\n */\nexport function buildPermit2SettleArgs(permit2Payload: ExactPermit2Payload) {\n return [\n {\n permitted: {\n token: getAddress(permit2Payload.permit2Authorization.permitted.token),\n amount: BigInt(permit2Payload.permit2Authorization.permitted.amount),\n },\n nonce: BigInt(permit2Payload.permit2Authorization.nonce),\n deadline: BigInt(permit2Payload.permit2Authorization.deadline),\n },\n getAddress(permit2Payload.permit2Authorization.from),\n {\n to: getAddress(permit2Payload.permit2Authorization.witness.to),\n validAfter: BigInt(permit2Payload.permit2Authorization.witness.validAfter),\n },\n permit2Payload.signature,\n ] as const;\n}\n\n/**\n * Encodes settle() calldata for the x402 Exact Permit2 proxy.\n * Used when bundling approve + settle (e.g. ERC-20 approval gas sponsoring).\n *\n * @param permit2Payload - The Permit2 authorization payload\n * @returns Hex-encoded settle calldata\n */\nexport function encodePermit2SettleCalldata(permit2Payload: ExactPermit2Payload): `0x${string}` {\n return encodeFunctionData({\n abi: x402ExactPermit2ProxyABI,\n functionName: \"settle\",\n args: buildPermit2SettleArgs(permit2Payload),\n });\n}\n\n/**\n * Simulates settleWithPermit() via eth_call (readContract).\n * The contract atomically calls token.permit() then PERMIT2.permitTransferFrom(),\n * so simulation covers allowance + balance + nonces.\n *\n * @param signer - EVM signer for contract reads\n * @param permit2Payload - Permit2 payload with authorization and signature\n * @param eip2612Info - EIP-2612 gas sponsoring info from the payload extension\n * @returns true if simulation succeeded, false if it failed\n */\nexport async function simulatePermit2SettleWithPermit(\n signer: FacilitatorEvmSigner,\n permit2Payload: ExactPermit2Payload,\n eip2612Info: Eip2612GasSponsoringInfo,\n): Promise<boolean> {\n try {\n const { v, r, s } = splitEip2612Signature(eip2612Info.signature);\n\n await signer.readContract({\n address: x402ExactPermit2ProxyAddress,\n abi: x402ExactPermit2ProxyABI,\n functionName: \"settleWithPermit\",\n args: [\n {\n value: BigInt(eip2612Info.amount),\n deadline: BigInt(eip2612Info.deadline),\n r,\n s,\n v,\n },\n ...buildPermit2SettleArgs(permit2Payload),\n ],\n });\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Diagnoses a Permit2 simulation failure by performing a multicall to check the proxy deployment, balance and allowance.\n *\n * @param signer - EVM signer for contract reads\n * @param tokenAddress - ERC-20 token contract address\n * @param permit2Payload - The Permit2 authorization payload\n * @param amountRequired - Required payment amount (as string)\n * @returns VerifyResponse with the most specific failure reason\n */\nexport async function diagnosePermit2SimulationFailure(\n signer: FacilitatorEvmSigner,\n tokenAddress: `0x${string}`,\n permit2Payload: ExactPermit2Payload,\n amountRequired: string,\n): Promise<VerifyResponse> {\n const payer = permit2Payload.permit2Authorization.from;\n\n const diagnosticCalls: ContractCall[] = [\n {\n address: x402ExactPermit2ProxyAddress,\n abi: x402ExactPermit2ProxyABI,\n functionName: \"PERMIT2\",\n },\n {\n address: tokenAddress,\n abi: eip3009ABI,\n functionName: \"balanceOf\",\n args: [payer],\n },\n {\n address: tokenAddress,\n abi: erc20AllowanceAbi,\n functionName: \"allowance\",\n args: [payer, PERMIT2_ADDRESS],\n },\n ];\n\n try {\n const results = await multicall(signer.readContract.bind(signer), diagnosticCalls);\n\n const [proxyResult, balanceResult, allowanceResult] = results;\n\n if (proxyResult.status === \"failure\") {\n return { isValid: false, invalidReason: Errors.ErrPermit2ProxyNotDeployed, payer };\n }\n\n if (balanceResult.status === \"success\") {\n const balance = balanceResult.result as bigint;\n if (balance < BigInt(amountRequired)) {\n return { isValid: false, invalidReason: Errors.ErrPermit2InsufficientBalance, payer };\n }\n }\n\n if (allowanceResult.status === \"success\") {\n const allowance = allowanceResult.result as bigint;\n if (allowance < BigInt(amountRequired)) {\n return { isValid: false, invalidReason: Errors.ErrPermit2AllowanceRequired, payer };\n }\n }\n } catch {\n // Diagnostic multicall itself failed — fall through to generic error\n }\n\n return { isValid: false, invalidReason: Errors.ErrPermit2SimulationFailed, payer };\n}\n\n/**\n * Targeted multicall for the ERC-20 approval path where simulation cannot be used\n * (the approval hasn't been broadcast yet, so settle() would fail for expected reasons).\n * Checks proxy deployment, payer token balance and payer ETH balance for gas.\n *\n * @param signer - EVM signer for contract reads\n * @param tokenAddress - ERC-20 token contract address\n * @param payer - The payer address\n * @param amountRequired - Required payment amount (as string)\n * @returns VerifyResponse — valid if checks pass, otherwise the most specific failure\n */\nexport async function checkPermit2Prerequisites(\n signer: FacilitatorEvmSigner,\n tokenAddress: `0x${string}`,\n payer: `0x${string}`,\n amountRequired: string,\n): Promise<VerifyResponse> {\n const diagnosticCalls: ContractCall[] = [\n {\n address: x402ExactPermit2ProxyAddress,\n abi: x402ExactPermit2ProxyABI,\n functionName: \"PERMIT2\",\n },\n {\n address: tokenAddress,\n abi: eip3009ABI,\n functionName: \"balanceOf\",\n args: [payer],\n },\n {\n address: MULTICALL3_ADDRESS,\n abi: multicall3GetEthBalanceAbi,\n functionName: \"getEthBalance\",\n args: [payer],\n },\n ];\n\n try {\n const results = await multicall(signer.readContract.bind(signer), diagnosticCalls);\n\n const [proxyResult, balanceResult, ethBalanceResult] = results;\n\n if (proxyResult.status === \"failure\") {\n return { isValid: false, invalidReason: Errors.ErrPermit2ProxyNotDeployed, payer };\n }\n\n if (balanceResult.status === \"success\") {\n const balance = balanceResult.result as bigint;\n if (balance < BigInt(amountRequired)) {\n return { isValid: false, invalidReason: Errors.ErrPermit2InsufficientBalance, payer };\n }\n }\n\n if (ethBalanceResult.status === \"success\") {\n const minEthForApprovalGas = ERC20_APPROVE_GAS_LIMIT * DEFAULT_MAX_FEE_PER_GAS;\n const ethBalance = ethBalanceResult.result as bigint;\n if (ethBalance < minEthForApprovalGas) {\n return {\n isValid: false,\n invalidReason: Errors.ErrErc20ApprovalInsufficientEthForGas,\n payer,\n };\n }\n }\n } catch {\n // Multicall failed — fall through to valid (fail open for prerequisites-only check)\n }\n\n return { isValid: true, invalidReason: undefined, payer };\n}\n\n/**\n * Delegates the full approve+settle simulation flow to the extension signer via simulateTransactions.\n * The signer owns execution strategy.\n *\n * @param extensionSigner - The extension signer with simulateTransactions capability\n * @param permit2Payload - The Permit2 specific payload\n * @param erc20Info - Object containing the signed approval transaction\n * @param erc20Info.signedTransaction - The RLP-encoded signed ERC-20 approve transaction\n * @returns true if the bundle simulation succeeded, false otherwise\n */\nexport async function simulatePermit2SettleWithErc20Approval(\n extensionSigner: Erc20ApprovalGasSponsoringSigner,\n permit2Payload: ExactPermit2Payload,\n erc20Info: { signedTransaction: string },\n): Promise<boolean> {\n if (!extensionSigner.simulateTransactions) {\n return false;\n }\n\n try {\n const settleData = encodePermit2SettleCalldata(permit2Payload);\n\n return await extensionSigner.simulateTransactions([\n erc20Info.signedTransaction as `0x${string}`,\n { to: x402ExactPermit2ProxyAddress, data: settleData, gas: BigInt(300_000) },\n ]);\n } catch {\n return false;\n }\n}\n\n/**\n * Waits for tx receipt and returns the appropriate SettleResponse.\n *\n * @param signer - Signer with waitForTransactionReceipt capability\n * @param tx - The transaction hash to wait for\n * @param payload - The payment payload (for network info)\n * @param payer - The payer address\n * @returns Promise resolving to settlement response\n */\nexport async function waitAndReturn(\n signer: Pick<FacilitatorEvmSigner, \"waitForTransactionReceipt\">,\n tx: `0x${string}`,\n payload: PaymentPayload,\n payer: `0x${string}`,\n): Promise<SettleResponse> {\n const receipt = await signer.waitForTransactionReceipt({ hash: tx });\n\n if (receipt.status !== \"success\") {\n return {\n success: false,\n errorReason: Errors.ErrInvalidTransactionState,\n transaction: tx,\n network: payload.accepted.network,\n payer,\n };\n }\n\n return {\n success: true,\n transaction: tx,\n network: payload.accepted.network,\n payer,\n };\n}\n\n/**\n * Maps contract revert errors to structured SettleResponse error reasons.\n *\n * @param error - The caught error\n * @param payload - The payment payload (for network info)\n * @param payer - The payer address\n * @returns A failed SettleResponse with mapped error reason\n */\nexport function mapSettleError(\n error: unknown,\n payload: PaymentPayload,\n payer: `0x${string}`,\n): SettleResponse {\n let errorReason = Errors.ErrTransactionFailed;\n if (error instanceof Error) {\n const message = error.message;\n if (message.includes(\"Permit2612AmountMismatch\")) {\n errorReason = Errors.ErrPermit2612AmountMismatch;\n } else if (message.includes(\"InvalidAmount\")) {\n errorReason = Errors.ErrPermit2InvalidAmount;\n } else if (message.includes(\"InvalidDestination\")) {\n errorReason = Errors.ErrPermit2InvalidDestination;\n } else if (message.includes(\"InvalidOwner\")) {\n errorReason = Errors.ErrPermit2InvalidOwner;\n } else if (message.includes(\"PaymentTooEarly\")) {\n errorReason = Errors.ErrPermit2PaymentTooEarly;\n } else if (message.includes(\"InvalidSignature\") || message.includes(\"SignatureExpired\")) {\n errorReason = Errors.ErrPermit2InvalidSignature;\n } else if (message.includes(\"InvalidNonce\")) {\n errorReason = Errors.ErrPermit2InvalidNonce;\n } else if (message.includes(\"erc20_approval_tx_failed\")) {\n errorReason = Errors.ErrErc20ApprovalTxFailed;\n } else {\n errorReason = `${Errors.ErrTransactionFailed}: ${message.slice(0, 500)}`;\n }\n }\n return {\n success: false,\n errorReason,\n transaction: \"\",\n network: payload.accepted.network,\n payer,\n };\n}\n\n/**\n * Validates EIP-2612 permit extension data for a Permit2 payment.\n *\n * @param info - The EIP-2612 gas sponsoring info\n * @param payer - The expected payer address\n * @param tokenAddress - The expected token address\n * @returns Validation result with optional invalidReason\n */\nexport function validateEip2612PermitForPayment(\n info: Eip2612GasSponsoringInfo,\n payer: `0x${string}`,\n tokenAddress: `0x${string}`,\n): { isValid: boolean; invalidReason?: string } {\n if (!validateEip2612GasSponsoringInfo(info)) {\n return { isValid: false, invalidReason: Errors.ErrInvalidEip2612ExtensionFormat };\n }\n\n if (getAddress(info.from as `0x${string}`) !== getAddress(payer)) {\n return { isValid: false, invalidReason: Errors.ErrEip2612FromMismatch };\n }\n\n if (getAddress(info.asset as `0x${string}`) !== tokenAddress) {\n return { isValid: false, invalidReason: Errors.ErrEip2612AssetMismatch };\n }\n\n if (getAddress(info.spender as `0x${string}`) !== getAddress(PERMIT2_ADDRESS)) {\n return { isValid: false, invalidReason: Errors.ErrEip2612SpenderNotPermit2 };\n }\n\n const now = Math.floor(Date.now() / 1000);\n if (BigInt(info.deadline) < BigInt(now + 6)) {\n return { isValid: false, invalidReason: Errors.ErrEip2612DeadlineExpired };\n }\n\n return { isValid: true };\n}\n","import {\n PaymentPayload,\n PaymentRequirements,\n SchemeNetworkFacilitator,\n FacilitatorContext,\n SettleResponse,\n VerifyResponse,\n} from \"@x402/core/types\";\nimport { FacilitatorEvmSigner } from \"../../signer\";\nimport { ExactEvmPayloadV2, ExactEIP3009Payload, isPermit2Payload } from \"../../types\";\nimport { verifyEIP3009, settleEIP3009 } from \"./eip3009\";\nimport { verifyPermit2, settlePermit2 } from \"./permit2\";\n\nexport interface ExactEvmSchemeConfig {\n /**\n * If enabled, the facilitator will deploy ERC-4337 smart wallets\n * via EIP-6492 when encountering undeployed contract signatures.\n *\n * @default false\n */\n deployERC4337WithEIP6492?: boolean;\n /**\n * If enabled, run on-chain simulation during settle's re-verify.\n *\n * @default false\n */\n simulateInSettle?: boolean;\n}\n\n/**\n * EVM facilitator implementation for the Exact payment scheme.\n * Thin router that delegates to EIP-3009 or Permit2 based on payload type.\n * All extension handling (EIP-2612, ERC-20 approval gas sponsoring) is owned\n * by the Permit2 functions via FacilitatorContext.\n */\nexport class ExactEvmScheme implements SchemeNetworkFacilitator {\n readonly scheme = \"exact\";\n readonly caipFamily = \"eip155:*\";\n private readonly config: Required<ExactEvmSchemeConfig>;\n\n /**\n * Creates a new ExactEvmScheme facilitator instance.\n *\n * @param signer - The EVM signer for facilitator operations\n * @param config - Optional configuration\n */\n constructor(\n private readonly signer: FacilitatorEvmSigner,\n config?: ExactEvmSchemeConfig,\n ) {\n this.config = {\n deployERC4337WithEIP6492: config?.deployERC4337WithEIP6492 ?? false,\n simulateInSettle: config?.simulateInSettle ?? false,\n };\n }\n\n /**\n * Returns undefined — EVM has no mechanism-specific extra data.\n *\n * @param _ - The network identifier (unused)\n * @returns undefined\n */\n getExtra(_: string): Record<string, unknown> | undefined {\n return undefined;\n }\n\n /**\n * Returns facilitator wallet addresses for the supported response.\n *\n * @param _ - The network identifier (unused, addresses are network-agnostic)\n * @returns Array of facilitator wallet addresses\n */\n getSigners(_: string): string[] {\n return [...this.signer.getAddresses()];\n }\n\n /**\n * Verifies a payment payload. Routes to Permit2 or EIP-3009 based on payload type.\n *\n * @param payload - The payment payload to verify\n * @param requirements - The payment requirements\n * @param context - Optional facilitator context for extension capabilities\n * @returns Promise resolving to verification response\n */\n async verify(\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n context?: FacilitatorContext,\n ): Promise<VerifyResponse> {\n const rawPayload = payload.payload as ExactEvmPayloadV2;\n const isPermit2 = isPermit2Payload(rawPayload);\n\n if (isPermit2) {\n return verifyPermit2(this.signer, payload, requirements, rawPayload, context);\n }\n\n const eip3009Payload: ExactEIP3009Payload = rawPayload;\n return verifyEIP3009(this.signer, payload, requirements, eip3009Payload);\n }\n\n /**\n * Settles a payment. Routes to Permit2 or EIP-3009 based on payload type.\n *\n * @param payload - The payment payload to settle\n * @param requirements - The payment requirements\n * @param context - Optional facilitator context for extension capabilities\n * @returns Promise resolving to settlement response\n */\n async settle(\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n context?: FacilitatorContext,\n ): Promise<SettleResponse> {\n const rawPayload = payload.payload as ExactEvmPayloadV2;\n const isPermit2 = isPermit2Payload(rawPayload);\n\n if (isPermit2) {\n return settlePermit2(this.signer, payload, requirements, rawPayload, context, {\n simulateInSettle: this.config.simulateInSettle,\n });\n }\n\n const eip3009Payload: ExactEIP3009Payload = rawPayload;\n return settleEIP3009(this.signer, payload, requirements, eip3009Payload, this.config);\n }\n}\n","import { x402Facilitator } from \"@x402/core/facilitator\";\nimport { Network } from \"@x402/core/types\";\nimport { FacilitatorEvmSigner } from \"../../signer\";\nimport { ExactEvmScheme } from \"./scheme\";\nimport { ExactEvmSchemeV1 } from \"../v1/facilitator/scheme\";\nimport { NETWORKS } from \"../../v1\";\n\n/**\n * Configuration options for registering EVM schemes to an x402Facilitator\n */\nexport interface EvmFacilitatorConfig {\n /**\n * The EVM signer for facilitator operations (verify and settle)\n */\n signer: FacilitatorEvmSigner;\n\n /**\n * Networks to register (single network or array of networks)\n * Examples: \"eip155:84532\", [\"eip155:84532\", \"eip155:1\"]\n */\n networks: Network | Network[];\n\n /**\n * If enabled, the facilitator will deploy ERC-4337 smart wallets\n * via EIP-6492 when encountering undeployed contract signatures.\n *\n * @default false\n */\n deployERC4337WithEIP6492?: boolean;\n\n /**\n * If enabled, reruns on-chain simulation during settle's re-verify.\n *\n * @default false\n */\n simulateInSettle?: boolean;\n}\n\n/**\n * Registers EVM exact payment schemes to an x402Facilitator instance.\n *\n * This function registers:\n * - V2: Specified networks with ExactEvmScheme\n * - V1: All supported EVM networks with ExactEvmSchemeV1\n *\n * @param facilitator - The x402Facilitator instance to register schemes to\n * @param config - Configuration for EVM facilitator registration\n * @returns The facilitator instance for chaining\n *\n * @example\n * ```typescript\n * import { registerExactEvmScheme } from \"@x402/evm/exact/facilitator/register\";\n * import { x402Facilitator } from \"@x402/core/facilitator\";\n * import { createPublicClient, createWalletClient } from \"viem\";\n *\n * const facilitator = new x402Facilitator();\n *\n * // Single network\n * registerExactEvmScheme(facilitator, {\n * signer: combinedClient,\n * networks: \"eip155:84532\" // Base Sepolia\n * });\n *\n * // Multiple networks (will auto-derive eip155:* pattern)\n * registerExactEvmScheme(facilitator, {\n * signer: combinedClient,\n * networks: [\"eip155:84532\", \"eip155:1\"] // Base Sepolia and Mainnet\n * });\n * ```\n */\nexport function registerExactEvmScheme(\n facilitator: x402Facilitator,\n config: EvmFacilitatorConfig,\n): x402Facilitator {\n // Register V2 scheme with specified networks\n facilitator.register(\n config.networks,\n new ExactEvmScheme(config.signer, {\n deployERC4337WithEIP6492: config.deployERC4337WithEIP6492,\n simulateInSettle: config.simulateInSettle,\n }),\n );\n\n // Register all V1 networks\n facilitator.registerV1(\n NETWORKS as Network[],\n new ExactEvmSchemeV1(config.signer, {\n deployERC4337WithEIP6492: config.deployERC4337WithEIP6492,\n simulateInSettle: config.simulateInSettle,\n }),\n );\n\n return facilitator;\n}\n"],"mappings":"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","names":["getAddress","getAddress","getAddress","getAddress","getAddress","getAddress","simOk"]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/exact/facilitator/eip3009.ts","../../../../src/exact/facilitator/permit2.ts","../../../../src/exact/facilitator/scheme.ts","../../../../src/exact/facilitator/register.ts"],"sourcesContent":["import {\n PaymentPayload,\n PaymentRequirements,\n SettleResponse,\n VerifyResponse,\n} from \"@x402/core/types\";\nimport { getAddress, Hex, isAddressEqual, parseErc6492Signature } from \"viem\";\nimport { authorizationTypes } from \"../../constants\";\nimport { FacilitatorEvmSigner } from \"../../signer\";\nimport { getEvmChainId } from \"../../utils\";\nimport { ExactEIP3009Payload } from \"../../types\";\nimport * as Errors from \"./errors\";\nimport {\n diagnoseEip3009SimulationFailure,\n executeTransferWithAuthorization,\n simulateEip3009Transfer,\n} from \"./eip3009-utils\";\n\nexport interface VerifyEIP3009Options {\n /** Run onchain simulation. Defaults to true. */\n simulate?: boolean;\n}\n\nexport interface EIP3009FacilitatorConfig {\n /**\n * If enabled, the facilitator will deploy ERC-4337 smart wallets\n * via EIP-6492 when encountering undeployed contract signatures.\n *\n * @default false\n */\n deployERC4337WithEIP6492: boolean;\n /**\n * If enabled, simulates transaction before settling. Defaults to false, ie only simulate during verify.\n *\n * @default false\n */\n simulateInSettle?: boolean;\n}\n\n/**\n * Verifies an EIP-3009 payment payload.\n *\n * @param signer - The facilitator signer for contract reads\n * @param payload - The payment payload to verify\n * @param requirements - The payment requirements\n * @param eip3009Payload - The EIP-3009 specific payload\n * @param options - Optional verification options\n * @returns Promise resolving to verification response\n */\nexport async function verifyEIP3009(\n signer: FacilitatorEvmSigner,\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n eip3009Payload: ExactEIP3009Payload,\n options?: VerifyEIP3009Options,\n): Promise<VerifyResponse> {\n const payer = eip3009Payload.authorization.from;\n let eip6492Deployment:\n | { factoryAddress: `0x${string}`; factoryCalldata: `0x${string}` }\n | undefined;\n\n // Verify scheme matches\n if (payload.accepted.scheme !== \"exact\" || requirements.scheme !== \"exact\") {\n return {\n isValid: false,\n invalidReason: Errors.ErrInvalidScheme,\n payer,\n };\n }\n\n // Get chain configuration\n if (!requirements.extra?.name || !requirements.extra?.version) {\n return {\n isValid: false,\n invalidReason: Errors.ErrMissingEip712Domain,\n payer,\n };\n }\n\n const { name, version } = requirements.extra;\n const erc20Address = getAddress(requirements.asset);\n\n // Verify network matches\n if (payload.accepted.network !== requirements.network) {\n return {\n isValid: false,\n invalidReason: Errors.ErrNetworkMismatch,\n payer,\n };\n }\n\n // Build typed data for signature verification\n const permitTypedData = {\n types: authorizationTypes,\n primaryType: \"TransferWithAuthorization\" as const,\n domain: {\n name,\n version,\n chainId: getEvmChainId(requirements.network),\n verifyingContract: erc20Address,\n },\n message: {\n from: eip3009Payload.authorization.from,\n to: eip3009Payload.authorization.to,\n value: BigInt(eip3009Payload.authorization.value),\n validAfter: BigInt(eip3009Payload.authorization.validAfter),\n validBefore: BigInt(eip3009Payload.authorization.validBefore),\n nonce: eip3009Payload.authorization.nonce,\n },\n };\n\n // Verify signature\n // Note: verifyTypedData is implementation-dependent and pluggable on FacilitatorEvmSigner\n // Some implementations only do EOA-style ECDSA recovery (e.g. viem/utils verifyTypedData, ethers.verifyTypedData)\n // Viem's publicClient.verifyTypedData supports EOA and Smart Contract Account (ERC-1271 / ERC-6492) signature verification\n let isValid = false;\n try {\n isValid = await signer.verifyTypedData({\n address: eip3009Payload.authorization.from,\n ...permitTypedData,\n signature: eip3009Payload.signature!,\n });\n } catch {\n isValid = false;\n }\n const signature = eip3009Payload.signature!;\n const sigLen = signature.startsWith(\"0x\") ? signature.length - 2 : signature.length;\n\n // Extract EIP-6492 deployment info (factory address + calldata) if present\n const erc6492Data = parseErc6492Signature(signature);\n const hasDeploymentInfo =\n erc6492Data.address &&\n erc6492Data.data &&\n !isAddressEqual(erc6492Data.address, \"0x0000000000000000000000000000000000000000\");\n\n if (hasDeploymentInfo) {\n eip6492Deployment = {\n factoryAddress: erc6492Data.address!,\n factoryCalldata: erc6492Data.data!,\n };\n }\n\n if (!isValid) {\n // Check if signature is from a smart wallet\n const isSmartWallet = sigLen > 130; // 65 bytes = 130 hex chars for EOA\n\n // EOA signature that failed verification — definitely invalid\n if (!isSmartWallet) {\n return {\n isValid: false,\n invalidReason: Errors.ErrInvalidSignature,\n payer,\n };\n }\n\n // Smart wallet signature: check if deployed or has ERC-6492 deployment info\n const bytecode = await signer.getCode({ address: payer });\n const isDeployed = bytecode && bytecode !== \"0x\";\n\n if (!isDeployed && !hasDeploymentInfo) {\n // Undeployed smart wallet with no factory info\n return {\n isValid: false,\n invalidReason: Errors.ErrUndeployedSmartWallet,\n payer,\n };\n }\n // Deployed smart wallet or undeployed with ERC-6492 factory info\n // fall through to remaining field checks and onchain simulation\n }\n\n // Verify payment recipient matches\n if (getAddress(eip3009Payload.authorization.to) !== getAddress(requirements.payTo)) {\n return {\n isValid: false,\n invalidReason: Errors.ErrRecipientMismatch,\n payer,\n };\n }\n\n // Verify validBefore is in the future (with 6 second buffer for block time)\n const now = Math.floor(Date.now() / 1000);\n if (BigInt(eip3009Payload.authorization.validBefore) < BigInt(now + 6)) {\n return {\n isValid: false,\n invalidReason: Errors.ErrValidBeforeExpired,\n payer,\n };\n }\n\n // Verify validAfter is not in the future\n if (BigInt(eip3009Payload.authorization.validAfter) > BigInt(now)) {\n return {\n isValid: false,\n invalidReason: Errors.ErrValidAfterInFuture,\n payer,\n };\n }\n\n // Verify amount exactly matches requirements\n if (BigInt(eip3009Payload.authorization.value) !== BigInt(requirements.amount)) {\n return {\n isValid: false,\n invalidReason: Errors.ErrInvalidAuthorizationValue,\n payer,\n };\n }\n\n // Transaction simulation\n if (options?.simulate !== false) {\n const simulationSucceeded = await simulateEip3009Transfer(\n signer,\n erc20Address,\n eip3009Payload,\n eip6492Deployment,\n );\n if (!simulationSucceeded) {\n return diagnoseEip3009SimulationFailure(\n signer,\n erc20Address,\n eip3009Payload,\n requirements,\n requirements.amount,\n );\n }\n }\n\n return {\n isValid: true,\n invalidReason: undefined,\n payer,\n };\n}\n\n/**\n * Settles an EIP-3009 payment by executing transferWithAuthorization.\n *\n * @param signer - The facilitator signer for contract writes\n * @param payload - The payment payload to settle\n * @param requirements - The payment requirements\n * @param eip3009Payload - The EIP-3009 specific payload\n * @param config - Facilitator configuration\n * @returns Promise resolving to settlement response\n */\nexport async function settleEIP3009(\n signer: FacilitatorEvmSigner,\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n eip3009Payload: ExactEIP3009Payload,\n config: EIP3009FacilitatorConfig,\n): Promise<SettleResponse> {\n const payer = eip3009Payload.authorization.from;\n\n // Re-verify before settling\n const valid = await verifyEIP3009(signer, payload, requirements, eip3009Payload, {\n simulate: config.simulateInSettle ?? false,\n });\n if (!valid.isValid) {\n return {\n success: false,\n network: payload.accepted.network,\n transaction: \"\",\n errorReason: valid.invalidReason ?? Errors.ErrInvalidScheme,\n payer,\n };\n }\n\n try {\n // Parse ERC-6492 signature if applicable (for optional deployment)\n const { address: factoryAddress, data: factoryCalldata } = parseErc6492Signature(\n eip3009Payload.signature!,\n );\n\n // Deploy ERC-4337 smart wallet via EIP-6492 if configured and needed\n if (\n config.deployERC4337WithEIP6492 &&\n factoryAddress &&\n factoryCalldata &&\n !isAddressEqual(factoryAddress, \"0x0000000000000000000000000000000000000000\")\n ) {\n // Check if smart wallet is already deployed\n const bytecode = await signer.getCode({ address: payer });\n\n if (!bytecode || bytecode === \"0x\") {\n // Wallet not deployed - attempt deployment\n const deployTx = await signer.sendTransaction({\n to: factoryAddress as Hex,\n data: factoryCalldata as Hex,\n });\n\n // Wait for deployment transaction\n await signer.waitForTransactionReceipt({ hash: deployTx });\n }\n }\n\n const tx = await executeTransferWithAuthorization(\n signer,\n getAddress(requirements.asset),\n eip3009Payload,\n );\n\n // Wait for transaction confirmation\n const receipt = await signer.waitForTransactionReceipt({ hash: tx });\n\n if (receipt.status !== \"success\") {\n return {\n success: false,\n errorReason: Errors.ErrTransactionFailed,\n transaction: tx,\n network: payload.accepted.network,\n payer,\n };\n }\n\n return {\n success: true,\n transaction: tx,\n network: payload.accepted.network,\n payer,\n };\n } catch {\n return {\n success: false,\n errorReason: Errors.ErrTransactionFailed,\n transaction: \"\",\n network: payload.accepted.network,\n payer,\n };\n }\n}\n","import {\n PaymentPayload,\n PaymentRequirements,\n FacilitatorContext,\n SettleResponse,\n VerifyResponse,\n} from \"@x402/core/types\";\nimport {\n extractEip2612GasSponsoringInfo,\n extractErc20ApprovalGasSponsoringInfo,\n ERC20_APPROVAL_GAS_SPONSORING_KEY,\n resolveErc20ApprovalExtensionSigner,\n type Eip2612GasSponsoringInfo,\n type Erc20ApprovalGasSponsoringFacilitatorExtension,\n type Erc20ApprovalGasSponsoringSigner,\n} from \"../extensions\";\nimport { getAddress, encodeFunctionData } from \"viem\";\nimport {\n PERMIT2_ADDRESS,\n permit2WitnessTypes,\n x402ExactPermit2ProxyABI,\n x402ExactPermit2ProxyAddress,\n} from \"../../constants\";\nimport * as Errors from \"./errors\";\nimport { FacilitatorEvmSigner } from \"../../signer\";\nimport { ExactPermit2Payload } from \"../../types\";\nimport { getEvmChainId } from \"../../utils\";\nimport { validateErc20ApprovalForPayment } from \"./erc20approval\";\nimport {\n simulatePermit2Settle,\n simulatePermit2SettleWithPermit,\n simulatePermit2SettleWithErc20Approval,\n diagnosePermit2SimulationFailure,\n checkPermit2Prerequisites,\n validateEip2612PermitForPayment,\n buildExactPermit2SettleArgs,\n splitEip2612Signature,\n waitAndReturnSettleResponse,\n mapSettleError,\n type Permit2ProxyConfig,\n} from \"../../shared/permit2\";\n\nconst exactProxyConfig: Permit2ProxyConfig = {\n proxyAddress: x402ExactPermit2ProxyAddress,\n proxyABI: x402ExactPermit2ProxyABI,\n};\n\nexport interface VerifyPermit2Options {\n /** Run onchain simulation. Defaults to true. */\n simulate?: boolean;\n}\n\nexport interface Permit2FacilitatorConfig {\n /**\n * If enabled, simulates transaction before settling. Defaults to false,\n * i.e. only simulate during verify.\n *\n * @default false\n */\n simulateInSettle?: boolean;\n}\n\n/**\n * Verifies a Permit2 payment payload.\n *\n * Handles all Permit2 verification paths:\n * - Standard: checks on-chain Permit2 allowance\n * - EIP-2612: validates the EIP-2612 permit extension when allowance is insufficient\n * - ERC-20 approval: validates the pre-signed approve tx extension when allowance is insufficient\n *\n * @param signer - The facilitator signer for contract reads\n * @param payload - The payment payload to verify\n * @param requirements - The payment requirements\n * @param permit2Payload - The Permit2 specific payload\n * @param context - Optional facilitator context for extension-provided capabilities\n * @param options - Optional verification options (e.g. simulate)\n * @returns Promise resolving to verification response\n */\nexport async function verifyPermit2(\n signer: FacilitatorEvmSigner,\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n permit2Payload: ExactPermit2Payload,\n context?: FacilitatorContext,\n options?: VerifyPermit2Options,\n): Promise<VerifyResponse> {\n const payer = permit2Payload.permit2Authorization.from;\n\n if (payload.accepted.scheme !== \"exact\" || requirements.scheme !== \"exact\") {\n return {\n isValid: false,\n invalidReason: Errors.ErrUnsupportedPayloadType,\n payer,\n };\n }\n\n if (payload.accepted.network !== requirements.network) {\n return {\n isValid: false,\n invalidReason: Errors.ErrNetworkMismatch,\n payer,\n };\n }\n\n const chainId = getEvmChainId(requirements.network);\n const tokenAddress = getAddress(requirements.asset);\n\n if (\n getAddress(permit2Payload.permit2Authorization.spender) !==\n getAddress(x402ExactPermit2ProxyAddress)\n ) {\n return {\n isValid: false,\n invalidReason: Errors.ErrPermit2InvalidSpender,\n payer,\n };\n }\n\n if (\n getAddress(permit2Payload.permit2Authorization.witness.to) !== getAddress(requirements.payTo)\n ) {\n return {\n isValid: false,\n invalidReason: Errors.ErrPermit2RecipientMismatch,\n payer,\n };\n }\n\n const now = Math.floor(Date.now() / 1000);\n if (BigInt(permit2Payload.permit2Authorization.deadline) < BigInt(now + 6)) {\n return {\n isValid: false,\n invalidReason: Errors.ErrPermit2DeadlineExpired,\n payer,\n };\n }\n\n if (BigInt(permit2Payload.permit2Authorization.witness.validAfter) > BigInt(now)) {\n return {\n isValid: false,\n invalidReason: Errors.ErrPermit2NotYetValid,\n payer,\n };\n }\n\n // Verify amount exactly matches requirements\n if (\n BigInt(permit2Payload.permit2Authorization.permitted.amount) !== BigInt(requirements.amount)\n ) {\n return {\n isValid: false,\n invalidReason: Errors.ErrPermit2AmountMismatch,\n payer,\n };\n }\n\n if (getAddress(permit2Payload.permit2Authorization.permitted.token) !== tokenAddress) {\n return {\n isValid: false,\n invalidReason: Errors.ErrPermit2TokenMismatch,\n payer,\n };\n }\n\n const permit2TypedData = {\n types: permit2WitnessTypes,\n primaryType: \"PermitWitnessTransferFrom\" as const,\n domain: {\n name: \"Permit2\",\n chainId,\n verifyingContract: PERMIT2_ADDRESS,\n },\n message: {\n permitted: {\n token: getAddress(permit2Payload.permit2Authorization.permitted.token),\n amount: BigInt(permit2Payload.permit2Authorization.permitted.amount),\n },\n spender: getAddress(permit2Payload.permit2Authorization.spender),\n nonce: BigInt(permit2Payload.permit2Authorization.nonce),\n deadline: BigInt(permit2Payload.permit2Authorization.deadline),\n witness: {\n to: getAddress(permit2Payload.permit2Authorization.witness.to),\n validAfter: BigInt(permit2Payload.permit2Authorization.witness.validAfter),\n },\n },\n };\n\n // Verify signature\n // Note: verifyTypedData is implementation-dependent and pluggable on FacilitatorEvmSigner\n // Some implementations only do EOA-style ECDSA recovery (e.g. viem/utils verifyTypedData, ethers.verifyTypedData)\n // Viem's publicClient.verifyTypedData supports EOA and Smart Contract Account (ERC-1271 / ERC-6492) signature verification\n let signatureValid = false;\n try {\n signatureValid = await signer.verifyTypedData({\n address: payer,\n ...permit2TypedData,\n signature: permit2Payload.signature,\n });\n } catch {\n signatureValid = false;\n }\n\n if (!signatureValid) {\n // Check if the payer is a deployed smart contract\n const bytecode = await signer.getCode({ address: payer });\n const isDeployedContract = bytecode && bytecode !== \"0x\";\n\n if (!isDeployedContract) {\n return {\n isValid: false,\n invalidReason: Errors.ErrPermit2InvalidSignature,\n payer,\n };\n }\n // Deployed smart contract: fall through to simulation\n }\n\n // If simulation is disabled, return early\n if (options?.simulate === false) {\n return { isValid: true, invalidReason: undefined, payer };\n }\n\n // Branch: EIP-2612 gas sponsoring (atomic settleWithPermit via contract)\n const eip2612Info = extractEip2612GasSponsoringInfo(payload);\n if (eip2612Info) {\n const fieldResult = validateEip2612PermitForPayment(eip2612Info, payer, tokenAddress);\n if (!fieldResult.isValid) {\n return { isValid: false, invalidReason: fieldResult.invalidReason!, payer };\n }\n\n const exactSettleArgs = buildExactPermit2SettleArgs(permit2Payload);\n const simOk = await simulatePermit2SettleWithPermit(\n exactProxyConfig,\n signer,\n exactSettleArgs,\n eip2612Info,\n );\n if (!simOk) {\n return diagnosePermit2SimulationFailure(\n exactProxyConfig,\n signer,\n tokenAddress,\n permit2Payload,\n requirements.amount,\n );\n }\n\n return { isValid: true, invalidReason: undefined, payer };\n }\n\n // Branch: ERC-20 approval gas sponsoring (broadcast approval + settle via extension signer)\n const erc20GasSponsorshipExtension =\n context?.getExtension<Erc20ApprovalGasSponsoringFacilitatorExtension>(\n ERC20_APPROVAL_GAS_SPONSORING_KEY,\n );\n if (erc20GasSponsorshipExtension) {\n const erc20Info = extractErc20ApprovalGasSponsoringInfo(payload);\n if (erc20Info) {\n const fieldResult = await validateErc20ApprovalForPayment(erc20Info, payer, tokenAddress);\n if (!fieldResult.isValid) {\n return { isValid: false, invalidReason: fieldResult.invalidReason!, payer };\n }\n\n const extensionSigner = resolveErc20ApprovalExtensionSigner(\n erc20GasSponsorshipExtension,\n requirements.network,\n );\n\n if (extensionSigner?.simulateTransactions) {\n const simOk = await simulatePermit2SettleWithErc20Approval(\n exactProxyConfig,\n extensionSigner,\n buildExactPermit2SettleArgs(permit2Payload),\n erc20Info,\n );\n if (!simOk) {\n return diagnosePermit2SimulationFailure(\n exactProxyConfig,\n signer,\n tokenAddress,\n permit2Payload,\n requirements.amount,\n );\n }\n return { isValid: true, invalidReason: undefined, payer };\n }\n\n // Fallback to prerequisite-only check if simulateTransactions is not available\n return checkPermit2Prerequisites(\n exactProxyConfig,\n signer,\n tokenAddress,\n payer,\n requirements.amount,\n );\n }\n }\n\n // Branch: standard settle (allowance already on-chain)\n const simOk = await simulatePermit2Settle(\n exactProxyConfig,\n signer,\n buildExactPermit2SettleArgs(permit2Payload),\n );\n if (!simOk) {\n return diagnosePermit2SimulationFailure(\n exactProxyConfig,\n signer,\n tokenAddress,\n permit2Payload,\n requirements.amount,\n );\n }\n\n return { isValid: true, invalidReason: undefined, payer };\n}\n\n/**\n * Settles a Permit2 payment. Single entry point for all Permit2 settlement paths:\n *\n * 1. EIP-2612 extension present -> settleWithPermit (atomic single tx via contract)\n * 2. ERC-20 approval extension present + extension signer -> broadcast approval + settle (via extension signer)\n * 3. Standard -> settle directly (allowance already on-chain)\n *\n * @param signer - The base facilitator signer for contract writes\n * @param payload - The payment payload to settle\n * @param requirements - The payment requirements\n * @param permit2Payload - The Permit2 specific payload\n * @param context - Optional facilitator context for extension-provided capabilities\n * @param config - Optional facilitator config (simulateInSettle)\n * @returns Promise resolving to settlement response\n */\nexport async function settlePermit2(\n signer: FacilitatorEvmSigner,\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n permit2Payload: ExactPermit2Payload,\n context?: FacilitatorContext,\n config?: Permit2FacilitatorConfig,\n): Promise<SettleResponse> {\n const payer = permit2Payload.permit2Authorization.from;\n\n const valid = await verifyPermit2(signer, payload, requirements, permit2Payload, context, {\n simulate: config?.simulateInSettle ?? false,\n });\n if (!valid.isValid) {\n return {\n success: false,\n network: payload.accepted.network,\n transaction: \"\",\n errorReason: valid.invalidReason ?? Errors.ErrInvalidScheme,\n payer,\n };\n }\n\n // Branch: EIP-2612 gas sponsoring (atomic settleWithPermit via contract)\n const eip2612Info = extractEip2612GasSponsoringInfo(payload);\n if (eip2612Info) {\n return settlePermit2WithEIP2612(exactProxyConfig, signer, payload, permit2Payload, eip2612Info);\n }\n\n // Branch: ERC-20 approval gas sponsoring (broadcast approval + settle via extension signer)\n const erc20Info = extractErc20ApprovalGasSponsoringInfo(payload);\n if (erc20Info) {\n const erc20GasSponsorshipExtension =\n context?.getExtension<Erc20ApprovalGasSponsoringFacilitatorExtension>(\n ERC20_APPROVAL_GAS_SPONSORING_KEY,\n );\n const extensionSigner = resolveErc20ApprovalExtensionSigner(\n erc20GasSponsorshipExtension,\n payload.accepted.network,\n );\n if (extensionSigner) {\n return settlePermit2WithERC20Approval(\n exactProxyConfig,\n extensionSigner,\n payload,\n permit2Payload,\n erc20Info,\n );\n }\n }\n\n // Branch: standard settle (allowance already on-chain)\n return settlePermit2Direct(exactProxyConfig, signer, payload, permit2Payload);\n}\n\n// ---------------------------------------------------------------------------\n// Exact-only settle helpers (not shared — upto has its own implementations)\n// ---------------------------------------------------------------------------\n\n/**\n * Settles a Permit2 payment via settleWithPermit, including the EIP-2612 permit atomically.\n *\n * @param config - The proxy contract configuration (address and ABI)\n * @param signer - The facilitator signer for contract writes\n * @param payload - The payment payload for network info\n * @param permit2Payload - The Permit2 payload with authorization and signature\n * @param eip2612Info - The EIP-2612 gas sponsoring info from the payload extension\n * @returns Promise resolving to a settlement response\n */\nasync function settlePermit2WithEIP2612(\n config: Permit2ProxyConfig,\n signer: FacilitatorEvmSigner,\n payload: PaymentPayload,\n permit2Payload: ExactPermit2Payload,\n eip2612Info: Eip2612GasSponsoringInfo,\n): Promise<SettleResponse> {\n const payer = permit2Payload.permit2Authorization.from;\n try {\n const { v, r, s } = splitEip2612Signature(eip2612Info.signature);\n\n const tx = await signer.writeContract({\n address: config.proxyAddress,\n abi: config.proxyABI,\n functionName: \"settleWithPermit\",\n args: [\n {\n value: BigInt(eip2612Info.amount),\n deadline: BigInt(eip2612Info.deadline),\n r,\n s,\n v,\n },\n ...buildExactPermit2SettleArgs(permit2Payload),\n ],\n });\n\n return waitAndReturnSettleResponse(signer, tx, payload, payer);\n } catch (error) {\n return mapSettleError(error, payload, payer);\n }\n}\n\n/**\n * Settles a Permit2 payment using an ERC-20 approval gas sponsoring extension.\n *\n * @param config - The proxy contract configuration (address and ABI)\n * @param extensionSigner - The extension signer with sendTransactions capability\n * @param payload - The payment payload for network info\n * @param permit2Payload - The Permit2 payload with authorization and signature\n * @param erc20Info - Object containing the signed approval transaction\n * @param erc20Info.signedTransaction - The RLP-encoded signed ERC-20 approve transaction\n * @returns Promise resolving to a settlement response\n */\nasync function settlePermit2WithERC20Approval(\n config: Permit2ProxyConfig,\n extensionSigner: Erc20ApprovalGasSponsoringSigner,\n payload: PaymentPayload,\n permit2Payload: ExactPermit2Payload,\n erc20Info: { signedTransaction: string },\n): Promise<SettleResponse> {\n const payer = permit2Payload.permit2Authorization.from;\n\n try {\n const settleData = encodeFunctionData({\n abi: config.proxyABI,\n functionName: \"settle\",\n args: buildExactPermit2SettleArgs(permit2Payload),\n });\n\n const txHashes = await extensionSigner.sendTransactions([\n erc20Info.signedTransaction as `0x${string}`,\n { to: config.proxyAddress, data: settleData, gas: BigInt(300_000) },\n ]);\n\n const settleTxHash = txHashes[txHashes.length - 1];\n return waitAndReturnSettleResponse(extensionSigner, settleTxHash, payload, payer);\n } catch (error) {\n return mapSettleError(error, payload, payer);\n }\n}\n\n/**\n * Settles a Permit2 payment directly when Permit2 allowance is already on-chain.\n *\n * @param config - The proxy contract configuration (address and ABI)\n * @param signer - The facilitator signer for contract writes\n * @param payload - The payment payload for network info\n * @param permit2Payload - The Permit2 payload with authorization and signature\n * @returns Promise resolving to a settlement response\n */\nasync function settlePermit2Direct(\n config: Permit2ProxyConfig,\n signer: FacilitatorEvmSigner,\n payload: PaymentPayload,\n permit2Payload: ExactPermit2Payload,\n): Promise<SettleResponse> {\n const payer = permit2Payload.permit2Authorization.from;\n try {\n const tx = await signer.writeContract({\n address: config.proxyAddress,\n abi: config.proxyABI,\n functionName: \"settle\",\n args: buildExactPermit2SettleArgs(permit2Payload),\n });\n\n return waitAndReturnSettleResponse(signer, tx, payload, payer);\n } catch (error) {\n return mapSettleError(error, payload, payer);\n }\n}\n","import {\n PaymentPayload,\n PaymentRequirements,\n SchemeNetworkFacilitator,\n FacilitatorContext,\n SettleResponse,\n VerifyResponse,\n} from \"@x402/core/types\";\nimport { FacilitatorEvmSigner } from \"../../signer\";\nimport { ExactEvmPayloadV2, ExactEIP3009Payload, isPermit2Payload } from \"../../types\";\nimport { verifyEIP3009, settleEIP3009 } from \"./eip3009\";\nimport { verifyPermit2, settlePermit2 } from \"./permit2\";\n\nexport interface ExactEvmSchemeConfig {\n /**\n * If enabled, the facilitator will deploy ERC-4337 smart wallets\n * via EIP-6492 when encountering undeployed contract signatures.\n *\n * @default false\n */\n deployERC4337WithEIP6492?: boolean;\n /**\n * If enabled, run on-chain simulation during settle's re-verify.\n *\n * @default false\n */\n simulateInSettle?: boolean;\n}\n\n/**\n * EVM facilitator implementation for the Exact payment scheme.\n * Thin router that delegates to EIP-3009 or Permit2 based on payload type.\n * All extension handling (EIP-2612, ERC-20 approval gas sponsoring) is owned\n * by the Permit2 functions via FacilitatorContext.\n */\nexport class ExactEvmScheme implements SchemeNetworkFacilitator {\n readonly scheme = \"exact\";\n readonly caipFamily = \"eip155:*\";\n private readonly config: Required<ExactEvmSchemeConfig>;\n\n /**\n * Creates a new ExactEvmScheme facilitator instance.\n *\n * @param signer - The EVM signer for facilitator operations\n * @param config - Optional configuration\n */\n constructor(\n private readonly signer: FacilitatorEvmSigner,\n config?: ExactEvmSchemeConfig,\n ) {\n this.config = {\n deployERC4337WithEIP6492: config?.deployERC4337WithEIP6492 ?? false,\n simulateInSettle: config?.simulateInSettle ?? false,\n };\n }\n\n /**\n * Returns undefined — EVM has no mechanism-specific extra data.\n *\n * @param _ - The network identifier (unused)\n * @returns undefined\n */\n getExtra(_: string): Record<string, unknown> | undefined {\n return undefined;\n }\n\n /**\n * Returns facilitator wallet addresses for the supported response.\n *\n * @param _ - The network identifier (unused, addresses are network-agnostic)\n * @returns Array of facilitator wallet addresses\n */\n getSigners(_: string): string[] {\n return [...this.signer.getAddresses()];\n }\n\n /**\n * Verifies a payment payload. Routes to Permit2 or EIP-3009 based on payload type.\n *\n * @param payload - The payment payload to verify\n * @param requirements - The payment requirements\n * @param context - Optional facilitator context for extension capabilities\n * @returns Promise resolving to verification response\n */\n async verify(\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n context?: FacilitatorContext,\n ): Promise<VerifyResponse> {\n const rawPayload = payload.payload as ExactEvmPayloadV2;\n const isPermit2 = isPermit2Payload(rawPayload);\n\n if (isPermit2) {\n return verifyPermit2(this.signer, payload, requirements, rawPayload, context);\n }\n\n const eip3009Payload: ExactEIP3009Payload = rawPayload;\n return verifyEIP3009(this.signer, payload, requirements, eip3009Payload);\n }\n\n /**\n * Settles a payment. Routes to Permit2 or EIP-3009 based on payload type.\n *\n * @param payload - The payment payload to settle\n * @param requirements - The payment requirements\n * @param context - Optional facilitator context for extension capabilities\n * @returns Promise resolving to settlement response\n */\n async settle(\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n context?: FacilitatorContext,\n ): Promise<SettleResponse> {\n const rawPayload = payload.payload as ExactEvmPayloadV2;\n const isPermit2 = isPermit2Payload(rawPayload);\n\n if (isPermit2) {\n return settlePermit2(this.signer, payload, requirements, rawPayload, context, {\n simulateInSettle: this.config.simulateInSettle,\n });\n }\n\n const eip3009Payload: ExactEIP3009Payload = rawPayload;\n return settleEIP3009(this.signer, payload, requirements, eip3009Payload, this.config);\n }\n}\n","import { x402Facilitator } from \"@x402/core/facilitator\";\nimport { Network } from \"@x402/core/types\";\nimport { FacilitatorEvmSigner } from \"../../signer\";\nimport { ExactEvmScheme } from \"./scheme\";\nimport { ExactEvmSchemeV1 } from \"../v1/facilitator/scheme\";\nimport { NETWORKS } from \"../../v1\";\n\n/**\n * Configuration options for registering EVM schemes to an x402Facilitator\n */\nexport interface EvmFacilitatorConfig {\n /**\n * The EVM signer for facilitator operations (verify and settle)\n */\n signer: FacilitatorEvmSigner;\n\n /**\n * Networks to register (single network or array of networks)\n * Examples: \"eip155:84532\", [\"eip155:84532\", \"eip155:1\"]\n */\n networks: Network | Network[];\n\n /**\n * If enabled, the facilitator will deploy ERC-4337 smart wallets\n * via EIP-6492 when encountering undeployed contract signatures.\n *\n * @default false\n */\n deployERC4337WithEIP6492?: boolean;\n\n /**\n * If enabled, reruns on-chain simulation during settle's re-verify.\n *\n * @default false\n */\n simulateInSettle?: boolean;\n}\n\n/**\n * Registers EVM exact payment schemes to an x402Facilitator instance.\n *\n * This function registers:\n * - V2: Specified networks with ExactEvmScheme\n * - V1: All supported EVM networks with ExactEvmSchemeV1\n *\n * @param facilitator - The x402Facilitator instance to register schemes to\n * @param config - Configuration for EVM facilitator registration\n * @returns The facilitator instance for chaining\n *\n * @example\n * ```typescript\n * import { registerExactEvmScheme } from \"@x402/evm/exact/facilitator/register\";\n * import { x402Facilitator } from \"@x402/core/facilitator\";\n * import { createPublicClient, createWalletClient } from \"viem\";\n *\n * const facilitator = new x402Facilitator();\n *\n * // Single network\n * registerExactEvmScheme(facilitator, {\n * signer: combinedClient,\n * networks: \"eip155:84532\" // Base Sepolia\n * });\n *\n * // Multiple networks (will auto-derive eip155:* pattern)\n * registerExactEvmScheme(facilitator, {\n * signer: combinedClient,\n * networks: [\"eip155:84532\", \"eip155:1\"] // Base Sepolia and Mainnet\n * });\n * ```\n */\nexport function registerExactEvmScheme(\n facilitator: x402Facilitator,\n config: EvmFacilitatorConfig,\n): x402Facilitator {\n // Register V2 scheme with specified networks\n facilitator.register(\n config.networks,\n new ExactEvmScheme(config.signer, {\n deployERC4337WithEIP6492: config.deployERC4337WithEIP6492,\n simulateInSettle: config.simulateInSettle,\n }),\n );\n\n // Register all V1 networks\n facilitator.registerV1(\n NETWORKS as Network[],\n new ExactEvmSchemeV1(config.signer, {\n deployERC4337WithEIP6492: config.deployERC4337WithEIP6492,\n simulateInSettle: config.simulateInSettle,\n }),\n );\n\n return facilitator;\n}\n"],"mappings":"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","names":["getAddress","getAddress","simOk"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SchemeNetworkServer, MoneyParser,
|
|
1
|
+
import { SchemeNetworkServer, MoneyParser, Network, Price, AssetAmount, PaymentRequirements } from '@x402/core/types';
|
|
2
2
|
import { x402ResourceServer } from '@x402/core/server';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -28,6 +28,15 @@ declare class ExactEvmScheme implements SchemeNetworkServer {
|
|
|
28
28
|
* });
|
|
29
29
|
*/
|
|
30
30
|
registerMoneyParser(parser: MoneyParser): ExactEvmScheme;
|
|
31
|
+
/**
|
|
32
|
+
* Returns the decimal precision of the default stablecoin for the given network.
|
|
33
|
+
* Implements the optional AssetDecimalsProvider interface used by resolveSettlementOverrideAmount.
|
|
34
|
+
*
|
|
35
|
+
* @param _asset - The asset symbol (unused; defaults to the network's default stablecoin)
|
|
36
|
+
* @param network - The network to look up the default asset for
|
|
37
|
+
* @returns The number of decimal places for the asset
|
|
38
|
+
*/
|
|
39
|
+
getAssetDecimals(_asset: string, network: Network): number;
|
|
31
40
|
/**
|
|
32
41
|
* Parses a price into an asset amount.
|
|
33
42
|
* If price is already an AssetAmount, returns it directly.
|
|
@@ -66,29 +75,21 @@ declare class ExactEvmScheme implements SchemeNetworkServer {
|
|
|
66
75
|
*/
|
|
67
76
|
private parseMoneyToDecimal;
|
|
68
77
|
/**
|
|
69
|
-
*
|
|
70
|
-
* Converts decimal amount to the default stablecoin on the specified network.
|
|
78
|
+
* Converts a numeric dollar amount to an AssetAmount using the default token for the network.
|
|
71
79
|
*
|
|
72
|
-
* @param amount - The
|
|
73
|
-
* @param network - The network
|
|
74
|
-
* @returns The
|
|
80
|
+
* @param amount - The dollar amount as a number
|
|
81
|
+
* @param network - The target network
|
|
82
|
+
* @returns The converted asset amount with token metadata
|
|
75
83
|
*/
|
|
76
84
|
private defaultMoneyConversion;
|
|
77
85
|
/**
|
|
78
|
-
*
|
|
86
|
+
* Converts a decimal string amount to an integer token amount using the given decimals.
|
|
79
87
|
*
|
|
80
|
-
* @param decimalAmount - The decimal
|
|
81
|
-
* @param decimals - The number of
|
|
82
|
-
* @returns The token amount as
|
|
88
|
+
* @param decimalAmount - The amount as a decimal string (e.g. "1.5")
|
|
89
|
+
* @param decimals - The number of decimal places for the token
|
|
90
|
+
* @returns The token amount as an integer string in smallest units
|
|
83
91
|
*/
|
|
84
92
|
private convertToTokenAmount;
|
|
85
|
-
/**
|
|
86
|
-
* Get the default asset info for a network (typically USDC)
|
|
87
|
-
*
|
|
88
|
-
* @param network - The network to get asset info for
|
|
89
|
-
* @returns The asset information including address, name, version, and decimals
|
|
90
|
-
*/
|
|
91
|
-
private getDefaultAsset;
|
|
92
93
|
}
|
|
93
94
|
|
|
94
95
|
/**
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getDefaultAsset
|
|
3
|
+
} from "../../chunk-NSFLAANF.mjs";
|
|
4
|
+
|
|
1
5
|
// src/exact/server/scheme.ts
|
|
2
6
|
var ExactEvmScheme = class {
|
|
3
7
|
constructor() {
|
|
@@ -28,6 +32,21 @@ var ExactEvmScheme = class {
|
|
|
28
32
|
this.moneyParsers.push(parser);
|
|
29
33
|
return this;
|
|
30
34
|
}
|
|
35
|
+
/**
|
|
36
|
+
* Returns the decimal precision of the default stablecoin for the given network.
|
|
37
|
+
* Implements the optional AssetDecimalsProvider interface used by resolveSettlementOverrideAmount.
|
|
38
|
+
*
|
|
39
|
+
* @param _asset - The asset symbol (unused; defaults to the network's default stablecoin)
|
|
40
|
+
* @param network - The network to look up the default asset for
|
|
41
|
+
* @returns The number of decimal places for the asset
|
|
42
|
+
*/
|
|
43
|
+
getAssetDecimals(_asset, network) {
|
|
44
|
+
try {
|
|
45
|
+
return getDefaultAsset(network).decimals;
|
|
46
|
+
} catch {
|
|
47
|
+
return 6;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
31
50
|
/**
|
|
32
51
|
* Parses a price into an asset amount.
|
|
33
52
|
* If price is already an AssetAmount, returns it directly.
|
|
@@ -94,15 +113,14 @@ var ExactEvmScheme = class {
|
|
|
94
113
|
return amount;
|
|
95
114
|
}
|
|
96
115
|
/**
|
|
97
|
-
*
|
|
98
|
-
* Converts decimal amount to the default stablecoin on the specified network.
|
|
116
|
+
* Converts a numeric dollar amount to an AssetAmount using the default token for the network.
|
|
99
117
|
*
|
|
100
|
-
* @param amount - The
|
|
101
|
-
* @param network - The network
|
|
102
|
-
* @returns The
|
|
118
|
+
* @param amount - The dollar amount as a number
|
|
119
|
+
* @param network - The target network
|
|
120
|
+
* @returns The converted asset amount with token metadata
|
|
103
121
|
*/
|
|
104
122
|
defaultMoneyConversion(amount, network) {
|
|
105
|
-
const assetInfo =
|
|
123
|
+
const assetInfo = getDefaultAsset(network);
|
|
106
124
|
const tokenAmount = this.convertToTokenAmount(amount.toString(), assetInfo.decimals);
|
|
107
125
|
const includeEip712Domain = !assetInfo.assetTransferMethod || assetInfo.supportsEip2612;
|
|
108
126
|
return {
|
|
@@ -120,11 +138,11 @@ var ExactEvmScheme = class {
|
|
|
120
138
|
};
|
|
121
139
|
}
|
|
122
140
|
/**
|
|
123
|
-
*
|
|
141
|
+
* Converts a decimal string amount to an integer token amount using the given decimals.
|
|
124
142
|
*
|
|
125
|
-
* @param decimalAmount - The decimal
|
|
126
|
-
* @param decimals - The number of
|
|
127
|
-
* @returns The token amount as
|
|
143
|
+
* @param decimalAmount - The amount as a decimal string (e.g. "1.5")
|
|
144
|
+
* @param decimals - The number of decimal places for the token
|
|
145
|
+
* @returns The token amount as an integer string in smallest units
|
|
128
146
|
*/
|
|
129
147
|
convertToTokenAmount(decimalAmount, decimals) {
|
|
130
148
|
const amount = parseFloat(decimalAmount);
|
|
@@ -136,51 +154,6 @@ var ExactEvmScheme = class {
|
|
|
136
154
|
const tokenAmount = (intPart + paddedDec).replace(/^0+/, "") || "0";
|
|
137
155
|
return tokenAmount;
|
|
138
156
|
}
|
|
139
|
-
/**
|
|
140
|
-
* Get the default asset info for a network (typically USDC)
|
|
141
|
-
*
|
|
142
|
-
* @param network - The network to get asset info for
|
|
143
|
-
* @returns The asset information including address, name, version, and decimals
|
|
144
|
-
*/
|
|
145
|
-
getDefaultAsset(network) {
|
|
146
|
-
const stablecoins = {
|
|
147
|
-
"eip155:8453": {
|
|
148
|
-
address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
|
149
|
-
name: "USD Coin",
|
|
150
|
-
version: "2",
|
|
151
|
-
decimals: 6
|
|
152
|
-
},
|
|
153
|
-
// Base mainnet USDC
|
|
154
|
-
"eip155:84532": {
|
|
155
|
-
address: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
|
|
156
|
-
name: "USDC",
|
|
157
|
-
version: "2",
|
|
158
|
-
decimals: 6
|
|
159
|
-
},
|
|
160
|
-
// Base Sepolia USDC
|
|
161
|
-
"eip155:4326": {
|
|
162
|
-
address: "0xFAfDdbb3FC7688494971a79cc65DCa3EF82079E7",
|
|
163
|
-
name: "MegaUSD",
|
|
164
|
-
version: "1",
|
|
165
|
-
decimals: 18,
|
|
166
|
-
assetTransferMethod: "permit2",
|
|
167
|
-
supportsEip2612: true
|
|
168
|
-
},
|
|
169
|
-
// MegaETH mainnet MegaUSD (no EIP-3009, supports EIP-2612)
|
|
170
|
-
"eip155:143": {
|
|
171
|
-
address: "0x754704Bc059F8C67012fEd69BC8A327a5aafb603",
|
|
172
|
-
name: "USD Coin",
|
|
173
|
-
version: "2",
|
|
174
|
-
decimals: 6
|
|
175
|
-
}
|
|
176
|
-
// Monad mainnet USDC
|
|
177
|
-
};
|
|
178
|
-
const assetInfo = stablecoins[network];
|
|
179
|
-
if (!assetInfo) {
|
|
180
|
-
throw new Error(`No default asset configured for network ${network}`);
|
|
181
|
-
}
|
|
182
|
-
return assetInfo;
|
|
183
|
-
}
|
|
184
157
|
};
|
|
185
158
|
|
|
186
159
|
// src/exact/server/register.ts
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/exact/server/scheme.ts","../../../../src/exact/server/register.ts"],"sourcesContent":["import {\n AssetAmount,\n Network,\n PaymentRequirements,\n Price,\n SchemeNetworkServer,\n MoneyParser,\n} from \"@x402/core/types\";\n\n/**\n * EVM server implementation for the Exact payment scheme.\n */\nexport class ExactEvmScheme implements SchemeNetworkServer {\n readonly scheme = \"exact\";\n private moneyParsers: MoneyParser[] = [];\n\n /**\n * Register a custom money parser in the parser chain.\n * Multiple parsers can be registered - they will be tried in registration order.\n * Each parser receives a decimal amount (e.g., 1.50 for $1.50).\n * If a parser returns null, the next parser in the chain will be tried.\n * The default parser is always the final fallback.\n *\n * @param parser - Custom function to convert amount to AssetAmount (or null to skip)\n * @returns The server instance for chaining\n *\n * @example\n * evmServer.registerMoneyParser(async (amount, network) => {\n * // Custom conversion logic\n * if (amount > 100) {\n * // Use different token for large amounts\n * return { amount: (amount * 1e18).toString(), asset: \"0xCustomToken\" };\n * }\n * return null; // Use next parser\n * });\n */\n registerMoneyParser(parser: MoneyParser): ExactEvmScheme {\n this.moneyParsers.push(parser);\n return this;\n }\n\n /**\n * Parses a price into an asset amount.\n * If price is already an AssetAmount, returns it directly.\n * If price is Money (string | number), parses to decimal and tries custom parsers.\n * Falls back to default conversion if all custom parsers return null.\n *\n * @param price - The price to parse\n * @param network - The network to use\n * @returns Promise that resolves to the parsed asset amount\n */\n async parsePrice(price: Price, network: Network): Promise<AssetAmount> {\n // If already an AssetAmount, return it directly\n if (typeof price === \"object\" && price !== null && \"amount\" in price) {\n if (!price.asset) {\n throw new Error(`Asset address must be specified for AssetAmount on network ${network}`);\n }\n return {\n amount: price.amount,\n asset: price.asset,\n extra: price.extra || {},\n };\n }\n\n // Parse Money to decimal number\n const amount = this.parseMoneyToDecimal(price);\n\n // Try each custom money parser in order\n for (const parser of this.moneyParsers) {\n const result = await parser(amount, network);\n if (result !== null) {\n return result;\n }\n }\n\n // All custom parsers returned null, use default conversion\n return this.defaultMoneyConversion(amount, network);\n }\n\n /**\n * Build payment requirements for this scheme/network combination\n *\n * @param paymentRequirements - The base payment requirements\n * @param supportedKind - The supported kind from facilitator (unused)\n * @param supportedKind.x402Version - The x402 version\n * @param supportedKind.scheme - The logical payment scheme\n * @param supportedKind.network - The network identifier in CAIP-2 format\n * @param supportedKind.extra - Optional extra metadata regarding scheme/network implementation details\n * @param extensionKeys - Extension keys supported by the facilitator (unused)\n * @returns Payment requirements ready to be sent to clients\n */\n enhancePaymentRequirements(\n paymentRequirements: PaymentRequirements,\n supportedKind: {\n x402Version: number;\n scheme: string;\n network: Network;\n extra?: Record<string, unknown>;\n },\n extensionKeys: string[],\n ): Promise<PaymentRequirements> {\n // Mark unused parameters to satisfy linter\n void supportedKind;\n void extensionKeys;\n return Promise.resolve(paymentRequirements);\n }\n\n /**\n * Parse Money (string | number) to a decimal number.\n * Handles formats like \"$1.50\", \"1.50\", 1.50, etc.\n *\n * @param money - The money value to parse\n * @returns Decimal number\n */\n private parseMoneyToDecimal(money: string | number): number {\n if (typeof money === \"number\") {\n return money;\n }\n\n // Remove $ sign and whitespace, then parse\n const cleanMoney = money.replace(/^\\$/, \"\").trim();\n const amount = parseFloat(cleanMoney);\n\n if (isNaN(amount)) {\n throw new Error(`Invalid money format: ${money}`);\n }\n\n return amount;\n }\n\n /**\n * Default money conversion implementation.\n * Converts decimal amount to the default stablecoin on the specified network.\n *\n * @param amount - The decimal amount (e.g., 1.50)\n * @param network - The network to use\n * @returns The parsed asset amount in the default stablecoin\n */\n private defaultMoneyConversion(amount: number, network: Network): AssetAmount {\n const assetInfo = this.getDefaultAsset(network);\n const tokenAmount = this.convertToTokenAmount(amount.toString(), assetInfo.decimals);\n\n // EIP-3009 tokens always need name/version for their transferWithAuthorization domain.\n // Permit2 tokens only need them if the token supports EIP-2612 (for gasless permit signing).\n // Omitting name/version for permit2 tokens signals the client to skip EIP-2612 and use\n // ERC-20 approval gas sponsoring instead.\n const includeEip712Domain = !assetInfo.assetTransferMethod || assetInfo.supportsEip2612;\n\n return {\n amount: tokenAmount,\n asset: assetInfo.address,\n extra: {\n ...(includeEip712Domain && {\n name: assetInfo.name,\n version: assetInfo.version,\n }),\n ...(assetInfo.assetTransferMethod && {\n assetTransferMethod: assetInfo.assetTransferMethod,\n }),\n },\n };\n }\n\n /**\n * Convert decimal amount to token units (e.g., 0.10 -> 100000 for 6-decimal tokens)\n *\n * @param decimalAmount - The decimal amount to convert\n * @param decimals - The number of decimals for the token\n * @returns The token amount as a string\n */\n private convertToTokenAmount(decimalAmount: string, decimals: number): string {\n const amount = parseFloat(decimalAmount);\n if (isNaN(amount)) {\n throw new Error(`Invalid amount: ${decimalAmount}`);\n }\n // Convert to smallest unit (e.g., for USDC with 6 decimals: 0.10 * 10^6 = 100000)\n const [intPart, decPart = \"\"] = String(amount).split(\".\");\n const paddedDec = decPart.padEnd(decimals, \"0\").slice(0, decimals);\n const tokenAmount = (intPart + paddedDec).replace(/^0+/, \"\") || \"0\";\n return tokenAmount;\n }\n\n /**\n * Get the default asset info for a network (typically USDC)\n *\n * @param network - The network to get asset info for\n * @returns The asset information including address, name, version, and decimals\n */\n private getDefaultAsset(network: Network): {\n address: string;\n name: string;\n version: string;\n decimals: number;\n assetTransferMethod?: string;\n supportsEip2612?: boolean;\n } {\n // Map of network to stablecoin info including EIP-712 domain parameters.\n // Each network has the right to determine its own default stablecoin that can be expressed as a USD string by calling servers.\n // Tokens that don't support EIP-3009 should set assetTransferMethod: \"permit2\".\n // For permit2 tokens, set supportsEip2612: true if the token implements EIP-2612 permit().\n // When supportsEip2612 is false/absent on a permit2 token, name/version are omitted from\n // extra so the client skips the EIP-2612 path and falls back to ERC-20 approval gas sponsoring.\n const stablecoins: Record<\n string,\n {\n address: string;\n name: string;\n version: string;\n decimals: number;\n assetTransferMethod?: string;\n supportsEip2612?: boolean;\n }\n > = {\n \"eip155:8453\": {\n address: \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\n name: \"USD Coin\",\n version: \"2\",\n decimals: 6,\n }, // Base mainnet USDC\n \"eip155:84532\": {\n address: \"0x036CbD53842c5426634e7929541eC2318f3dCF7e\",\n name: \"USDC\",\n version: \"2\",\n decimals: 6,\n }, // Base Sepolia USDC\n \"eip155:4326\": {\n address: \"0xFAfDdbb3FC7688494971a79cc65DCa3EF82079E7\",\n name: \"MegaUSD\",\n version: \"1\",\n decimals: 18,\n assetTransferMethod: \"permit2\",\n supportsEip2612: true,\n }, // MegaETH mainnet MegaUSD (no EIP-3009, supports EIP-2612)\n \"eip155:143\": {\n address: \"0x754704Bc059F8C67012fEd69BC8A327a5aafb603\",\n name: \"USD Coin\",\n version: \"2\",\n decimals: 6,\n }, // Monad mainnet USDC\n };\n\n const assetInfo = stablecoins[network];\n if (!assetInfo) {\n throw new Error(`No default asset configured for network ${network}`);\n }\n\n return assetInfo;\n }\n}\n","import { x402ResourceServer } from \"@x402/core/server\";\nimport { Network } from \"@x402/core/types\";\nimport { ExactEvmScheme } from \"./scheme\";\n\n/**\n * Configuration options for registering EVM schemes to an x402ResourceServer\n */\nexport interface EvmResourceServerConfig {\n /**\n * Optional specific networks to register\n * If not provided, registers wildcard support (eip155:*)\n */\n networks?: Network[];\n}\n\n/**\n * Registers EVM exact payment schemes to an x402ResourceServer instance.\n *\n * This function registers:\n * - V2: eip155:* wildcard scheme with ExactEvmScheme (or specific networks if provided)\n *\n * @param server - The x402ResourceServer instance to register schemes to\n * @param config - Configuration for EVM resource server registration\n * @returns The server instance for chaining\n *\n * @example\n * ```typescript\n * import { registerExactEvmScheme } from \"@x402/evm/exact/server/register\";\n * import { x402ResourceServer } from \"@x402/core/server\";\n *\n * const server = new x402ResourceServer(facilitatorClient);\n * registerExactEvmScheme(server, {});\n * ```\n */\nexport function registerExactEvmScheme(\n server: x402ResourceServer,\n config: EvmResourceServerConfig = {},\n): x402ResourceServer {\n // Register V2 scheme\n if (config.networks && config.networks.length > 0) {\n // Register specific networks\n config.networks.forEach(network => {\n server.register(network, new ExactEvmScheme());\n });\n } else {\n // Register wildcard for all EVM chains\n server.register(\"eip155:*\", new ExactEvmScheme());\n }\n\n return server;\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/exact/server/scheme.ts","../../../../src/exact/server/register.ts"],"sourcesContent":["import {\n AssetAmount,\n Network,\n PaymentRequirements,\n Price,\n SchemeNetworkServer,\n MoneyParser,\n} from \"@x402/core/types\";\nimport { getDefaultAsset, type ExactDefaultAssetInfo } from \"../../shared/defaultAssets\";\n\n/**\n * EVM server implementation for the Exact payment scheme.\n */\nexport class ExactEvmScheme implements SchemeNetworkServer {\n readonly scheme = \"exact\";\n private moneyParsers: MoneyParser[] = [];\n\n /**\n * Register a custom money parser in the parser chain.\n * Multiple parsers can be registered - they will be tried in registration order.\n * Each parser receives a decimal amount (e.g., 1.50 for $1.50).\n * If a parser returns null, the next parser in the chain will be tried.\n * The default parser is always the final fallback.\n *\n * @param parser - Custom function to convert amount to AssetAmount (or null to skip)\n * @returns The server instance for chaining\n *\n * @example\n * evmServer.registerMoneyParser(async (amount, network) => {\n * // Custom conversion logic\n * if (amount > 100) {\n * // Use different token for large amounts\n * return { amount: (amount * 1e18).toString(), asset: \"0xCustomToken\" };\n * }\n * return null; // Use next parser\n * });\n */\n registerMoneyParser(parser: MoneyParser): ExactEvmScheme {\n this.moneyParsers.push(parser);\n return this;\n }\n\n /**\n * Returns the decimal precision of the default stablecoin for the given network.\n * Implements the optional AssetDecimalsProvider interface used by resolveSettlementOverrideAmount.\n *\n * @param _asset - The asset symbol (unused; defaults to the network's default stablecoin)\n * @param network - The network to look up the default asset for\n * @returns The number of decimal places for the asset\n */\n getAssetDecimals(_asset: string, network: Network): number {\n try {\n return getDefaultAsset(network).decimals;\n } catch {\n return 6;\n }\n }\n\n /**\n * Parses a price into an asset amount.\n * If price is already an AssetAmount, returns it directly.\n * If price is Money (string | number), parses to decimal and tries custom parsers.\n * Falls back to default conversion if all custom parsers return null.\n *\n * @param price - The price to parse\n * @param network - The network to use\n * @returns Promise that resolves to the parsed asset amount\n */\n async parsePrice(price: Price, network: Network): Promise<AssetAmount> {\n // If already an AssetAmount, return it directly\n if (typeof price === \"object\" && price !== null && \"amount\" in price) {\n if (!price.asset) {\n throw new Error(`Asset address must be specified for AssetAmount on network ${network}`);\n }\n return {\n amount: price.amount,\n asset: price.asset,\n extra: price.extra || {},\n };\n }\n\n // Parse Money to decimal number\n const amount = this.parseMoneyToDecimal(price);\n\n // Try each custom money parser in order\n for (const parser of this.moneyParsers) {\n const result = await parser(amount, network);\n if (result !== null) {\n return result;\n }\n }\n\n // All custom parsers returned null, use default conversion\n return this.defaultMoneyConversion(amount, network);\n }\n\n /**\n * Build payment requirements for this scheme/network combination\n *\n * @param paymentRequirements - The base payment requirements\n * @param supportedKind - The supported kind from facilitator (unused)\n * @param supportedKind.x402Version - The x402 version\n * @param supportedKind.scheme - The logical payment scheme\n * @param supportedKind.network - The network identifier in CAIP-2 format\n * @param supportedKind.extra - Optional extra metadata regarding scheme/network implementation details\n * @param extensionKeys - Extension keys supported by the facilitator (unused)\n * @returns Payment requirements ready to be sent to clients\n */\n enhancePaymentRequirements(\n paymentRequirements: PaymentRequirements,\n supportedKind: {\n x402Version: number;\n scheme: string;\n network: Network;\n extra?: Record<string, unknown>;\n },\n extensionKeys: string[],\n ): Promise<PaymentRequirements> {\n // Mark unused parameters to satisfy linter\n void supportedKind;\n void extensionKeys;\n return Promise.resolve(paymentRequirements);\n }\n\n /**\n * Parse Money (string | number) to a decimal number.\n * Handles formats like \"$1.50\", \"1.50\", 1.50, etc.\n *\n * @param money - The money value to parse\n * @returns Decimal number\n */\n private parseMoneyToDecimal(money: string | number): number {\n if (typeof money === \"number\") {\n return money;\n }\n\n // Remove $ sign and whitespace, then parse\n const cleanMoney = money.replace(/^\\$/, \"\").trim();\n const amount = parseFloat(cleanMoney);\n\n if (isNaN(amount)) {\n throw new Error(`Invalid money format: ${money}`);\n }\n\n return amount;\n }\n\n /**\n * Converts a numeric dollar amount to an AssetAmount using the default token for the network.\n *\n * @param amount - The dollar amount as a number\n * @param network - The target network\n * @returns The converted asset amount with token metadata\n */\n private defaultMoneyConversion(amount: number, network: Network): AssetAmount {\n const assetInfo: ExactDefaultAssetInfo = getDefaultAsset(network);\n const tokenAmount = this.convertToTokenAmount(amount.toString(), assetInfo.decimals);\n\n // EIP-3009 tokens always need name/version for their transferWithAuthorization domain.\n // Permit2 tokens only need them if the token supports EIP-2612 (for gasless permit signing).\n // Omitting name/version for permit2 tokens signals the client to skip EIP-2612 and use\n // ERC-20 approval gas sponsoring instead.\n const includeEip712Domain = !assetInfo.assetTransferMethod || assetInfo.supportsEip2612;\n\n return {\n amount: tokenAmount,\n asset: assetInfo.address,\n extra: {\n ...(includeEip712Domain && {\n name: assetInfo.name,\n version: assetInfo.version,\n }),\n ...(assetInfo.assetTransferMethod && {\n assetTransferMethod: assetInfo.assetTransferMethod,\n }),\n },\n };\n }\n\n /**\n * Converts a decimal string amount to an integer token amount using the given decimals.\n *\n * @param decimalAmount - The amount as a decimal string (e.g. \"1.5\")\n * @param decimals - The number of decimal places for the token\n * @returns The token amount as an integer string in smallest units\n */\n private convertToTokenAmount(decimalAmount: string, decimals: number): string {\n const amount = parseFloat(decimalAmount);\n if (isNaN(amount)) {\n throw new Error(`Invalid amount: ${decimalAmount}`);\n }\n const [intPart, decPart = \"\"] = String(amount).split(\".\");\n const paddedDec = decPart.padEnd(decimals, \"0\").slice(0, decimals);\n const tokenAmount = (intPart + paddedDec).replace(/^0+/, \"\") || \"0\";\n return tokenAmount;\n }\n}\n","import { x402ResourceServer } from \"@x402/core/server\";\nimport { Network } from \"@x402/core/types\";\nimport { ExactEvmScheme } from \"./scheme\";\n\n/**\n * Configuration options for registering EVM schemes to an x402ResourceServer\n */\nexport interface EvmResourceServerConfig {\n /**\n * Optional specific networks to register\n * If not provided, registers wildcard support (eip155:*)\n */\n networks?: Network[];\n}\n\n/**\n * Registers EVM exact payment schemes to an x402ResourceServer instance.\n *\n * This function registers:\n * - V2: eip155:* wildcard scheme with ExactEvmScheme (or specific networks if provided)\n *\n * @param server - The x402ResourceServer instance to register schemes to\n * @param config - Configuration for EVM resource server registration\n * @returns The server instance for chaining\n *\n * @example\n * ```typescript\n * import { registerExactEvmScheme } from \"@x402/evm/exact/server/register\";\n * import { x402ResourceServer } from \"@x402/core/server\";\n *\n * const server = new x402ResourceServer(facilitatorClient);\n * registerExactEvmScheme(server, {});\n * ```\n */\nexport function registerExactEvmScheme(\n server: x402ResourceServer,\n config: EvmResourceServerConfig = {},\n): x402ResourceServer {\n // Register V2 scheme\n if (config.networks && config.networks.length > 0) {\n // Register specific networks\n config.networks.forEach(network => {\n server.register(network, new ExactEvmScheme());\n });\n } else {\n // Register wildcard for all EVM chains\n server.register(\"eip155:*\", new ExactEvmScheme());\n }\n\n return server;\n}\n"],"mappings":"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","names":[]}
|
package/dist/esm/index.d.mts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
export { E as ExactEvmScheme
|
|
1
|
+
export { E as ExactEvmScheme } from './scheme-DCR7hsa3.mjs';
|
|
2
2
|
export { C as ClientEvmSigner, F as FacilitatorEvmSigner, t as toClientEvmSigner, a as toFacilitatorEvmSigner } from './signer-D912R4mq.mjs';
|
|
3
|
+
export { a as PERMIT2_ADDRESS, P as Permit2AllowanceParams, d as authorizationTypes, c as createPermit2ApprovalTx, f as eip3009ABI, e as erc20AllowanceAbi, g as getPermit2AllowanceReadParams, p as permit2WitnessTypes, u as uptoPermit2WitnessTypes, h as x402ExactPermit2ProxyABI, x as x402ExactPermit2ProxyAddress, i as x402UptoPermit2ProxyABI, b as x402UptoPermit2ProxyAddress } from './permit2-CyZxwngN.mjs';
|
|
4
|
+
export { UptoEvmScheme } from './upto/client/index.mjs';
|
|
3
5
|
import '@x402/core/types';
|
|
4
6
|
|
|
5
7
|
/**
|
|
@@ -72,5 +74,39 @@ declare function isPermit2Payload(payload: ExactEvmPayloadV2): payload is ExactP
|
|
|
72
74
|
* @returns True if the payload is an EIP-3009 payload, false otherwise.
|
|
73
75
|
*/
|
|
74
76
|
declare function isEIP3009Payload(payload: ExactEvmPayloadV2): payload is ExactEIP3009Payload;
|
|
77
|
+
/**
|
|
78
|
+
* Upto Permit2 witness — includes `facilitator` field absent from exact witness.
|
|
79
|
+
* Only the address matching `witness.facilitator` can call settle() on-chain.
|
|
80
|
+
*/
|
|
81
|
+
type UptoPermit2Witness = {
|
|
82
|
+
to: `0x${string}`;
|
|
83
|
+
facilitator: `0x${string}`;
|
|
84
|
+
validAfter: string;
|
|
85
|
+
};
|
|
86
|
+
type UptoPermit2Authorization = {
|
|
87
|
+
permitted: {
|
|
88
|
+
token: `0x${string}`;
|
|
89
|
+
amount: string;
|
|
90
|
+
};
|
|
91
|
+
spender: `0x${string}`;
|
|
92
|
+
nonce: string;
|
|
93
|
+
deadline: string;
|
|
94
|
+
witness: UptoPermit2Witness;
|
|
95
|
+
};
|
|
96
|
+
type UptoPermit2Payload = {
|
|
97
|
+
signature: `0x${string}`;
|
|
98
|
+
permit2Authorization: UptoPermit2Authorization & {
|
|
99
|
+
from: `0x${string}`;
|
|
100
|
+
};
|
|
101
|
+
};
|
|
102
|
+
/**
|
|
103
|
+
* Type guard to check if a payload is an upto Permit2 payload.
|
|
104
|
+
* Validates structural presence of all required fields: signature, permit2Authorization
|
|
105
|
+
* (with from, permitted, spender, nonce, deadline), and a witness containing facilitator.
|
|
106
|
+
*
|
|
107
|
+
* @param payload - The payload to check
|
|
108
|
+
* @returns True if the payload is an upto Permit2 payload, false otherwise
|
|
109
|
+
*/
|
|
110
|
+
declare function isUptoPermit2Payload(payload: Record<string, unknown>): payload is UptoPermit2Payload;
|
|
75
111
|
|
|
76
|
-
export { type AssetTransferMethod, type ExactEIP3009Payload, type ExactEvmPayloadV1, type ExactEvmPayloadV2, type ExactPermit2Payload, type Permit2Authorization, type Permit2Witness, isEIP3009Payload, isPermit2Payload };
|
|
112
|
+
export { type AssetTransferMethod, type ExactEIP3009Payload, type ExactEvmPayloadV1, type ExactEvmPayloadV2, type ExactPermit2Payload, type Permit2Authorization, type Permit2Witness, type UptoPermit2Authorization, type UptoPermit2Payload, type UptoPermit2Witness, isEIP3009Payload, isPermit2Payload, isUptoPermit2Payload };
|