@x402/evm 2.6.0 → 2.7.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.
Files changed (46) hide show
  1. package/README.md +24 -0
  2. package/dist/cjs/exact/client/index.d.ts +12 -5
  3. package/dist/cjs/exact/client/index.js +127 -28
  4. package/dist/cjs/exact/client/index.js.map +1 -1
  5. package/dist/cjs/exact/facilitator/index.d.ts +13 -1
  6. package/dist/cjs/exact/facilitator/index.js +987 -606
  7. package/dist/cjs/exact/facilitator/index.js.map +1 -1
  8. package/dist/cjs/exact/v1/client/index.d.ts +1 -1
  9. package/dist/cjs/exact/v1/client/index.js +11 -5
  10. package/dist/cjs/exact/v1/client/index.js.map +1 -1
  11. package/dist/cjs/exact/v1/facilitator/index.d.ts +16 -1
  12. package/dist/cjs/exact/v1/facilitator/index.js +414 -177
  13. package/dist/cjs/exact/v1/facilitator/index.js.map +1 -1
  14. package/dist/cjs/index.d.ts +2 -2
  15. package/dist/cjs/index.js +143 -30
  16. package/dist/cjs/index.js.map +1 -1
  17. package/dist/cjs/{permit2-DHAq6FTe.d.ts → permit2-U9Zolx3O.d.ts} +38 -5
  18. package/dist/{esm/signer-DC81R8wQ.d.mts → cjs/signer-D912R4mq.d.ts} +9 -3
  19. package/dist/cjs/v1/index.d.ts +1 -1
  20. package/dist/cjs/v1/index.js +6 -0
  21. package/dist/cjs/v1/index.js.map +1 -1
  22. package/dist/esm/chunk-GD4MKCN7.mjs +57 -0
  23. package/dist/esm/chunk-GD4MKCN7.mjs.map +1 -0
  24. package/dist/esm/{chunk-XL6IFXCP.mjs → chunk-IZEI7JTG.mjs} +516 -178
  25. package/dist/esm/chunk-IZEI7JTG.mjs.map +1 -0
  26. package/dist/esm/{chunk-LBIJBD7Q.mjs → chunk-WJWNS4G4.mjs} +113 -20
  27. package/dist/esm/chunk-WJWNS4G4.mjs.map +1 -0
  28. package/dist/esm/exact/client/index.d.mts +12 -5
  29. package/dist/esm/exact/client/index.mjs +3 -2
  30. package/dist/esm/exact/facilitator/index.d.mts +13 -1
  31. package/dist/esm/exact/facilitator/index.mjs +498 -391
  32. package/dist/esm/exact/facilitator/index.mjs.map +1 -1
  33. package/dist/esm/exact/v1/client/index.d.mts +1 -1
  34. package/dist/esm/exact/v1/client/index.mjs +1 -1
  35. package/dist/esm/exact/v1/facilitator/index.d.mts +16 -1
  36. package/dist/esm/exact/v1/facilitator/index.mjs +1 -1
  37. package/dist/esm/index.d.mts +2 -2
  38. package/dist/esm/index.mjs +7 -9
  39. package/dist/esm/index.mjs.map +1 -1
  40. package/dist/esm/{permit2-BuAhWvNC.d.mts → permit2-Bbh3a8_h.d.mts} +38 -5
  41. package/dist/{cjs/signer-DC81R8wQ.d.ts → esm/signer-D912R4mq.d.mts} +9 -3
  42. package/dist/esm/v1/index.d.mts +1 -1
  43. package/dist/esm/v1/index.mjs +1 -1
  44. package/package.json +2 -3
  45. package/dist/esm/chunk-LBIJBD7Q.mjs.map +0 -1
  46. package/dist/esm/chunk-XL6IFXCP.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/exact/facilitator/eip3009.ts","../../../../src/exact/facilitator/permit2.ts","../../../../src/exact/facilitator/errors.ts","../../../../src/exact/facilitator/erc20approval.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, parseSignature } from \"viem\";\nimport { authorizationTypes, eip3009ABI } from \"../../constants\";\nimport { FacilitatorEvmSigner } from \"../../signer\";\nimport { getEvmChainId } from \"../../utils\";\nimport { ExactEIP3009Payload } from \"../../types\";\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\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 * @returns Promise resolving to verification response\n */\nexport async function verifyEIP3009(\n signer: FacilitatorEvmSigner,\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n eip3009Payload: ExactEIP3009Payload,\n): Promise<VerifyResponse> {\n const payer = eip3009Payload.authorization.from;\n\n // Verify scheme matches\n if (payload.accepted.scheme !== \"exact\" || requirements.scheme !== \"exact\") {\n return {\n isValid: false,\n invalidReason: \"unsupported_scheme\",\n payer,\n };\n }\n\n // Get chain configuration\n if (!requirements.extra?.name || !requirements.extra?.version) {\n return {\n isValid: false,\n invalidReason: \"missing_eip712_domain\",\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: \"network_mismatch\",\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 try {\n const recoveredAddress = await signer.verifyTypedData({\n address: eip3009Payload.authorization.from,\n ...permitTypedData,\n signature: eip3009Payload.signature!,\n });\n\n if (!recoveredAddress) {\n return {\n isValid: false,\n invalidReason: \"invalid_exact_evm_payload_signature\",\n payer,\n };\n }\n } catch {\n // Signature verification failed - could be an undeployed smart wallet\n // Check if smart wallet is deployed\n const signature = eip3009Payload.signature!;\n const signatureLength = signature.startsWith(\"0x\") ? signature.length - 2 : signature.length;\n const isSmartWallet = signatureLength > 130; // 65 bytes = 130 hex chars for EOA\n\n if (isSmartWallet) {\n const payerAddress = eip3009Payload.authorization.from;\n const bytecode = await signer.getCode({ address: payerAddress });\n\n if (!bytecode || bytecode === \"0x\") {\n // Wallet is not deployed. Check if it's EIP-6492 with deployment info.\n const erc6492Data = parseErc6492Signature(signature);\n const hasDeploymentInfo =\n erc6492Data.address &&\n erc6492Data.data &&\n !isAddressEqual(erc6492Data.address, \"0x0000000000000000000000000000000000000000\");\n\n if (!hasDeploymentInfo) {\n // Non-EIP-6492 undeployed smart wallet - will always fail at settlement\n return {\n isValid: false,\n invalidReason: \"invalid_exact_evm_payload_undeployed_smart_wallet\",\n payer: payerAddress,\n };\n }\n // EIP-6492 signature with deployment info - allow through\n } else {\n // Wallet is deployed but signature still failed - invalid signature\n return {\n isValid: false,\n invalidReason: \"invalid_exact_evm_payload_signature\",\n payer,\n };\n }\n } else {\n // EOA signature failed\n return {\n isValid: false,\n invalidReason: \"invalid_exact_evm_payload_signature\",\n payer,\n };\n }\n }\n\n // Verify payment recipient matches\n if (getAddress(eip3009Payload.authorization.to) !== getAddress(requirements.payTo)) {\n return {\n isValid: false,\n invalidReason: \"invalid_exact_evm_payload_recipient_mismatch\",\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: \"invalid_exact_evm_payload_authorization_valid_before\",\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: \"invalid_exact_evm_payload_authorization_valid_after\",\n payer,\n };\n }\n\n // Check balance\n try {\n const balance = (await signer.readContract({\n address: erc20Address,\n abi: eip3009ABI,\n functionName: \"balanceOf\",\n args: [eip3009Payload.authorization.from],\n })) as bigint;\n\n if (BigInt(balance) < BigInt(requirements.amount)) {\n return {\n isValid: false,\n invalidReason: \"insufficient_funds\",\n invalidMessage: `Insufficient funds to complete the payment. Required: ${requirements.amount} ${requirements.asset}, Available: ${balance.toString()} ${requirements.asset}. Please add funds to your wallet and try again.`,\n payer,\n };\n }\n } catch {\n // If we can't check balance, continue with other validations\n }\n\n // Verify amount exactly matches requirements\n if (BigInt(eip3009Payload.authorization.value) !== BigInt(requirements.amount)) {\n return {\n isValid: false,\n invalidReason: \"invalid_exact_evm_payload_authorization_value_mismatch\",\n payer,\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 if (!valid.isValid) {\n return {\n success: false,\n network: payload.accepted.network,\n transaction: \"\",\n errorReason: valid.invalidReason ?? \"invalid_scheme\",\n payer,\n };\n }\n\n try {\n // Parse ERC-6492 signature if applicable\n const parseResult = parseErc6492Signature(eip3009Payload.signature!);\n const { signature, address: factoryAddress, data: factoryCalldata } = parseResult;\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 // Determine if this is an ECDSA signature (EOA) or smart wallet signature\n const signatureLength = signature.startsWith(\"0x\") ? signature.length - 2 : signature.length;\n const isECDSA = signatureLength === 130;\n\n let tx: Hex;\n if (isECDSA) {\n // For EOA wallets, parse signature into v, r, s and use that overload\n const parsedSig = parseSignature(signature);\n\n tx = await signer.writeContract({\n address: getAddress(requirements.asset),\n abi: eip3009ABI,\n functionName: \"transferWithAuthorization\",\n args: [\n getAddress(eip3009Payload.authorization.from),\n getAddress(eip3009Payload.authorization.to),\n BigInt(eip3009Payload.authorization.value),\n BigInt(eip3009Payload.authorization.validAfter),\n BigInt(eip3009Payload.authorization.validBefore),\n eip3009Payload.authorization.nonce,\n (parsedSig.v as number | undefined) || parsedSig.yParity,\n parsedSig.r,\n parsedSig.s,\n ],\n });\n } else {\n // For smart wallets, use the bytes signature overload\n tx = await signer.writeContract({\n address: getAddress(requirements.asset),\n abi: eip3009ABI,\n functionName: \"transferWithAuthorization\",\n args: [\n getAddress(eip3009Payload.authorization.from),\n getAddress(eip3009Payload.authorization.to),\n BigInt(eip3009Payload.authorization.value),\n BigInt(eip3009Payload.authorization.validAfter),\n BigInt(eip3009Payload.authorization.validBefore),\n eip3009Payload.authorization.nonce,\n signature,\n ],\n });\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: \"invalid_transaction_state\",\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: \"transaction_failed\",\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 validateEip2612GasSponsoringInfo,\n extractErc20ApprovalGasSponsoringInfo,\n ERC20_APPROVAL_GAS_SPONSORING,\n type Erc20ApprovalGasSponsoringFacilitatorExtension,\n} from \"@x402/extensions\";\nimport type { Eip2612GasSponsoringInfo } from \"@x402/extensions\";\nimport { getAddress } from \"viem\";\nimport {\n eip3009ABI,\n PERMIT2_ADDRESS,\n permit2WitnessTypes,\n x402ExactPermit2ProxyABI,\n x402ExactPermit2ProxyAddress,\n erc20AllowanceAbi,\n} from \"../../constants\";\nimport {\n ErrPermit2612AmountMismatch,\n ErrPermit2InvalidAmount,\n ErrPermit2InvalidDestination,\n ErrPermit2InvalidNonce,\n ErrPermit2InvalidOwner,\n ErrPermit2InvalidSignature,\n ErrPermit2PaymentTooEarly,\n} from \"./errors\";\nimport { FacilitatorEvmSigner } from \"../../signer\";\nimport { ExactPermit2Payload } from \"../../types\";\nimport { getEvmChainId } from \"../../utils\";\nimport { validateErc20ApprovalForPayment } from \"./erc20approval\";\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 * @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): 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: \"unsupported_scheme\",\n payer,\n };\n }\n\n if (payload.accepted.network !== requirements.network) {\n return {\n isValid: false,\n invalidReason: \"network_mismatch\",\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: \"invalid_permit2_spender\",\n payer,\n };\n }\n\n if (\n getAddress(permit2Payload.permit2Authorization.witness.to) !== getAddress(requirements.payTo)\n ) {\n return {\n isValid: false,\n invalidReason: \"invalid_permit2_recipient_mismatch\",\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: \"permit2_deadline_expired\",\n payer,\n };\n }\n\n if (BigInt(permit2Payload.permit2Authorization.witness.validAfter) > BigInt(now)) {\n return {\n isValid: false,\n invalidReason: \"permit2_not_yet_valid\",\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: \"permit2_amount_mismatch\",\n payer,\n };\n }\n\n if (getAddress(permit2Payload.permit2Authorization.permitted.token) !== tokenAddress) {\n return {\n isValid: false,\n invalidReason: \"permit2_token_mismatch\",\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 try {\n const isValid = await signer.verifyTypedData({\n address: payer,\n ...permit2TypedData,\n signature: permit2Payload.signature,\n });\n\n if (!isValid) {\n return {\n isValid: false,\n invalidReason: \"invalid_permit2_signature\",\n payer,\n };\n }\n } catch {\n return {\n isValid: false,\n invalidReason: \"invalid_permit2_signature\",\n payer,\n };\n }\n\n // Check Permit2 allowance — if insufficient, try gas sponsoring extensions\n const allowanceResult = await _verifyPermit2Allowance(\n signer,\n payload,\n requirements,\n payer,\n tokenAddress,\n context,\n );\n if (allowanceResult) {\n return allowanceResult;\n }\n\n try {\n const balance = (await signer.readContract({\n address: tokenAddress,\n abi: eip3009ABI,\n functionName: \"balanceOf\",\n args: [payer],\n })) as bigint;\n\n if (balance < BigInt(requirements.amount)) {\n return {\n isValid: false,\n invalidReason: \"insufficient_funds\",\n invalidMessage: `Insufficient funds to complete the payment. Required: ${requirements.amount} ${requirements.asset}, Available: ${balance.toString()} ${requirements.asset}. Please add funds to your wallet and try again.`,\n payer,\n };\n }\n } catch {\n // If we can't check balance, continue\n }\n\n return {\n isValid: true,\n invalidReason: undefined,\n payer,\n };\n}\n\n/**\n * Checks Permit2 allowance and validates gas sponsoring extensions if allowance is insufficient.\n *\n * @param signer - The facilitator signer for on-chain reads\n * @param payload - The payment payload\n * @param requirements - The payment requirements\n * @param payer - The payer address\n * @param tokenAddress - The token contract address\n * @param context - Optional facilitator context for extension lookup\n * @returns A VerifyResponse if verification should stop (failure), or null to continue\n */\nasync function _verifyPermit2Allowance(\n signer: FacilitatorEvmSigner,\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n payer: `0x${string}`,\n tokenAddress: `0x${string}`,\n context?: FacilitatorContext,\n): Promise<VerifyResponse | null> {\n try {\n const allowance = (await signer.readContract({\n address: tokenAddress,\n abi: erc20AllowanceAbi,\n functionName: \"allowance\",\n args: [payer, PERMIT2_ADDRESS],\n })) as bigint;\n\n if (allowance >= BigInt(requirements.amount)) {\n return null; // Sufficient allowance, continue verification\n }\n\n // Allowance insufficient — try EIP-2612 gas sponsoring first\n const eip2612Info = extractEip2612GasSponsoringInfo(payload);\n if (eip2612Info) {\n const result = validateEip2612PermitForPayment(eip2612Info, payer, tokenAddress);\n if (!result.isValid) {\n return { isValid: false, invalidReason: result.invalidReason!, payer };\n }\n return null; // EIP-2612 is valid, allowance will be set atomically during settlement\n }\n\n // Try ERC-20 approval gas sponsoring as fallback\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 result = await validateErc20ApprovalForPayment(erc20Info, payer, tokenAddress);\n if (!result.isValid) {\n return { isValid: false, invalidReason: result.invalidReason!, payer };\n }\n return null; // ERC-20 approval is valid, will be broadcast before settlement\n }\n }\n\n return { isValid: false, invalidReason: \"permit2_allowance_required\", payer };\n } catch {\n // If allowance check fails, validate extensions if present; otherwise proceed optimistically\n const eip2612Info = extractEip2612GasSponsoringInfo(payload);\n if (eip2612Info) {\n const result = validateEip2612PermitForPayment(eip2612Info, payer, tokenAddress);\n if (!result.isValid) {\n return { isValid: false, invalidReason: result.invalidReason!, payer };\n }\n }\n return null;\n }\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 * @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): Promise<SettleResponse> {\n const payer = permit2Payload.permit2Authorization.from;\n\n const valid = await verifyPermit2(signer, payload, requirements, permit2Payload, context);\n if (!valid.isValid) {\n return {\n success: false,\n network: payload.accepted.network,\n transaction: \"\",\n errorReason: valid.invalidReason ?? \"invalid_scheme\",\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 if (erc20GasSponsorshipExtension?.signer) {\n return _settlePermit2WithERC20Approval(\n erc20GasSponsorshipExtension.signer,\n payload,\n permit2Payload,\n erc20Info,\n );\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 {\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(payer),\n {\n to: getAddress(permit2Payload.permit2Authorization.witness.to),\n validAfter: BigInt(permit2Payload.permit2Authorization.witness.validAfter),\n },\n permit2Payload.signature,\n ],\n });\n\n return _waitAndReturn(signer, tx, payload, payer);\n } catch (error) {\n return _mapSettleError(error, payload, payer);\n }\n}\n\n/**\n * Broadcasts the pre-signed ERC-20 approve tx then settles via the extension signer.\n * Both operations use the extension signer, enabling atomic bundling by production implementations.\n *\n * @param extensionSigner - The extension signer with sendRawTransaction + writeContract\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 EIP-1559 approval tx\n * @returns Promise resolving to settlement response\n */\nasync function _settlePermit2WithERC20Approval(\n extensionSigner: Erc20ApprovalGasSponsoringFacilitatorExtension[\"signer\"] & {},\n payload: PaymentPayload,\n permit2Payload: ExactPermit2Payload,\n erc20Info: { signedTransaction: string },\n): Promise<SettleResponse> {\n const payer = permit2Payload.permit2Authorization.from;\n\n try {\n const approvalTxHash = await extensionSigner.sendRawTransaction({\n serializedTransaction: erc20Info.signedTransaction as `0x${string}`,\n });\n\n const approvalReceipt = await extensionSigner.waitForTransactionReceipt({\n hash: approvalTxHash,\n });\n\n if (approvalReceipt.status !== \"success\") {\n return {\n success: false,\n errorReason: \"erc20_approval_tx_failed\",\n transaction: approvalTxHash,\n network: payload.accepted.network,\n payer,\n };\n }\n\n const tx = await extensionSigner.writeContract({\n address: x402ExactPermit2ProxyAddress,\n abi: x402ExactPermit2ProxyABI,\n functionName: \"settle\",\n args: [\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(payer),\n {\n to: getAddress(permit2Payload.permit2Authorization.witness.to),\n validAfter: BigInt(permit2Payload.permit2Authorization.witness.validAfter),\n },\n permit2Payload.signature,\n ],\n });\n\n return _waitAndReturn(extensionSigner, tx, 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: [\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(payer),\n {\n to: getAddress(permit2Payload.permit2Authorization.witness.to),\n validAfter: BigInt(permit2Payload.permit2Authorization.witness.validAfter),\n },\n permit2Payload.signature,\n ],\n });\n\n return _waitAndReturn(signer, tx, payload, payer);\n } catch (error) {\n return _mapSettleError(error, payload, payer);\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 */\nasync 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: \"invalid_transaction_state\",\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 */\nfunction _mapSettleError(\n error: unknown,\n payload: PaymentPayload,\n payer: `0x${string}`,\n): SettleResponse {\n let errorReason = \"transaction_failed\";\n if (error instanceof Error) {\n const message = error.message;\n if (message.includes(\"Permit2612AmountMismatch\")) {\n errorReason = ErrPermit2612AmountMismatch;\n } else if (message.includes(\"InvalidAmount\")) {\n errorReason = ErrPermit2InvalidAmount;\n } else if (message.includes(\"InvalidDestination\")) {\n errorReason = ErrPermit2InvalidDestination;\n } else if (message.includes(\"InvalidOwner\")) {\n errorReason = ErrPermit2InvalidOwner;\n } else if (message.includes(\"PaymentTooEarly\")) {\n errorReason = ErrPermit2PaymentTooEarly;\n } else if (message.includes(\"InvalidSignature\") || message.includes(\"SignatureExpired\")) {\n errorReason = ErrPermit2InvalidSignature;\n } else if (message.includes(\"InvalidNonce\")) {\n errorReason = ErrPermit2InvalidNonce;\n } else {\n errorReason = `transaction_failed: ${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 */\nfunction 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: \"invalid_eip2612_extension_format\" };\n }\n\n if (getAddress(info.from as `0x${string}`) !== getAddress(payer)) {\n return { isValid: false, invalidReason: \"eip2612_from_mismatch\" };\n }\n\n if (getAddress(info.asset as `0x${string}`) !== tokenAddress) {\n return { isValid: false, invalidReason: \"eip2612_asset_mismatch\" };\n }\n\n if (getAddress(info.spender as `0x${string}`) !== getAddress(PERMIT2_ADDRESS)) {\n return { isValid: false, invalidReason: \"eip2612_spender_not_permit2\" };\n }\n\n const now = Math.floor(Date.now() / 1000);\n if (BigInt(info.deadline) < BigInt(now + 6)) {\n return { isValid: false, invalidReason: \"eip2612_deadline_expired\" };\n }\n\n return { isValid: true };\n}\n\n/**\n * Splits a 65-byte EIP-2612 signature into v, r, s components.\n *\n * @param signature - The hex-encoded 65-byte signature\n * @returns Object with v (uint8), r (bytes32), s (bytes32)\n */\nfunction 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 * Named error reason constants for the exact EVM facilitator.\n *\n * These strings must be character-for-character identical to the Go constants in\n * go/mechanisms/evm/exact/facilitator/errors.go to maintain cross-SDK parity.\n */\n\n// EIP-3009 verify errors\nexport const ErrInvalidScheme = \"invalid_exact_evm_scheme\";\nexport const ErrNetworkMismatch = \"invalid_exact_evm_network_mismatch\";\n\n// Permit2 verify errors\nexport const ErrPermit2InvalidSpender = \"invalid_permit2_spender\";\nexport const ErrPermit2RecipientMismatch = \"invalid_permit2_recipient_mismatch\";\nexport const ErrPermit2DeadlineExpired = \"permit2_deadline_expired\";\nexport const ErrPermit2NotYetValid = \"permit2_not_yet_valid\";\nexport const ErrPermit2InsufficientAmount = \"permit2_insufficient_amount\";\nexport const ErrPermit2TokenMismatch = \"permit2_token_mismatch\";\nexport const ErrPermit2InvalidSignature = \"invalid_permit2_signature\";\nexport const ErrPermit2AllowanceRequired = \"permit2_allowance_required\";\n\n// Permit2 settle errors (from contract reverts)\nexport const ErrPermit2InvalidAmount = \"permit2_invalid_amount\";\nexport const ErrPermit2InvalidDestination = \"permit2_invalid_destination\";\nexport const ErrPermit2InvalidOwner = \"permit2_invalid_owner\";\nexport const ErrPermit2PaymentTooEarly = \"permit2_payment_too_early\";\nexport const ErrPermit2InvalidNonce = \"permit2_invalid_nonce\";\nexport const ErrPermit2612AmountMismatch = \"permit2_2612_amount_mismatch\";\n\n// ERC-20 approval gas sponsoring verify errors\nexport const ErrErc20ApprovalInvalidFormat = \"invalid_erc20_approval_extension_format\";\nexport const ErrErc20ApprovalFromMismatch = \"erc20_approval_from_mismatch\";\nexport const ErrErc20ApprovalAssetMismatch = \"erc20_approval_asset_mismatch\";\nexport const ErrErc20ApprovalSpenderNotPermit2 = \"erc20_approval_spender_not_permit2\";\nexport const ErrErc20ApprovalTxWrongTarget = \"erc20_approval_tx_wrong_target\";\nexport const ErrErc20ApprovalTxWrongSelector = \"erc20_approval_tx_wrong_selector\";\nexport const ErrErc20ApprovalTxWrongSpender = \"erc20_approval_tx_wrong_spender\";\nexport const ErrErc20ApprovalTxInvalidCalldata = \"erc20_approval_tx_invalid_calldata\";\nexport const ErrErc20ApprovalTxSignerMismatch = \"erc20_approval_tx_signer_mismatch\";\nexport const ErrErc20ApprovalTxInvalidSignature = \"erc20_approval_tx_invalid_signature\";\nexport const ErrErc20ApprovalTxParseFailed = \"erc20_approval_tx_parse_failed\";\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 \"@x402/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 {\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\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 };\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\n if (isPermit2Payload(rawPayload)) {\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\n if (isPermit2Payload(rawPayload)) {\n return settlePermit2(this.signer, payload, requirements, rawPayload, context);\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/**\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 }),\n );\n\n // Register all V1 networks\n facilitator.registerV1(\n NETWORKS as Network[],\n new ExactEvmSchemeV1(config.signer, {\n deployERC4337WithEIP6492: config.deployERC4337WithEIP6492,\n }),\n );\n\n return facilitator;\n}\n"],"mappings":"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","names":["getAddress","getAddress","getAddress","getAddress"]}
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,5 +1,5 @@
1
1
  import { SchemeNetworkClient, PaymentRequirements, PaymentPayload, Network } from '@x402/core/types';
2
- import { C as ClientEvmSigner } from '../../../signer-DC81R8wQ.mjs';
2
+ import { C as ClientEvmSigner } from '../../../signer-D912R4mq.mjs';
3
3
 
4
4
  /**
5
5
  * EVM client implementation for the Exact payment scheme (V1).
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  ExactEvmSchemeV12 as ExactEvmSchemeV1
3
- } from "../../../chunk-XL6IFXCP.mjs";
3
+ } from "../../../chunk-IZEI7JTG.mjs";
4
4
  export {
5
5
  ExactEvmSchemeV1
6
6
  };
@@ -1,5 +1,5 @@
1
1
  import { SchemeNetworkFacilitator, PaymentPayload, PaymentRequirements, VerifyResponse, SettleResponse } from '@x402/core/types';
2
- import { F as FacilitatorEvmSigner } from '../../../signer-DC81R8wQ.mjs';
2
+ import { F as FacilitatorEvmSigner } from '../../../signer-D912R4mq.mjs';
3
3
 
4
4
  interface ExactEvmSchemeV1Config {
5
5
  /**
@@ -9,6 +9,12 @@ interface ExactEvmSchemeV1Config {
9
9
  * @default false
10
10
  */
11
11
  deployERC4337WithEIP6492?: boolean;
12
+ /**
13
+ * If enabled, simulates transaction before settling. Defaults to false, ie only simulate during verify.
14
+ *
15
+ * @default false
16
+ */
17
+ simulateInSettle?: boolean;
12
18
  }
13
19
  /**
14
20
  * EVM facilitator implementation for the Exact payment scheme (V1).
@@ -57,6 +63,15 @@ declare class ExactEvmSchemeV1 implements SchemeNetworkFacilitator {
57
63
  * @returns Promise resolving to settlement response
58
64
  */
59
65
  settle(payload: PaymentPayload, requirements: PaymentRequirements): Promise<SettleResponse>;
66
+ /**
67
+ * Internal verify with optional simulation control.
68
+ *
69
+ * @param payload - The payment payload to verify
70
+ * @param requirements - The payment requirements
71
+ * @param options - Verification options (e.g. simulate)
72
+ * @returns Promise resolving to verification response
73
+ */
74
+ private _verify;
60
75
  }
61
76
 
62
77
  export { ExactEvmSchemeV1, type ExactEvmSchemeV1Config };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  ExactEvmSchemeV1
3
- } from "../../../chunk-XL6IFXCP.mjs";
3
+ } from "../../../chunk-IZEI7JTG.mjs";
4
4
  export {
5
5
  ExactEvmSchemeV1
6
6
  };
@@ -1,5 +1,5 @@
1
- export { E as ExactEvmScheme, 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, h as x402ExactPermit2ProxyABI, x as x402ExactPermit2ProxyAddress, b as x402UptoPermit2ProxyAddress } from './permit2-BuAhWvNC.mjs';
2
- export { C as ClientEvmSigner, F as FacilitatorEvmSigner, t as toClientEvmSigner, a as toFacilitatorEvmSigner } from './signer-DC81R8wQ.mjs';
1
+ export { E as ExactEvmScheme, 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, h as x402ExactPermit2ProxyABI, x as x402ExactPermit2ProxyAddress, b as x402UptoPermit2ProxyAddress } from './permit2-Bbh3a8_h.mjs';
2
+ export { C as ClientEvmSigner, F as FacilitatorEvmSigner, t as toClientEvmSigner, a as toFacilitatorEvmSigner } from './signer-D912R4mq.mjs';
3
3
  import '@x402/core/types';
4
4
 
5
5
  /**
@@ -2,11 +2,12 @@ import {
2
2
  ExactEvmScheme,
3
3
  createPermit2ApprovalTx,
4
4
  getPermit2AllowanceReadParams
5
- } from "./chunk-LBIJBD7Q.mjs";
5
+ } from "./chunk-WJWNS4G4.mjs";
6
6
  import {
7
7
  isEIP3009Payload,
8
8
  isPermit2Payload
9
9
  } from "./chunk-TKN5V2BV.mjs";
10
+ import "./chunk-GD4MKCN7.mjs";
10
11
  import {
11
12
  PERMIT2_ADDRESS,
12
13
  authorizationTypes,
@@ -16,21 +17,18 @@ import {
16
17
  x402ExactPermit2ProxyABI,
17
18
  x402ExactPermit2ProxyAddress,
18
19
  x402UptoPermit2ProxyAddress
19
- } from "./chunk-XL6IFXCP.mjs";
20
+ } from "./chunk-IZEI7JTG.mjs";
20
21
 
21
22
  // src/signer.ts
22
23
  function toClientEvmSigner(signer, publicClient) {
23
24
  const readContract = signer.readContract ?? publicClient?.readContract.bind(publicClient);
24
- if (!readContract) {
25
- throw new Error(
26
- "toClientEvmSigner requires either a signer with readContract or a publicClient. Use createWalletClient(...).extend(publicActions) or pass a publicClient."
27
- );
28
- }
29
25
  const result = {
30
26
  address: signer.address,
31
- signTypedData: (msg) => signer.signTypedData(msg),
32
- readContract
27
+ signTypedData: (msg) => signer.signTypedData(msg)
33
28
  };
29
+ if (readContract) {
30
+ result.readContract = readContract;
31
+ }
34
32
  const signTransaction = signer.signTransaction;
35
33
  if (signTransaction) {
36
34
  result.signTransaction = (args) => signTransaction(args);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/signer.ts"],"sourcesContent":["/**\n * ClientEvmSigner - Used by x402 clients to sign payment authorizations.\n *\n * Typically a viem WalletClient extended with publicActions:\n * ```typescript\n * const client = createWalletClient({\n * account: privateKeyToAccount('0x...'),\n * chain: baseSepolia,\n * transport: http(),\n * }).extend(publicActions);\n * ```\n *\n * Or composed via `toClientEvmSigner(account, publicClient)`.\n */\nexport type ClientEvmSigner = {\n readonly address: `0x${string}`;\n signTypedData(message: {\n domain: Record<string, unknown>;\n types: Record<string, unknown>;\n primaryType: string;\n message: Record<string, unknown>;\n }): Promise<`0x${string}`>;\n readContract(args: {\n address: `0x${string}`;\n abi: readonly unknown[];\n functionName: string;\n args?: readonly unknown[];\n }): Promise<unknown>;\n /**\n * Optional: Signs a raw EIP-1559 transaction without broadcasting.\n * Required for ERC-20 approval gas sponsoring when the token lacks EIP-2612.\n */\n signTransaction?(args: {\n to: `0x${string}`;\n data: `0x${string}`;\n nonce: number;\n gas: bigint;\n maxFeePerGas: bigint;\n maxPriorityFeePerGas: bigint;\n chainId: number;\n }): Promise<`0x${string}`>;\n /**\n * Optional: Gets the current transaction count (nonce) for an address.\n * Required for ERC-20 approval gas sponsoring.\n */\n getTransactionCount?(args: { address: `0x${string}` }): Promise<number>;\n /**\n * Optional: Estimates current gas fees per gas.\n * Required for ERC-20 approval gas sponsoring.\n */\n estimateFeesPerGas?(): Promise<{ maxFeePerGas: bigint; maxPriorityFeePerGas: bigint }>;\n};\n\n/**\n * FacilitatorEvmSigner - Used by x402 facilitators to verify and settle payments\n * This is typically a viem PublicClient + WalletClient combination that can\n * read contract state, verify signatures, write transactions, and wait for receipts\n *\n * Supports multiple addresses for load balancing, key rotation, and high availability\n */\nexport type FacilitatorEvmSigner = {\n /**\n * Get all addresses this facilitator can use for signing\n * Enables dynamic address selection for load balancing and key rotation\n */\n getAddresses(): readonly `0x${string}`[];\n\n readContract(args: {\n address: `0x${string}`;\n abi: readonly unknown[];\n functionName: string;\n args?: readonly unknown[];\n }): Promise<unknown>;\n verifyTypedData(args: {\n address: `0x${string}`;\n domain: Record<string, unknown>;\n types: Record<string, unknown>;\n primaryType: string;\n message: Record<string, unknown>;\n signature: `0x${string}`;\n }): Promise<boolean>;\n writeContract(args: {\n address: `0x${string}`;\n abi: readonly unknown[];\n functionName: string;\n args: readonly unknown[];\n }): Promise<`0x${string}`>;\n sendTransaction(args: { to: `0x${string}`; data: `0x${string}` }): Promise<`0x${string}`>;\n waitForTransactionReceipt(args: { hash: `0x${string}` }): Promise<{ status: string }>;\n getCode(args: { address: `0x${string}` }): Promise<`0x${string}` | undefined>;\n};\n\n/**\n * Composes a ClientEvmSigner from a local account and a public client.\n *\n * Use this when your signer (e.g., `privateKeyToAccount`) doesn't have\n * `readContract`. The `publicClient` provides the on-chain read capability.\n *\n * Alternatively, use a WalletClient extended with publicActions directly:\n * ```typescript\n * const signer = createWalletClient({\n * account: privateKeyToAccount('0x...'),\n * chain: baseSepolia,\n * transport: http(),\n * }).extend(publicActions);\n * ```\n *\n * @param signer - A signer with `address` and `signTypedData` (and optionally `readContract`)\n * @param publicClient - A client with `readContract` (required if signer lacks it)\n * @param publicClient.readContract - The readContract method from the public client\n * @param publicClient.getTransactionCount - Optional getTransactionCount for ERC-20 approval\n * @param publicClient.estimateFeesPerGas - Optional estimateFeesPerGas for ERC-20 approval\n * @returns A complete ClientEvmSigner\n *\n * @example\n * ```typescript\n * const account = privateKeyToAccount(\"0x...\");\n * const publicClient = createPublicClient({ chain: baseSepolia, transport: http() });\n * const signer = toClientEvmSigner(account, publicClient);\n * ```\n */\nexport function toClientEvmSigner(\n signer: Omit<ClientEvmSigner, \"readContract\"> & {\n readContract?: ClientEvmSigner[\"readContract\"];\n },\n publicClient?: {\n readContract(args: {\n address: `0x${string}`;\n abi: readonly unknown[];\n functionName: string;\n args?: readonly unknown[];\n }): Promise<unknown>;\n getTransactionCount?(args: { address: `0x${string}` }): Promise<number>;\n estimateFeesPerGas?(): Promise<{ maxFeePerGas: bigint; maxPriorityFeePerGas: bigint }>;\n },\n): ClientEvmSigner {\n const readContract = signer.readContract ?? publicClient?.readContract.bind(publicClient);\n\n if (!readContract) {\n throw new Error(\n \"toClientEvmSigner requires either a signer with readContract or a publicClient. \" +\n \"Use createWalletClient(...).extend(publicActions) or pass a publicClient.\",\n );\n }\n\n const result: ClientEvmSigner = {\n address: signer.address,\n signTypedData: msg => signer.signTypedData(msg),\n readContract,\n };\n\n // Forward optional capabilities from signer or publicClient\n const signTransaction = signer.signTransaction;\n if (signTransaction) {\n result.signTransaction = args => signTransaction(args);\n }\n\n const getTransactionCount =\n signer.getTransactionCount ?? publicClient?.getTransactionCount?.bind(publicClient);\n if (getTransactionCount) {\n result.getTransactionCount = args => getTransactionCount(args);\n }\n\n const estimateFeesPerGas =\n signer.estimateFeesPerGas ?? publicClient?.estimateFeesPerGas?.bind(publicClient);\n if (estimateFeesPerGas) {\n result.estimateFeesPerGas = () => estimateFeesPerGas();\n }\n\n return result;\n}\n\n/**\n * Converts a viem client with single address to a FacilitatorEvmSigner\n * Wraps the single address in a getAddresses() function for compatibility\n *\n * @param client - The client to convert (must have 'address' property)\n * @returns FacilitatorEvmSigner with getAddresses() support\n */\nexport function toFacilitatorEvmSigner(\n client: Omit<FacilitatorEvmSigner, \"getAddresses\"> & { address: `0x${string}` },\n): FacilitatorEvmSigner {\n return {\n ...client,\n getAddresses: () => [client.address],\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAyHO,SAAS,kBACd,QAGA,cAUiB;AACjB,QAAM,eAAe,OAAO,gBAAgB,cAAc,aAAa,KAAK,YAAY;AAExF,MAAI,CAAC,cAAc;AACjB,UAAM,IAAI;AAAA,MACR;AAAA,IAEF;AAAA,EACF;AAEA,QAAM,SAA0B;AAAA,IAC9B,SAAS,OAAO;AAAA,IAChB,eAAe,SAAO,OAAO,cAAc,GAAG;AAAA,IAC9C;AAAA,EACF;AAGA,QAAM,kBAAkB,OAAO;AAC/B,MAAI,iBAAiB;AACnB,WAAO,kBAAkB,UAAQ,gBAAgB,IAAI;AAAA,EACvD;AAEA,QAAM,sBACJ,OAAO,uBAAuB,cAAc,qBAAqB,KAAK,YAAY;AACpF,MAAI,qBAAqB;AACvB,WAAO,sBAAsB,UAAQ,oBAAoB,IAAI;AAAA,EAC/D;AAEA,QAAM,qBACJ,OAAO,sBAAsB,cAAc,oBAAoB,KAAK,YAAY;AAClF,MAAI,oBAAoB;AACtB,WAAO,qBAAqB,MAAM,mBAAmB;AAAA,EACvD;AAEA,SAAO;AACT;AASO,SAAS,uBACd,QACsB;AACtB,SAAO;AAAA,IACL,GAAG;AAAA,IACH,cAAc,MAAM,CAAC,OAAO,OAAO;AAAA,EACrC;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/signer.ts"],"sourcesContent":["/**\n * ClientEvmSigner - Used by x402 clients to sign payment authorizations.\n *\n * Typically a viem WalletClient extended with publicActions:\n * ```typescript\n * const client = createWalletClient({\n * account: privateKeyToAccount('0x...'),\n * chain: baseSepolia,\n * transport: http(),\n * }).extend(publicActions);\n * ```\n *\n * Or composed via `toClientEvmSigner(account, publicClient)`.\n */\nexport type ClientEvmSigner = {\n readonly address: `0x${string}`;\n signTypedData(message: {\n domain: Record<string, unknown>;\n types: Record<string, unknown>;\n primaryType: string;\n message: Record<string, unknown>;\n }): Promise<`0x${string}`>;\n /**\n * Optional on-chain reads.\n * Required only for extension enrichment (EIP-2612 / ERC-20 approval).\n */\n readContract?(args: {\n address: `0x${string}`;\n abi: readonly unknown[];\n functionName: string;\n args?: readonly unknown[];\n }): Promise<unknown>;\n /**\n * Optional: Signs a raw EIP-1559 transaction without broadcasting.\n * Required for ERC-20 approval gas sponsoring when the token lacks EIP-2612.\n */\n signTransaction?(args: {\n to: `0x${string}`;\n data: `0x${string}`;\n nonce: number;\n gas: bigint;\n maxFeePerGas: bigint;\n maxPriorityFeePerGas: bigint;\n chainId: number;\n }): Promise<`0x${string}`>;\n /**\n * Optional: Gets the current transaction count (nonce) for an address.\n * Required for ERC-20 approval gas sponsoring.\n */\n getTransactionCount?(args: { address: `0x${string}` }): Promise<number>;\n /**\n * Optional: Estimates current gas fees per gas.\n * Required for ERC-20 approval gas sponsoring.\n */\n estimateFeesPerGas?(): Promise<{ maxFeePerGas: bigint; maxPriorityFeePerGas: bigint }>;\n};\n\n/**\n * FacilitatorEvmSigner - Used by x402 facilitators to verify and settle payments\n * This is typically a viem PublicClient + WalletClient combination that can\n * read contract state, verify signatures, write transactions, and wait for receipts\n *\n * Supports multiple addresses for load balancing, key rotation, and high availability\n */\nexport type FacilitatorEvmSigner = {\n /**\n * Get all addresses this facilitator can use for signing\n * Enables dynamic address selection for load balancing and key rotation\n */\n getAddresses(): readonly `0x${string}`[];\n\n readContract(args: {\n address: `0x${string}`;\n abi: readonly unknown[];\n functionName: string;\n args?: readonly unknown[];\n }): Promise<unknown>;\n verifyTypedData(args: {\n address: `0x${string}`;\n domain: Record<string, unknown>;\n types: Record<string, unknown>;\n primaryType: string;\n message: Record<string, unknown>;\n signature: `0x${string}`;\n }): Promise<boolean>;\n writeContract(args: {\n address: `0x${string}`;\n abi: readonly unknown[];\n functionName: string;\n args: readonly unknown[];\n /** Optional gas limit. When provided, skips eth_estimateGas simulation. */\n gas?: bigint;\n }): Promise<`0x${string}`>;\n sendTransaction(args: { to: `0x${string}`; data: `0x${string}` }): Promise<`0x${string}`>;\n waitForTransactionReceipt(args: { hash: `0x${string}` }): Promise<{ status: string }>;\n getCode(args: { address: `0x${string}` }): Promise<`0x${string}` | undefined>;\n};\n\n/**\n * Composes a ClientEvmSigner from a local account and a public client.\n *\n * Use this when your signer (e.g., `privateKeyToAccount`) doesn't have\n * `readContract`. The `publicClient` provides the on-chain read capability.\n *\n * Alternatively, use a WalletClient extended with publicActions directly:\n * ```typescript\n * const signer = createWalletClient({\n * account: privateKeyToAccount('0x...'),\n * chain: baseSepolia,\n * transport: http(),\n * }).extend(publicActions);\n * ```\n *\n * @param signer - A signer with `address` and `signTypedData` (and optionally `readContract`)\n * @param publicClient - A client with optional read/nonce/fee helpers\n * @param publicClient.readContract - The readContract method from the public client\n * @param publicClient.getTransactionCount - Optional getTransactionCount for ERC-20 approval\n * @param publicClient.estimateFeesPerGas - Optional estimateFeesPerGas for ERC-20 approval\n * @returns A ClientEvmSigner with any available optional capabilities\n *\n * @example\n * ```typescript\n * const account = privateKeyToAccount(\"0x...\");\n * const publicClient = createPublicClient({ chain: baseSepolia, transport: http() });\n * const signer = toClientEvmSigner(account, publicClient);\n * ```\n */\nexport function toClientEvmSigner(\n signer: Omit<ClientEvmSigner, \"readContract\"> & {\n readContract?: ClientEvmSigner[\"readContract\"];\n },\n publicClient?: {\n readContract(args: {\n address: `0x${string}`;\n abi: readonly unknown[];\n functionName: string;\n args?: readonly unknown[];\n }): Promise<unknown>;\n getTransactionCount?(args: { address: `0x${string}` }): Promise<number>;\n estimateFeesPerGas?(): Promise<{ maxFeePerGas: bigint; maxPriorityFeePerGas: bigint }>;\n },\n): ClientEvmSigner {\n const readContract = signer.readContract ?? publicClient?.readContract.bind(publicClient);\n\n const result: ClientEvmSigner = {\n address: signer.address,\n signTypedData: msg => signer.signTypedData(msg),\n };\n\n if (readContract) {\n result.readContract = readContract;\n }\n\n // Forward optional capabilities from signer or publicClient\n const signTransaction = signer.signTransaction;\n if (signTransaction) {\n result.signTransaction = args => signTransaction(args);\n }\n\n const getTransactionCount =\n signer.getTransactionCount ?? publicClient?.getTransactionCount?.bind(publicClient);\n if (getTransactionCount) {\n result.getTransactionCount = args => getTransactionCount(args);\n }\n\n const estimateFeesPerGas =\n signer.estimateFeesPerGas ?? publicClient?.estimateFeesPerGas?.bind(publicClient);\n if (estimateFeesPerGas) {\n result.estimateFeesPerGas = () => estimateFeesPerGas();\n }\n\n return result;\n}\n\n/**\n * Converts a viem client with single address to a FacilitatorEvmSigner\n * Wraps the single address in a getAddresses() function for compatibility\n *\n * @param client - The client to convert (must have 'address' property)\n * @returns FacilitatorEvmSigner with getAddresses() support\n */\nexport function toFacilitatorEvmSigner(\n client: Omit<FacilitatorEvmSigner, \"getAddresses\"> & { address: `0x${string}` },\n): FacilitatorEvmSigner {\n return {\n ...client,\n getAddresses: () => [client.address],\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AA+HO,SAAS,kBACd,QAGA,cAUiB;AACjB,QAAM,eAAe,OAAO,gBAAgB,cAAc,aAAa,KAAK,YAAY;AAExF,QAAM,SAA0B;AAAA,IAC9B,SAAS,OAAO;AAAA,IAChB,eAAe,SAAO,OAAO,cAAc,GAAG;AAAA,EAChD;AAEA,MAAI,cAAc;AAChB,WAAO,eAAe;AAAA,EACxB;AAGA,QAAM,kBAAkB,OAAO;AAC/B,MAAI,iBAAiB;AACnB,WAAO,kBAAkB,UAAQ,gBAAgB,IAAI;AAAA,EACvD;AAEA,QAAM,sBACJ,OAAO,uBAAuB,cAAc,qBAAqB,KAAK,YAAY;AACpF,MAAI,qBAAqB;AACvB,WAAO,sBAAsB,UAAQ,oBAAoB,IAAI;AAAA,EAC/D;AAEA,QAAM,qBACJ,OAAO,sBAAsB,cAAc,oBAAoB,KAAK,YAAY;AAClF,MAAI,oBAAoB;AACtB,WAAO,qBAAqB,MAAM,mBAAmB;AAAA,EACvD;AAEA,SAAO;AACT;AASO,SAAS,uBACd,QACsB;AACtB,SAAO;AAAA,IACL,GAAG;AAAA,IACH,cAAc,MAAM,CAAC,OAAO,OAAO;AAAA,EACrC;AACF;","names":[]}
@@ -1,5 +1,11 @@
1
1
  import { SchemeNetworkClient, PaymentRequirements, PaymentPayloadContext, PaymentPayloadResult } from '@x402/core/types';
2
- import { C as ClientEvmSigner } from './signer-DC81R8wQ.mjs';
2
+ import { C as ClientEvmSigner } from './signer-D912R4mq.mjs';
3
+
4
+ type ExactEvmSchemeConfig = {
5
+ rpcUrl?: string;
6
+ };
7
+ type ExactEvmSchemeConfigByChainId = Record<number, ExactEvmSchemeConfig>;
8
+ type ExactEvmSchemeOptions = ExactEvmSchemeConfig | ExactEvmSchemeConfigByChainId;
3
9
 
4
10
  /**
5
11
  * EVM client implementation for the Exact payment scheme.
@@ -15,15 +21,18 @@ import { C as ClientEvmSigner } from './signer-DC81R8wQ.mjs';
15
21
  */
16
22
  declare class ExactEvmScheme implements SchemeNetworkClient {
17
23
  private readonly signer;
24
+ private readonly options?;
18
25
  readonly scheme = "exact";
19
26
  /**
20
27
  * Creates a new ExactEvmClient instance.
21
28
  *
22
29
  * @param signer - The EVM signer for client operations.
23
- * Must support `readContract` for EIP-2612 gas sponsoring.
24
- * Use `createWalletClient(...).extend(publicActions)` or `toClientEvmSigner(account, publicClient)`.
30
+ * Base flow only requires `address` + `signTypedData`.
31
+ * Extension enrichment (EIP-2612 / ERC-20 approval sponsoring) additionally
32
+ * requires optional capabilities like `readContract` and tx signing helpers.
33
+ * @param options - Optional RPC configuration used to backfill extension capabilities.
25
34
  */
26
- constructor(signer: ClientEvmSigner);
35
+ constructor(signer: ClientEvmSigner, options?: ExactEvmSchemeOptions | undefined);
27
36
  /**
28
37
  * Creates a payment payload for the Exact scheme.
29
38
  * Routes to EIP-3009 or Permit2 based on requirements.extra.assetTransferMethod.
@@ -215,6 +224,30 @@ declare const eip3009ABI: readonly [{
215
224
  }];
216
225
  readonly stateMutability: "view";
217
226
  readonly type: "function";
227
+ }, {
228
+ readonly inputs: readonly [];
229
+ readonly name: "name";
230
+ readonly outputs: readonly [{
231
+ readonly name: "";
232
+ readonly type: "string";
233
+ }];
234
+ readonly stateMutability: "view";
235
+ readonly type: "function";
236
+ }, {
237
+ readonly inputs: readonly [{
238
+ readonly name: "authorizer";
239
+ readonly type: "address";
240
+ }, {
241
+ readonly name: "nonce";
242
+ readonly type: "bytes32";
243
+ }];
244
+ readonly name: "authorizationState";
245
+ readonly outputs: readonly [{
246
+ readonly name: "";
247
+ readonly type: "bool";
248
+ }];
249
+ readonly stateMutability: "view";
250
+ readonly type: "function";
218
251
  }];
219
252
  /** ERC-20 allowance(address,address) ABI for checking spender approval. */
220
253
  declare const erc20AllowanceAbi: readonly [{
@@ -514,4 +547,4 @@ declare function getPermit2AllowanceReadParams(params: Permit2AllowanceParams):
514
547
  args: [`0x${string}`, `0x${string}`];
515
548
  };
516
549
 
517
- export { ExactEvmScheme as E, type Permit2AllowanceParams as P, PERMIT2_ADDRESS as a, x402UptoPermit2ProxyAddress as b, createPermit2ApprovalTx as c, authorizationTypes as d, erc20AllowanceAbi as e, eip3009ABI as f, getPermit2AllowanceReadParams as g, x402ExactPermit2ProxyABI as h, permit2WitnessTypes as p, x402ExactPermit2ProxyAddress as x };
550
+ export { ExactEvmScheme as E, type Permit2AllowanceParams as P, PERMIT2_ADDRESS as a, x402UptoPermit2ProxyAddress as b, createPermit2ApprovalTx as c, authorizationTypes as d, erc20AllowanceAbi as e, eip3009ABI as f, getPermit2AllowanceReadParams as g, x402ExactPermit2ProxyABI as h, type ExactEvmSchemeOptions as i, type ExactEvmSchemeConfig as j, type ExactEvmSchemeConfigByChainId as k, permit2WitnessTypes as p, x402ExactPermit2ProxyAddress as x };
@@ -20,7 +20,11 @@ type ClientEvmSigner = {
20
20
  primaryType: string;
21
21
  message: Record<string, unknown>;
22
22
  }): Promise<`0x${string}`>;
23
- readContract(args: {
23
+ /**
24
+ * Optional on-chain reads.
25
+ * Required only for extension enrichment (EIP-2612 / ERC-20 approval).
26
+ */
27
+ readContract?(args: {
24
28
  address: `0x${string}`;
25
29
  abi: readonly unknown[];
26
30
  functionName: string;
@@ -87,6 +91,8 @@ type FacilitatorEvmSigner = {
87
91
  abi: readonly unknown[];
88
92
  functionName: string;
89
93
  args: readonly unknown[];
94
+ /** Optional gas limit. When provided, skips eth_estimateGas simulation. */
95
+ gas?: bigint;
90
96
  }): Promise<`0x${string}`>;
91
97
  sendTransaction(args: {
92
98
  to: `0x${string}`;
@@ -117,11 +123,11 @@ type FacilitatorEvmSigner = {
117
123
  * ```
118
124
  *
119
125
  * @param signer - A signer with `address` and `signTypedData` (and optionally `readContract`)
120
- * @param publicClient - A client with `readContract` (required if signer lacks it)
126
+ * @param publicClient - A client with optional read/nonce/fee helpers
121
127
  * @param publicClient.readContract - The readContract method from the public client
122
128
  * @param publicClient.getTransactionCount - Optional getTransactionCount for ERC-20 approval
123
129
  * @param publicClient.estimateFeesPerGas - Optional estimateFeesPerGas for ERC-20 approval
124
- * @returns A complete ClientEvmSigner
130
+ * @returns A ClientEvmSigner with any available optional capabilities
125
131
  *
126
132
  * @example
127
133
  * ```typescript
@@ -1,6 +1,6 @@
1
1
  export { ExactEvmSchemeV1 } from '../exact/v1/client/index.mjs';
2
2
  import '@x402/core/types';
3
- import '../signer-DC81R8wQ.mjs';
3
+ import '../signer-D912R4mq.mjs';
4
4
 
5
5
  declare const EVM_NETWORK_CHAIN_ID_MAP: {
6
6
  readonly ethereum: 1;
@@ -3,7 +3,7 @@ import {
3
3
  ExactEvmSchemeV12 as ExactEvmSchemeV1,
4
4
  NETWORKS,
5
5
  getEvmChainIdV1
6
- } from "../chunk-XL6IFXCP.mjs";
6
+ } from "../chunk-IZEI7JTG.mjs";
7
7
  export {
8
8
  EVM_NETWORK_CHAIN_ID_MAP,
9
9
  ExactEvmSchemeV1,