@payai/x402-evm 2.3.6 → 2.4.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 (78) hide show
  1. package/dist/cjs/exact/client/index.d.ts +3 -2
  2. package/dist/cjs/exact/client/index.js +173 -194
  3. package/dist/cjs/exact/client/index.js.map +1 -1
  4. package/dist/cjs/exact/facilitator/index.js +199 -185
  5. package/dist/cjs/exact/facilitator/index.js.map +1 -1
  6. package/dist/cjs/exact/server/index.d.ts +18 -17
  7. package/dist/cjs/exact/server/index.js +100 -55
  8. package/dist/cjs/exact/server/index.js.map +1 -1
  9. package/dist/cjs/exact/v1/client/index.js +3 -1
  10. package/dist/cjs/exact/v1/client/index.js.map +1 -1
  11. package/dist/cjs/exact/v1/facilitator/index.js +3 -1
  12. package/dist/cjs/exact/v1/facilitator/index.js.map +1 -1
  13. package/dist/cjs/index.d.ts +38 -2
  14. package/dist/cjs/index.js +441 -191
  15. package/dist/cjs/index.js.map +1 -1
  16. package/dist/cjs/{permit2-U9Zolx3O.d.ts → permit2-CyZxwngN.d.ts} +278 -87
  17. package/dist/cjs/scheme-CXDF0D2A.d.ts +47 -0
  18. package/dist/cjs/upto/client/index.d.ts +32 -0
  19. package/dist/cjs/upto/client/index.js +507 -0
  20. package/dist/cjs/upto/client/index.js.map +1 -0
  21. package/dist/cjs/upto/facilitator/index.d.ts +52 -0
  22. package/dist/cjs/upto/facilitator/index.js +1233 -0
  23. package/dist/cjs/upto/facilitator/index.js.map +1 -0
  24. package/dist/cjs/upto/server/index.d.ts +77 -0
  25. package/dist/cjs/upto/server/index.js +246 -0
  26. package/dist/cjs/upto/server/index.js.map +1 -0
  27. package/dist/cjs/v1/index.d.ts +2 -0
  28. package/dist/cjs/v1/index.js +3 -1
  29. package/dist/cjs/v1/index.js.map +1 -1
  30. package/dist/esm/chunk-C4ZQMS77.mjs +629 -0
  31. package/dist/esm/chunk-C4ZQMS77.mjs.map +1 -0
  32. package/dist/esm/chunk-CRT6YNY5.mjs +529 -0
  33. package/dist/esm/chunk-CRT6YNY5.mjs.map +1 -0
  34. package/dist/esm/chunk-D6RXZXOS.mjs +158 -0
  35. package/dist/esm/chunk-D6RXZXOS.mjs.map +1 -0
  36. package/dist/esm/chunk-GJ57SZGI.mjs +121 -0
  37. package/dist/esm/chunk-GJ57SZGI.mjs.map +1 -0
  38. package/dist/esm/chunk-JII456TS.mjs +34 -0
  39. package/dist/esm/chunk-JII456TS.mjs.map +1 -0
  40. package/dist/esm/chunk-NSFLAANF.mjs +80 -0
  41. package/dist/esm/chunk-NSFLAANF.mjs.map +1 -0
  42. package/dist/esm/{chunk-PCJKIY5G.mjs → chunk-RYT6M3PA.mjs} +29 -501
  43. package/dist/esm/chunk-RYT6M3PA.mjs.map +1 -0
  44. package/dist/esm/chunk-WKBC5YMI.mjs +291 -0
  45. package/dist/esm/chunk-WKBC5YMI.mjs.map +1 -0
  46. package/dist/esm/exact/client/index.d.mts +3 -2
  47. package/dist/esm/exact/client/index.mjs +8 -5
  48. package/dist/esm/exact/facilitator/index.mjs +84 -430
  49. package/dist/esm/exact/facilitator/index.mjs.map +1 -1
  50. package/dist/esm/exact/server/index.d.mts +18 -17
  51. package/dist/esm/exact/server/index.mjs +28 -55
  52. package/dist/esm/exact/server/index.mjs.map +1 -1
  53. package/dist/esm/exact/v1/client/index.mjs +2 -1
  54. package/dist/esm/exact/v1/facilitator/index.mjs +2 -1
  55. package/dist/esm/index.d.mts +38 -2
  56. package/dist/esm/index.mjs +21 -8
  57. package/dist/esm/index.mjs.map +1 -1
  58. package/dist/esm/{permit2-Bbh3a8_h.d.mts → permit2-CyZxwngN.d.mts} +278 -87
  59. package/dist/esm/scheme-DCR7hsa3.d.mts +47 -0
  60. package/dist/esm/upto/client/index.d.mts +32 -0
  61. package/dist/esm/upto/client/index.mjs +18 -0
  62. package/dist/esm/upto/client/index.mjs.map +1 -0
  63. package/dist/esm/upto/facilitator/index.d.mts +52 -0
  64. package/dist/esm/upto/facilitator/index.mjs +473 -0
  65. package/dist/esm/upto/facilitator/index.mjs.map +1 -0
  66. package/dist/esm/upto/server/index.d.mts +77 -0
  67. package/dist/esm/upto/server/index.mjs +145 -0
  68. package/dist/esm/upto/server/index.mjs.map +1 -0
  69. package/dist/esm/v1/index.d.mts +2 -0
  70. package/dist/esm/v1/index.mjs +2 -1
  71. package/package.json +31 -1
  72. package/dist/esm/chunk-GD4MKCN7.mjs +0 -57
  73. package/dist/esm/chunk-GD4MKCN7.mjs.map +0 -1
  74. package/dist/esm/chunk-LWO35IGS.mjs +0 -518
  75. package/dist/esm/chunk-LWO35IGS.mjs.map +0 -1
  76. package/dist/esm/chunk-PCJKIY5G.mjs.map +0 -1
  77. package/dist/esm/chunk-TKN5V2BV.mjs +0 -13
  78. package/dist/esm/chunk-TKN5V2BV.mjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/exact/extensions.ts","../../src/shared/permit2.ts","../../src/shared/erc20approval.ts","../../src/upto/facilitator/errors.ts"],"sourcesContent":["import type { PaymentPayload } from \"@payai/x402/types\";\nimport type { FacilitatorEvmSigner } from \"../signer\";\n\nexport const EIP2612_GAS_SPONSORING_KEY = \"eip2612GasSponsoring\" as const;\nexport const ERC20_APPROVAL_GAS_SPONSORING_KEY = \"erc20ApprovalGasSponsoring\" as const;\nexport const ERC20_APPROVAL_GAS_SPONSORING_VERSION = \"1\" as const;\n\nexport interface Eip2612GasSponsoringInfo {\n [key: string]: unknown;\n from: string;\n asset: string;\n spender: string;\n amount: string;\n nonce: string;\n deadline: string;\n signature: string;\n version: string;\n}\n\nexport interface Erc20ApprovalGasSponsoringInfo {\n [key: string]: unknown;\n from: `0x${string}`;\n asset: `0x${string}`;\n spender: `0x${string}`;\n amount: string;\n signedTransaction: `0x${string}`;\n version: string;\n}\n\n/**\n * A single transaction to be executed by the signer.\n * - `0x${string}`: a pre-signed serialized transaction (broadcast as-is via sendRawTransaction)\n * - `{ to, data, gas? }`: an unsigned call intent (signer signs and broadcasts)\n */\nexport type TransactionRequest =\n | `0x${string}`\n | { to: `0x${string}`; data: `0x${string}`; gas?: bigint };\n\nexport type Erc20ApprovalGasSponsoringSigner = FacilitatorEvmSigner & {\n sendTransactions(transactions: TransactionRequest[]): Promise<`0x${string}`[]>;\n simulateTransactions?(transactions: TransactionRequest[]): Promise<boolean>;\n};\n\nexport interface Erc20ApprovalGasSponsoringFacilitatorExtension {\n key: typeof ERC20_APPROVAL_GAS_SPONSORING_KEY;\n signer?: Erc20ApprovalGasSponsoringSigner;\n signerForNetwork?: (network: string) => Erc20ApprovalGasSponsoringSigner | undefined;\n}\n\n/**\n * Extracts a typed `info` payload from an extension entry.\n *\n * @param payload - Payment payload containing optional extensions.\n * @param extensionKey - Extension key to extract.\n * @returns The extension `info` object when present; otherwise null.\n */\nfunction _extractInfo(\n payload: PaymentPayload,\n extensionKey: string,\n): Record<string, unknown> | null {\n const extensions = payload.extensions;\n if (!extensions) return null;\n const extension = extensions[extensionKey] as { info?: Record<string, unknown> } | undefined;\n if (!extension?.info) return null;\n return extension.info;\n}\n\n/**\n * Extracts and validates required EIP-2612 gas sponsoring fields.\n *\n * @param payload - Payment payload returned by the client scheme.\n * @returns Parsed EIP-2612 gas sponsoring info when available and complete.\n */\nexport function extractEip2612GasSponsoringInfo(\n payload: PaymentPayload,\n): Eip2612GasSponsoringInfo | null {\n const info = _extractInfo(payload, EIP2612_GAS_SPONSORING_KEY);\n if (!info) return null;\n if (\n !info.from ||\n !info.asset ||\n !info.spender ||\n !info.amount ||\n !info.nonce ||\n !info.deadline ||\n !info.signature ||\n !info.version\n ) {\n return null;\n }\n return info as unknown as Eip2612GasSponsoringInfo;\n}\n\n/**\n * Validates the structure and formatting of EIP-2612 sponsoring info.\n *\n * @param info - EIP-2612 extension info to validate.\n * @returns True when all required fields match expected patterns.\n */\nexport function validateEip2612GasSponsoringInfo(info: Eip2612GasSponsoringInfo): boolean {\n const addressPattern = /^0x[a-fA-F0-9]{40}$/;\n const numericPattern = /^[0-9]+$/;\n const hexPattern = /^0x[a-fA-F0-9]+$/;\n const versionPattern = /^[0-9]+(\\.[0-9]+)*$/;\n return (\n addressPattern.test(info.from) &&\n addressPattern.test(info.asset) &&\n addressPattern.test(info.spender) &&\n numericPattern.test(info.amount) &&\n numericPattern.test(info.nonce) &&\n numericPattern.test(info.deadline) &&\n hexPattern.test(info.signature) &&\n versionPattern.test(info.version)\n );\n}\n\n/**\n * Extracts and validates required ERC-20 approval sponsoring fields.\n *\n * @param payload - Payment payload returned by the client scheme.\n * @returns Parsed ERC-20 approval sponsoring info when available and complete.\n */\nexport function extractErc20ApprovalGasSponsoringInfo(\n payload: PaymentPayload,\n): Erc20ApprovalGasSponsoringInfo | null {\n const info = _extractInfo(payload, ERC20_APPROVAL_GAS_SPONSORING_KEY);\n if (!info) return null;\n if (\n !info.from ||\n !info.asset ||\n !info.spender ||\n !info.amount ||\n !info.signedTransaction ||\n !info.version\n ) {\n return null;\n }\n return info as unknown as Erc20ApprovalGasSponsoringInfo;\n}\n\n/**\n * Validates the structure and formatting of ERC-20 approval sponsoring info.\n *\n * @param info - ERC-20 approval extension info to validate.\n * @returns True when all required fields match expected patterns.\n */\nexport function validateErc20ApprovalGasSponsoringInfo(\n info: Erc20ApprovalGasSponsoringInfo,\n): boolean {\n const addressPattern = /^0x[a-fA-F0-9]{40}$/;\n const numericPattern = /^[0-9]+$/;\n const hexPattern = /^0x[a-fA-F0-9]+$/;\n const versionPattern = /^[0-9]+(\\.[0-9]+)*$/;\n return (\n addressPattern.test(info.from) &&\n addressPattern.test(info.asset) &&\n addressPattern.test(info.spender) &&\n numericPattern.test(info.amount) &&\n hexPattern.test(info.signedTransaction) &&\n versionPattern.test(info.version)\n );\n}\n\n/**\n * Resolves the ERC-20 approval extension signer for a specific network.\n *\n * @param extension - Optional facilitator extension config.\n * @param network - CAIP-2 network identifier.\n * @returns A network-specific signer when available, else the default signer.\n */\nexport function resolveErc20ApprovalExtensionSigner(\n extension: Erc20ApprovalGasSponsoringFacilitatorExtension | undefined,\n network: string,\n): Erc20ApprovalGasSponsoringSigner | undefined {\n if (!extension) return undefined;\n return extension.signerForNetwork?.(network) ?? extension.signer;\n}\n","import {\n PaymentPayload,\n PaymentPayloadResult,\n PaymentRequirements,\n FacilitatorContext,\n SettleResponse,\n VerifyResponse,\n} from \"@payai/x402/types\";\nimport {\n extractEip2612GasSponsoringInfo,\n validateEip2612GasSponsoringInfo,\n extractErc20ApprovalGasSponsoringInfo,\n ERC20_APPROVAL_GAS_SPONSORING_KEY,\n type Eip2612GasSponsoringInfo,\n type Erc20ApprovalGasSponsoringFacilitatorExtension,\n type Erc20ApprovalGasSponsoringSigner,\n} from \"../exact/extensions\";\nimport { getAddress, encodeFunctionData } from \"viem\";\nimport { PERMIT2_ADDRESS, eip3009ABI, erc20AllowanceAbi, permit2WitnessTypes } from \"../constants\";\nimport { multicall, ContractCall } from \"../multicall\";\nimport { createPermit2Nonce, getEvmChainId } from \"../utils\";\nimport {\n ErrPermit2612AmountMismatch,\n ErrPermit2InvalidAmount,\n ErrPermit2InvalidDestination,\n ErrPermit2InvalidNonce,\n ErrPermit2InvalidOwner,\n ErrPermit2InvalidSignature,\n ErrPermit2PaymentTooEarly,\n ErrPermit2AllowanceRequired,\n ErrPermit2SimulationFailed,\n ErrPermit2InsufficientBalance,\n ErrPermit2ProxyNotDeployed,\n ErrInvalidTransactionState,\n ErrTransactionFailed,\n ErrInvalidEip2612ExtensionFormat,\n ErrEip2612FromMismatch,\n ErrEip2612AssetMismatch,\n ErrEip2612SpenderNotPermit2,\n ErrEip2612DeadlineExpired,\n ErrErc20ApprovalTxFailed,\n} from \"../exact/facilitator/errors\";\nimport { ClientEvmSigner, FacilitatorEvmSigner } from \"../signer\";\nimport { ExactPermit2Payload, Permit2Authorization, UptoPermit2Payload } from \"../types\";\nimport { validateErc20ApprovalForPayment } from \"./erc20approval\";\nimport {\n ErrUptoAmountExceedsPermitted,\n ErrUptoUnauthorizedFacilitator,\n} from \"../upto/facilitator/errors\";\n\n/**\n * Base type for Permit2 payloads shared between exact and upto schemes.\n * Both {@link ExactPermit2Payload} and {@link UptoPermit2Payload} satisfy this type.\n */\nexport type Permit2PayloadBase = ExactPermit2Payload | UptoPermit2Payload;\n\n/**\n * Configuration for the Permit2 proxy contract used during settlement.\n * The exact and upto schemes use different proxy addresses and ABIs.\n */\nexport type Permit2ProxyConfig = {\n /** The deployed proxy contract address. */\n proxyAddress: `0x${string}`;\n /** The proxy contract ABI (must include settle and settleWithPermit functions). */\n proxyABI: readonly Record<string, unknown>[];\n};\n\n/**\n * Checks Permit2 allowance and validates gas sponsoring extensions if allowance is insufficient.\n *\n * When the on-chain ERC-20 allowance to the Permit2 contract is below the required amount,\n * this function falls back to validating EIP-2612 or ERC-20 approval gas sponsoring extensions\n * attached to the payment payload.\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 */\nexport async 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 // Allowance check failed — validate extensions if present; fail closed if none valid\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;\n }\n\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;\n }\n }\n\n return { isValid: false, invalidReason: \"permit2_allowance_required\", payer };\n }\n}\n\n/**\n * Waits for a transaction 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 a settlement response indicating success or failure\n */\nexport async function waitAndReturnSettleResponse(\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: 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 * Inspects the error message for known contract revert strings and maps them\n * to the corresponding error reason constants. Falls back to a generic\n * \"transaction_failed\" reason with truncated message for unrecognized errors.\n *\n * @param error - The caught error (typically from a contract write)\n * @param payload - The payment payload (for network info)\n * @param payer - The payer address\n * @returns A failed SettleResponse with the mapped error reason\n */\nexport function mapSettleError(\n error: unknown,\n payload: PaymentPayload,\n payer: `0x${string}`,\n): SettleResponse {\n let errorReason: string = ErrTransactionFailed;\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 if (message.includes(\"erc20_approval_tx_failed\")) {\n errorReason = ErrErc20ApprovalTxFailed;\n } else if (message.includes(\"AmountExceedsPermitted\")) {\n errorReason = ErrUptoAmountExceedsPermitted;\n } else if (message.includes(\"UnauthorizedFacilitator\")) {\n errorReason = ErrUptoUnauthorizedFacilitator;\n } else {\n errorReason = `${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 * Checks that the permit extension has a valid format and that the from address,\n * asset address, spender address, and deadline all match expectations.\n *\n * @param info - The EIP-2612 gas sponsoring info extracted from the payment payload\n * @param payer - The expected payer address\n * @param tokenAddress - The expected token address\n * @returns Validation result with isValid flag and optional invalidReason string\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: ErrInvalidEip2612ExtensionFormat };\n }\n\n if (getAddress(info.from as `0x${string}`) !== getAddress(payer)) {\n return { isValid: false, invalidReason: ErrEip2612FromMismatch };\n }\n\n if (getAddress(info.asset as `0x${string}`) !== tokenAddress) {\n return { isValid: false, invalidReason: ErrEip2612AssetMismatch };\n }\n\n if (getAddress(info.spender as `0x${string}`) !== getAddress(PERMIT2_ADDRESS)) {\n return { isValid: false, invalidReason: ErrEip2612SpenderNotPermit2 };\n }\n\n const now = Math.floor(Date.now() / 1000);\n if (BigInt(info.deadline) < BigInt(now + 6)) {\n return { isValid: false, invalidReason: ErrEip2612DeadlineExpired };\n }\n\n return { isValid: true };\n}\n\n// ---------------------------------------------------------------------------\n// Simulation helpers (shared across exact and upto)\n// ---------------------------------------------------------------------------\n\n/**\n * Simulates settle() via eth_call (readContract).\n * Returns true if simulation succeeded, false if it failed.\n *\n * @param config - The proxy contract configuration (address and ABI)\n * @param signer - EVM signer for contract reads\n * @param settleArgs - Pre-built settle function arguments (scheme-specific)\n * @returns true if simulation succeeded, false if it failed\n */\nexport async function simulatePermit2Settle(\n config: Permit2ProxyConfig,\n signer: FacilitatorEvmSigner,\n settleArgs: readonly unknown[],\n): Promise<boolean> {\n try {\n await signer.readContract({\n address: config.proxyAddress,\n abi: config.proxyABI,\n functionName: \"settle\",\n args: settleArgs,\n });\n return true;\n } catch {\n return false;\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 config - The proxy contract configuration (address and ABI)\n * @param signer - EVM signer for contract reads\n * @param settleArgs - Pre-built settle function arguments (scheme-specific)\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 config: Permit2ProxyConfig,\n signer: FacilitatorEvmSigner,\n settleArgs: readonly unknown[],\n eip2612Info: Eip2612GasSponsoringInfo,\n): Promise<boolean> {\n try {\n const { v, r, s } = splitEip2612Signature(eip2612Info.signature);\n\n await signer.readContract({\n address: config.proxyAddress,\n abi: config.proxyABI,\n functionName: \"settleWithPermit\",\n args: [\n {\n value: BigInt(eip2612Info.amount),\n deadline: BigInt(eip2612Info.deadline),\n r,\n s,\n v,\n },\n ...settleArgs,\n ],\n });\n return true;\n } catch {\n return false;\n }\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 config - The proxy contract configuration (address and ABI)\n * @param extensionSigner - The extension signer with simulateTransactions capability\n * @param settleArgs - Pre-built settle function arguments (scheme-specific)\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 true if the bundle simulation succeeded, false otherwise\n */\nexport async function simulatePermit2SettleWithErc20Approval(\n config: Permit2ProxyConfig,\n extensionSigner: Erc20ApprovalGasSponsoringSigner,\n settleArgs: readonly unknown[],\n erc20Info: { signedTransaction: string },\n): Promise<boolean> {\n if (!extensionSigner.simulateTransactions) {\n return false;\n }\n\n try {\n const settleData = encodeFunctionData({\n abi: config.proxyABI,\n functionName: \"settle\",\n args: settleArgs,\n });\n\n return await extensionSigner.simulateTransactions([\n erc20Info.signedTransaction as `0x${string}`,\n { to: config.proxyAddress, data: settleData, gas: BigInt(300_000) },\n ]);\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 config - The proxy contract configuration (address and ABI)\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 config: Permit2ProxyConfig,\n signer: FacilitatorEvmSigner,\n tokenAddress: `0x${string}`,\n permit2Payload: Permit2PayloadBase,\n amountRequired: string,\n): Promise<VerifyResponse> {\n const payer = permit2Payload.permit2Authorization.from;\n\n const diagnosticCalls: ContractCall[] = [\n {\n address: config.proxyAddress,\n abi: config.proxyABI,\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: 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: 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: ErrPermit2AllowanceRequired, payer };\n }\n }\n } catch {\n // Diagnostic multicall itself failed — fall through to generic error\n }\n\n return { isValid: false, invalidReason: 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 config - The proxy contract configuration (address and ABI)\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 config: Permit2ProxyConfig,\n signer: FacilitatorEvmSigner,\n tokenAddress: `0x${string}`,\n payer: `0x${string}`,\n amountRequired: string,\n): Promise<VerifyResponse> {\n const diagnosticCalls: ContractCall[] = [\n {\n address: config.proxyAddress,\n abi: config.proxyABI,\n functionName: \"PERMIT2\",\n },\n {\n address: tokenAddress,\n abi: eip3009ABI,\n functionName: \"balanceOf\",\n args: [payer],\n },\n ];\n\n try {\n const results = await multicall(signer.readContract.bind(signer), diagnosticCalls);\n\n const [proxyResult, balanceResult] = results;\n\n if (proxyResult.status === \"failure\") {\n return { isValid: false, invalidReason: 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: ErrPermit2InsufficientBalance, payer };\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 * Builds args for exact settle(permit, owner, witness, signature).\n *\n * @param permit2Payload - The Permit2 payload containing authorization and signature data\n * @returns Tuple of contract call arguments for the exact settle function\n */\nexport function buildExactPermit2SettleArgs(permit2Payload: Permit2PayloadBase) {\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 * Builds args for upto settle(permit, amount, owner, witness, signature).\n * The upto contract's settle() takes an additional `amount` parameter and the witness\n * includes a `facilitator` field.\n *\n * @param permit2Payload - The upto Permit2 payload containing authorization and signature data\n * @param settlementAmount - The amount to settle on-chain\n * @param facilitatorAddress - The facilitator address authorized in the witness\n * @returns Tuple of contract call arguments for the upto settle function\n */\nexport function buildUptoPermit2SettleArgs(\n permit2Payload: UptoPermit2Payload,\n settlementAmount: bigint,\n facilitatorAddress: `0x${string}`,\n) {\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 settlementAmount,\n getAddress(permit2Payload.permit2Authorization.from),\n {\n to: getAddress(permit2Payload.permit2Authorization.witness.to),\n facilitator: getAddress(facilitatorAddress),\n validAfter: BigInt(permit2Payload.permit2Authorization.witness.validAfter),\n },\n permit2Payload.signature,\n ] as const;\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 (with or without 0x prefix)\n * @returns Object with v (uint8), r (bytes32 hex), s (bytes32 hex)\n * @throws Error if the signature is not exactly 65 bytes (130 hex chars)\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// Client-side helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Creates a Permit2 payload for any scheme (exact or upto).\n * The only scheme-specific input is the proxy address used as the spender.\n *\n * @param proxyAddress - The x402 proxy contract address to set as spender\n * @param signer - The EVM client signer\n * @param x402Version - The x402 protocol version\n * @param paymentRequirements - The payment requirements\n * @returns Promise resolving to a payment payload result\n */\nexport async function createPermit2PayloadForProxy(\n proxyAddress: `0x${string}`,\n signer: ClientEvmSigner,\n x402Version: number,\n paymentRequirements: PaymentRequirements,\n): Promise<PaymentPayloadResult> {\n const now = Math.floor(Date.now() / 1000);\n const nonce = createPermit2Nonce();\n\n // Lower time bound - allow some clock skew\n const validAfter = (now - 600).toString();\n // Upper time bound is enforced by Permit2's deadline field\n const deadline = (now + paymentRequirements.maxTimeoutSeconds).toString();\n\n const permit2Authorization: Permit2Authorization & { from: `0x${string}` } = {\n from: signer.address,\n permitted: {\n token: getAddress(paymentRequirements.asset),\n amount: paymentRequirements.amount,\n },\n spender: proxyAddress,\n nonce,\n deadline,\n witness: {\n to: getAddress(paymentRequirements.payTo),\n validAfter,\n },\n };\n\n const signature = await signPermit2Authorization(\n signer,\n permit2Authorization,\n paymentRequirements,\n );\n\n return {\n x402Version,\n payload: { signature, permit2Authorization },\n };\n}\n\n/**\n * Signs a Permit2 authorization using EIP-712 with witness data.\n * The signature authorizes the proxy contract to transfer tokens on behalf of the signer.\n *\n * @param signer - The EVM client signer\n * @param permit2Authorization - The Permit2 authorization parameters\n * @param requirements - The payment requirements\n * @returns Promise resolving to the hex-encoded signature\n */\nasync function signPermit2Authorization(\n signer: ClientEvmSigner,\n permit2Authorization: Permit2Authorization & { from: `0x${string}` },\n requirements: PaymentRequirements,\n): Promise<`0x${string}`> {\n const chainId = getEvmChainId(requirements.network);\n\n return await signer.signTypedData({\n domain: { name: \"Permit2\", chainId, verifyingContract: PERMIT2_ADDRESS },\n types: permit2WitnessTypes,\n primaryType: \"PermitWitnessTransferFrom\",\n message: {\n permitted: {\n token: getAddress(permit2Authorization.permitted.token),\n amount: BigInt(permit2Authorization.permitted.amount),\n },\n spender: getAddress(permit2Authorization.spender),\n nonce: BigInt(permit2Authorization.nonce),\n deadline: BigInt(permit2Authorization.deadline),\n witness: {\n to: getAddress(permit2Authorization.witness.to),\n validAfter: BigInt(permit2Authorization.witness.validAfter),\n },\n },\n });\n}\n","import {\n getAddress,\n parseTransaction,\n decodeFunctionData,\n recoverTransactionAddress,\n type TransactionSerialized,\n} from \"viem\";\nimport type { VerifyResponse } from \"@payai/x402/types\";\nimport {\n validateErc20ApprovalGasSponsoringInfo,\n type Erc20ApprovalGasSponsoringInfo,\n} from \"../exact/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 \"../exact/facilitator/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","/**\n * Named error reason constants for the upto EVM facilitator.\n *\n * Shared Permit2 errors are re-exported from exact/facilitator/errors.ts.\n * Upto-specific errors are defined here.\n *\n * These strings must be character-for-character identical to the Go constants\n * to maintain cross-SDK parity.\n */\n\n// Re-export shared Permit2 errors\nexport {\n ErrPermit2InvalidSpender,\n ErrPermit2RecipientMismatch,\n ErrPermit2DeadlineExpired,\n ErrPermit2NotYetValid,\n ErrPermit2AmountMismatch,\n ErrPermit2TokenMismatch,\n ErrPermit2InvalidSignature,\n ErrPermit2AllowanceRequired,\n ErrPermit2InvalidAmount,\n ErrPermit2InvalidDestination,\n ErrPermit2InvalidOwner,\n ErrPermit2PaymentTooEarly,\n ErrPermit2InvalidNonce,\n ErrPermit2612AmountMismatch,\n ErrErc20ApprovalInvalidFormat,\n ErrErc20ApprovalFromMismatch,\n ErrErc20ApprovalAssetMismatch,\n ErrErc20ApprovalSpenderNotPermit2,\n ErrErc20ApprovalTxWrongTarget,\n ErrErc20ApprovalTxWrongSelector,\n ErrErc20ApprovalTxWrongSpender,\n ErrErc20ApprovalTxInvalidCalldata,\n ErrErc20ApprovalTxSignerMismatch,\n ErrErc20ApprovalTxInvalidSignature,\n ErrErc20ApprovalTxParseFailed,\n} from \"../../exact/facilitator/errors\";\n\n// Upto-specific errors\nexport const ErrUptoInvalidScheme = \"invalid_upto_evm_scheme\";\nexport const ErrUptoNetworkMismatch = \"invalid_upto_evm_network_mismatch\";\nexport const ErrUptoSettlementExceedsAmount = \"invalid_upto_evm_payload_settlement_exceeds_amount\";\nexport const ErrUptoAmountExceedsPermitted = \"upto_amount_exceeds_permitted\";\nexport const ErrUptoUnauthorizedFacilitator = \"upto_unauthorized_facilitator\";\nexport const ErrUptoFacilitatorMismatch = \"upto_facilitator_mismatch\";\n"],"mappings":"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","names":["getAddress","getAddress"]}
@@ -0,0 +1,158 @@
1
+ import {
2
+ ExactEvmSchemeV12 as ExactEvmSchemeV1,
3
+ NETWORKS
4
+ } from "./chunk-RYT6M3PA.mjs";
5
+ import {
6
+ createPermit2Payload,
7
+ trySignEip2612PermitExtension,
8
+ trySignErc20ApprovalExtension
9
+ } from "./chunk-WKBC5YMI.mjs";
10
+ import {
11
+ authorizationTypes,
12
+ createNonce,
13
+ getEvmChainId
14
+ } from "./chunk-C4ZQMS77.mjs";
15
+
16
+ // src/exact/client/eip3009.ts
17
+ import { getAddress } from "viem";
18
+ async function createEIP3009Payload(signer, x402Version, paymentRequirements) {
19
+ const nonce = createNonce();
20
+ const now = Math.floor(Date.now() / 1e3);
21
+ const authorization = {
22
+ from: signer.address,
23
+ to: getAddress(paymentRequirements.payTo),
24
+ value: paymentRequirements.amount,
25
+ validAfter: (now - 600).toString(),
26
+ validBefore: (now + paymentRequirements.maxTimeoutSeconds).toString(),
27
+ nonce
28
+ };
29
+ const signature = await signEIP3009Authorization(signer, authorization, paymentRequirements);
30
+ const payload = {
31
+ authorization,
32
+ signature
33
+ };
34
+ return {
35
+ x402Version,
36
+ payload
37
+ };
38
+ }
39
+ async function signEIP3009Authorization(signer, authorization, requirements) {
40
+ const chainId = getEvmChainId(requirements.network);
41
+ if (!requirements.extra?.name || !requirements.extra?.version) {
42
+ throw new Error(
43
+ `EIP-712 domain parameters (name, version) are required in payment requirements for asset ${requirements.asset}`
44
+ );
45
+ }
46
+ const { name, version } = requirements.extra;
47
+ const domain = {
48
+ name,
49
+ version,
50
+ chainId,
51
+ verifyingContract: getAddress(requirements.asset)
52
+ };
53
+ const message = {
54
+ from: getAddress(authorization.from),
55
+ to: getAddress(authorization.to),
56
+ value: BigInt(authorization.value),
57
+ validAfter: BigInt(authorization.validAfter),
58
+ validBefore: BigInt(authorization.validBefore),
59
+ nonce: authorization.nonce
60
+ };
61
+ return await signer.signTypedData({
62
+ domain,
63
+ types: authorizationTypes,
64
+ primaryType: "TransferWithAuthorization",
65
+ message
66
+ });
67
+ }
68
+
69
+ // src/exact/client/scheme.ts
70
+ var ExactEvmScheme = class {
71
+ /**
72
+ * Creates a new ExactEvmClient instance.
73
+ *
74
+ * @param signer - The EVM signer for client operations.
75
+ * Base flow only requires `address` + `signTypedData`.
76
+ * Extension enrichment (EIP-2612 / ERC-20 approval sponsoring) additionally
77
+ * requires optional capabilities like `readContract` and tx signing helpers.
78
+ * @param options - Optional RPC configuration used to backfill extension capabilities.
79
+ */
80
+ constructor(signer, options) {
81
+ this.signer = signer;
82
+ this.options = options;
83
+ this.scheme = "exact";
84
+ }
85
+ /**
86
+ * Creates a payment payload for the Exact scheme.
87
+ * Routes to EIP-3009 or Permit2 based on requirements.extra.assetTransferMethod.
88
+ *
89
+ * For Permit2 flows, if the server advertises `eip2612GasSponsoring` and the
90
+ * signer supports `readContract`, automatically signs an EIP-2612 permit
91
+ * when Permit2 allowance is insufficient.
92
+ *
93
+ * @param x402Version - The x402 protocol version
94
+ * @param paymentRequirements - The payment requirements
95
+ * @param context - Optional context with server-declared extensions
96
+ * @returns Promise resolving to a payment payload result (with optional extensions)
97
+ */
98
+ async createPaymentPayload(x402Version, paymentRequirements, context) {
99
+ const assetTransferMethod = paymentRequirements.extra?.assetTransferMethod ?? "eip3009";
100
+ if (assetTransferMethod === "permit2") {
101
+ const result = await createPermit2Payload(this.signer, x402Version, paymentRequirements);
102
+ const eip2612Extensions = await trySignEip2612PermitExtension(
103
+ this.signer,
104
+ this.options,
105
+ paymentRequirements,
106
+ result,
107
+ context
108
+ );
109
+ if (eip2612Extensions) {
110
+ return {
111
+ ...result,
112
+ extensions: eip2612Extensions
113
+ };
114
+ }
115
+ const erc20Extensions = await trySignErc20ApprovalExtension(
116
+ this.signer,
117
+ this.options,
118
+ paymentRequirements,
119
+ context
120
+ );
121
+ if (erc20Extensions) {
122
+ return {
123
+ ...result,
124
+ extensions: erc20Extensions
125
+ };
126
+ }
127
+ return result;
128
+ }
129
+ return createEIP3009Payload(this.signer, x402Version, paymentRequirements);
130
+ }
131
+ };
132
+
133
+ // src/exact/client/register.ts
134
+ function registerExactEvmScheme(client, config) {
135
+ const evmScheme = new ExactEvmScheme(config.signer, config.schemeOptions);
136
+ if (config.networks && config.networks.length > 0) {
137
+ config.networks.forEach((network) => {
138
+ client.register(network, evmScheme);
139
+ });
140
+ } else {
141
+ client.register("eip155:*", evmScheme);
142
+ }
143
+ NETWORKS.forEach((network) => {
144
+ client.registerV1(network, new ExactEvmSchemeV1(config.signer));
145
+ });
146
+ if (config.policies) {
147
+ config.policies.forEach((policy) => {
148
+ client.registerPolicy(policy);
149
+ });
150
+ }
151
+ return client;
152
+ }
153
+
154
+ export {
155
+ ExactEvmScheme,
156
+ registerExactEvmScheme
157
+ };
158
+ //# sourceMappingURL=chunk-D6RXZXOS.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/exact/client/eip3009.ts","../../src/exact/client/scheme.ts","../../src/exact/client/register.ts"],"sourcesContent":["import { PaymentRequirements, PaymentPayloadResult } from \"@payai/x402/types\";\nimport { getAddress } from \"viem\";\nimport { authorizationTypes } from \"../../constants\";\nimport { ClientEvmSigner } from \"../../signer\";\nimport { ExactEIP3009Payload } from \"../../types\";\nimport { createNonce, getEvmChainId } from \"../../utils\";\n\n/**\n * Creates an EIP-3009 (transferWithAuthorization) payload.\n *\n * @param signer - The EVM signer for client operations\n * @param x402Version - The x402 protocol version\n * @param paymentRequirements - The payment requirements\n * @returns Promise resolving to a payment payload result\n */\nexport async function createEIP3009Payload(\n signer: ClientEvmSigner,\n x402Version: number,\n paymentRequirements: PaymentRequirements,\n): Promise<PaymentPayloadResult> {\n const nonce = createNonce();\n const now = Math.floor(Date.now() / 1000);\n\n const authorization: ExactEIP3009Payload[\"authorization\"] = {\n from: signer.address,\n to: getAddress(paymentRequirements.payTo),\n value: paymentRequirements.amount,\n validAfter: (now - 600).toString(),\n validBefore: (now + paymentRequirements.maxTimeoutSeconds).toString(),\n nonce,\n };\n\n const signature = await signEIP3009Authorization(signer, authorization, paymentRequirements);\n\n const payload: ExactEIP3009Payload = {\n authorization,\n signature,\n };\n\n return {\n x402Version,\n payload,\n };\n}\n\n/**\n * Sign the EIP-3009 authorization using EIP-712.\n *\n * @param signer - The EVM signer\n * @param authorization - The authorization to sign\n * @param requirements - The payment requirements\n * @returns Promise resolving to the signature\n */\nasync function signEIP3009Authorization(\n signer: ClientEvmSigner,\n authorization: ExactEIP3009Payload[\"authorization\"],\n requirements: PaymentRequirements,\n): Promise<`0x${string}`> {\n const chainId = getEvmChainId(requirements.network);\n\n if (!requirements.extra?.name || !requirements.extra?.version) {\n throw new Error(\n `EIP-712 domain parameters (name, version) are required in payment requirements for asset ${requirements.asset}`,\n );\n }\n\n const { name, version } = requirements.extra;\n\n const domain = {\n name,\n version,\n chainId,\n verifyingContract: getAddress(requirements.asset),\n };\n\n const message = {\n from: getAddress(authorization.from),\n to: getAddress(authorization.to),\n value: BigInt(authorization.value),\n validAfter: BigInt(authorization.validAfter),\n validBefore: BigInt(authorization.validBefore),\n nonce: authorization.nonce,\n };\n\n return await signer.signTypedData({\n domain,\n types: authorizationTypes,\n primaryType: \"TransferWithAuthorization\",\n message,\n });\n}\n","import {\n SchemeNetworkClient,\n PaymentRequirements,\n PaymentPayloadResult,\n PaymentPayloadContext,\n} from \"@payai/x402/types\";\nimport { ClientEvmSigner } from \"../../signer\";\nimport { AssetTransferMethod } from \"../../types\";\nimport { createEIP3009Payload } from \"./eip3009\";\nimport { createPermit2Payload } from \"./permit2\";\nimport {\n trySignEip2612PermitExtension,\n trySignErc20ApprovalExtension,\n} from \"../../shared/extensions\";\nimport { ExactEvmSchemeOptions } from \"./rpc\";\n\n/**\n * EVM client implementation for the Exact payment scheme.\n * Supports both EIP-3009 (transferWithAuthorization) and Permit2 flows.\n *\n * Routes to the appropriate authorization method based on\n * `requirements.extra.assetTransferMethod`. Defaults to EIP-3009\n * for backward compatibility with older facilitators.\n *\n * When the server advertises `eip2612GasSponsoring` and the asset transfer\n * method is `permit2`, the scheme automatically signs an EIP-2612 permit\n * if the user lacks Permit2 approval. This requires `readContract` on the signer.\n */\nexport class ExactEvmScheme implements SchemeNetworkClient {\n readonly scheme = \"exact\";\n\n /**\n * Creates a new ExactEvmClient instance.\n *\n * @param signer - The EVM signer for client operations.\n * Base flow only requires `address` + `signTypedData`.\n * Extension enrichment (EIP-2612 / ERC-20 approval sponsoring) additionally\n * requires optional capabilities like `readContract` and tx signing helpers.\n * @param options - Optional RPC configuration used to backfill extension capabilities.\n */\n constructor(\n private readonly signer: ClientEvmSigner,\n private readonly options?: ExactEvmSchemeOptions,\n ) {}\n\n /**\n * Creates a payment payload for the Exact scheme.\n * Routes to EIP-3009 or Permit2 based on requirements.extra.assetTransferMethod.\n *\n * For Permit2 flows, if the server advertises `eip2612GasSponsoring` and the\n * signer supports `readContract`, automatically signs an EIP-2612 permit\n * when Permit2 allowance is insufficient.\n *\n * @param x402Version - The x402 protocol version\n * @param paymentRequirements - The payment requirements\n * @param context - Optional context with server-declared extensions\n * @returns Promise resolving to a payment payload result (with optional extensions)\n */\n async createPaymentPayload(\n x402Version: number,\n paymentRequirements: PaymentRequirements,\n context?: PaymentPayloadContext,\n ): Promise<PaymentPayloadResult> {\n const assetTransferMethod =\n (paymentRequirements.extra?.assetTransferMethod as AssetTransferMethod) ?? \"eip3009\";\n\n if (assetTransferMethod === \"permit2\") {\n const result = await createPermit2Payload(this.signer, x402Version, paymentRequirements);\n\n const eip2612Extensions = await trySignEip2612PermitExtension(\n this.signer,\n this.options,\n paymentRequirements,\n result,\n context,\n );\n\n if (eip2612Extensions) {\n return {\n ...result,\n extensions: eip2612Extensions,\n };\n }\n\n const erc20Extensions = await trySignErc20ApprovalExtension(\n this.signer,\n this.options,\n paymentRequirements,\n context,\n );\n if (erc20Extensions) {\n return {\n ...result,\n extensions: erc20Extensions,\n };\n }\n\n return result;\n }\n\n return createEIP3009Payload(this.signer, x402Version, paymentRequirements);\n }\n}\n","import { x402Client, SelectPaymentRequirements, PaymentPolicy } from \"@payai/x402/client\";\nimport { Network } from \"@payai/x402/types\";\nimport { ClientEvmSigner } from \"../../signer\";\nimport { ExactEvmScheme } from \"./scheme\";\nimport { ExactEvmSchemeOptions } from \"./rpc\";\nimport { ExactEvmSchemeV1 } from \"../v1/client/scheme\";\nimport { NETWORKS } from \"../../v1\";\n\n/**\n * Configuration options for registering EVM schemes to an x402Client\n */\nexport interface EvmClientConfig {\n /**\n * The EVM signer to use for creating payment payloads\n */\n signer: ClientEvmSigner;\n\n /**\n * Optional payment requirements selector function\n * If not provided, uses the default selector (first available option)\n */\n paymentRequirementsSelector?: SelectPaymentRequirements;\n\n /**\n * Optional policies to apply to the client\n */\n policies?: PaymentPolicy[];\n\n /**\n * Optional Exact EVM client scheme options.\n * Supports either a single config ({ rpcUrl }) or per-chain configs\n * keyed by EVM chain ID ({ 8453: { rpcUrl: \"...\" } }).\n */\n schemeOptions?: ExactEvmSchemeOptions;\n\n /**\n * Optional specific networks to register.\n * If not provided, registers wildcard support (eip155:*).\n */\n networks?: Network[];\n}\n\n/**\n * Registers EVM exact payment schemes to an x402Client instance.\n *\n * This function registers:\n * - V2: eip155:* wildcard scheme with ExactEvmScheme (or specific networks if provided)\n * - V1: All supported EVM networks with ExactEvmSchemeV1\n *\n * @param client - The x402Client instance to register schemes to\n * @param config - Configuration for EVM client registration\n * @returns The client instance for chaining\n *\n * @example\n * ```typescript\n * import { registerExactEvmScheme } from \"@payai/x402-evm/exact/client/register\";\n * import { x402Client } from \"@payai/x402/client\";\n * import { privateKeyToAccount } from \"viem/accounts\";\n *\n * const account = privateKeyToAccount(\"0x...\");\n * const client = new x402Client();\n * registerExactEvmScheme(client, { signer: account });\n * ```\n */\nexport function registerExactEvmScheme(client: x402Client, config: EvmClientConfig): x402Client {\n const evmScheme = new ExactEvmScheme(config.signer, config.schemeOptions);\n\n // Register V2 scheme\n // EIP-2612 gas sponsoring is handled internally by the scheme when the\n // server advertises support - no separate extension registration needed.\n if (config.networks && config.networks.length > 0) {\n // Register specific networks\n config.networks.forEach(network => {\n client.register(network, evmScheme);\n });\n } else {\n // Register wildcard for all EVM chains\n client.register(\"eip155:*\", evmScheme);\n }\n\n // Register all V1 networks\n NETWORKS.forEach(network => {\n client.registerV1(network as Network, new ExactEvmSchemeV1(config.signer));\n });\n\n // Apply policies if provided\n if (config.policies) {\n config.policies.forEach(policy => {\n client.registerPolicy(policy);\n });\n }\n\n return client;\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,121 @@
1
+ import {
2
+ trySignEip2612PermitExtension,
3
+ trySignErc20ApprovalExtension
4
+ } from "./chunk-WKBC5YMI.mjs";
5
+ import {
6
+ PERMIT2_ADDRESS,
7
+ createPermit2Nonce,
8
+ getEvmChainId,
9
+ uptoPermit2WitnessTypes,
10
+ x402UptoPermit2ProxyAddress
11
+ } from "./chunk-C4ZQMS77.mjs";
12
+
13
+ // src/upto/client/permit2.ts
14
+ import { getAddress } from "viem";
15
+ async function createUptoPermit2Payload(signer, x402Version, paymentRequirements) {
16
+ const facilitatorAddress = paymentRequirements.extra?.facilitatorAddress;
17
+ if (!facilitatorAddress) {
18
+ throw new Error(
19
+ "upto scheme requires facilitatorAddress in paymentRequirements.extra. Ensure the server is configured with an upto facilitator that provides getExtra()."
20
+ );
21
+ }
22
+ const now = Math.floor(Date.now() / 1e3);
23
+ const nonce = createPermit2Nonce();
24
+ const validAfter = (now - 600).toString();
25
+ const deadline = (now + paymentRequirements.maxTimeoutSeconds).toString();
26
+ if (BigInt(deadline) <= BigInt(validAfter)) {
27
+ throw new Error(
28
+ `Invalid time window: deadline (${deadline}) must be after validAfter (${validAfter}). Check that maxTimeoutSeconds (${paymentRequirements.maxTimeoutSeconds}) is positive.`
29
+ );
30
+ }
31
+ const permit2Authorization = {
32
+ from: signer.address,
33
+ permitted: {
34
+ token: getAddress(paymentRequirements.asset),
35
+ amount: paymentRequirements.amount
36
+ },
37
+ spender: x402UptoPermit2ProxyAddress,
38
+ nonce,
39
+ deadline,
40
+ witness: {
41
+ to: getAddress(paymentRequirements.payTo),
42
+ facilitator: getAddress(facilitatorAddress),
43
+ validAfter
44
+ }
45
+ };
46
+ const chainId = getEvmChainId(paymentRequirements.network);
47
+ const signature = await signer.signTypedData({
48
+ domain: { name: "Permit2", chainId, verifyingContract: PERMIT2_ADDRESS },
49
+ types: uptoPermit2WitnessTypes,
50
+ primaryType: "PermitWitnessTransferFrom",
51
+ message: {
52
+ permitted: {
53
+ token: getAddress(permit2Authorization.permitted.token),
54
+ amount: BigInt(permit2Authorization.permitted.amount)
55
+ },
56
+ spender: getAddress(permit2Authorization.spender),
57
+ nonce: BigInt(permit2Authorization.nonce),
58
+ deadline: BigInt(permit2Authorization.deadline),
59
+ witness: {
60
+ to: getAddress(permit2Authorization.witness.to),
61
+ facilitator: getAddress(permit2Authorization.witness.facilitator),
62
+ validAfter: BigInt(permit2Authorization.witness.validAfter)
63
+ }
64
+ }
65
+ });
66
+ return {
67
+ x402Version,
68
+ payload: { signature, permit2Authorization }
69
+ };
70
+ }
71
+
72
+ // src/upto/client/scheme.ts
73
+ var UptoEvmScheme = class {
74
+ /**
75
+ * Creates a new UptoEvmScheme instance.
76
+ *
77
+ * @param signer - The EVM signer for client operations
78
+ * @param options - Optional RPC configuration
79
+ */
80
+ constructor(signer, options) {
81
+ this.signer = signer;
82
+ this.options = options;
83
+ this.scheme = "upto";
84
+ }
85
+ /**
86
+ * Creates a payment payload for the Upto scheme using Permit2.
87
+ *
88
+ * @param x402Version - The x402 protocol version
89
+ * @param paymentRequirements - The payment requirements
90
+ * @param context - Optional context with server-declared extensions
91
+ * @returns Promise resolving to a payment payload result
92
+ */
93
+ async createPaymentPayload(x402Version, paymentRequirements, context) {
94
+ const result = await createUptoPermit2Payload(this.signer, x402Version, paymentRequirements);
95
+ const eip2612Extensions = await trySignEip2612PermitExtension(
96
+ this.signer,
97
+ this.options,
98
+ paymentRequirements,
99
+ result,
100
+ context
101
+ );
102
+ if (eip2612Extensions) {
103
+ return { ...result, extensions: eip2612Extensions };
104
+ }
105
+ const erc20Extensions = await trySignErc20ApprovalExtension(
106
+ this.signer,
107
+ this.options,
108
+ paymentRequirements,
109
+ context
110
+ );
111
+ if (erc20Extensions) {
112
+ return { ...result, extensions: erc20Extensions };
113
+ }
114
+ return result;
115
+ }
116
+ };
117
+
118
+ export {
119
+ UptoEvmScheme
120
+ };
121
+ //# sourceMappingURL=chunk-GJ57SZGI.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/upto/client/permit2.ts","../../src/upto/client/scheme.ts"],"sourcesContent":["import { PaymentRequirements, PaymentPayloadResult } from \"@payai/x402/types\";\nimport {\n PERMIT2_ADDRESS,\n uptoPermit2WitnessTypes,\n x402UptoPermit2ProxyAddress,\n} from \"../../constants\";\nimport { ClientEvmSigner } from \"../../signer\";\nimport { UptoPermit2Authorization } from \"../../types\";\nimport { createPermit2Nonce, getEvmChainId } from \"../../utils\";\nimport { getAddress } from \"viem\";\n\n// Re-export Permit2-generic approval helpers\nexport { createPermit2ApprovalTx, getPermit2AllowanceReadParams } from \"../../exact/client/permit2\";\nexport type { Permit2AllowanceParams } from \"../../exact/client/permit2\";\n\n/**\n * Creates a signed upto Permit2 payment payload for the given requirements.\n *\n * Constructs a Permit2 authorization with an upto witness (including facilitator address)\n * and signs it using EIP-712 typed data.\n *\n * @param signer - The EVM client signer for signing typed data\n * @param x402Version - The x402 protocol version\n * @param paymentRequirements - The payment requirements including asset, amount, and payTo\n * @returns Promise resolving to a payment payload result with the signed authorization\n */\nexport async function createUptoPermit2Payload(\n signer: ClientEvmSigner,\n x402Version: number,\n paymentRequirements: PaymentRequirements,\n): Promise<PaymentPayloadResult> {\n const facilitatorAddress = paymentRequirements.extra?.facilitatorAddress as\n | `0x${string}`\n | undefined;\n if (!facilitatorAddress) {\n throw new Error(\n \"upto scheme requires facilitatorAddress in paymentRequirements.extra. \" +\n \"Ensure the server is configured with an upto facilitator that provides getExtra().\",\n );\n }\n\n const now = Math.floor(Date.now() / 1000);\n const nonce = createPermit2Nonce();\n const validAfter = (now - 600).toString();\n const deadline = (now + paymentRequirements.maxTimeoutSeconds).toString();\n\n if (BigInt(deadline) <= BigInt(validAfter)) {\n throw new Error(\n `Invalid time window: deadline (${deadline}) must be after validAfter (${validAfter}). ` +\n `Check that maxTimeoutSeconds (${paymentRequirements.maxTimeoutSeconds}) is positive.`,\n );\n }\n\n const permit2Authorization: UptoPermit2Authorization & { from: `0x${string}` } = {\n from: signer.address,\n permitted: {\n token: getAddress(paymentRequirements.asset),\n amount: paymentRequirements.amount,\n },\n spender: x402UptoPermit2ProxyAddress,\n nonce,\n deadline,\n witness: {\n to: getAddress(paymentRequirements.payTo),\n facilitator: getAddress(facilitatorAddress),\n validAfter,\n },\n };\n\n const chainId = getEvmChainId(paymentRequirements.network);\n\n const signature = await signer.signTypedData({\n domain: { name: \"Permit2\", chainId, verifyingContract: PERMIT2_ADDRESS },\n types: uptoPermit2WitnessTypes,\n primaryType: \"PermitWitnessTransferFrom\",\n message: {\n permitted: {\n token: getAddress(permit2Authorization.permitted.token),\n amount: BigInt(permit2Authorization.permitted.amount),\n },\n spender: getAddress(permit2Authorization.spender),\n nonce: BigInt(permit2Authorization.nonce),\n deadline: BigInt(permit2Authorization.deadline),\n witness: {\n to: getAddress(permit2Authorization.witness.to),\n facilitator: getAddress(permit2Authorization.witness.facilitator),\n validAfter: BigInt(permit2Authorization.witness.validAfter),\n },\n },\n });\n\n return {\n x402Version,\n payload: { signature, permit2Authorization },\n };\n}\n","import {\n SchemeNetworkClient,\n PaymentRequirements,\n PaymentPayloadResult,\n PaymentPayloadContext,\n} from \"@payai/x402/types\";\nimport { ClientEvmSigner } from \"../../signer\";\nimport { createUptoPermit2Payload } from \"./permit2\";\nimport {\n trySignEip2612PermitExtension,\n trySignErc20ApprovalExtension,\n} from \"../../shared/extensions\";\nimport { UptoEvmSchemeOptions } from \"./rpc\";\n\n/**\n * EVM client implementation for the Upto payment scheme.\n * Handles Permit2-based payment payload creation and gas-sponsoring extensions.\n */\nexport class UptoEvmScheme implements SchemeNetworkClient {\n readonly scheme = \"upto\";\n\n /**\n * Creates a new UptoEvmScheme instance.\n *\n * @param signer - The EVM signer for client operations\n * @param options - Optional RPC configuration\n */\n constructor(\n private readonly signer: ClientEvmSigner,\n private readonly options?: UptoEvmSchemeOptions,\n ) {}\n\n /**\n * Creates a payment payload for the Upto scheme using Permit2.\n *\n * @param x402Version - The x402 protocol version\n * @param paymentRequirements - The payment requirements\n * @param context - Optional context with server-declared extensions\n * @returns Promise resolving to a payment payload result\n */\n async createPaymentPayload(\n x402Version: number,\n paymentRequirements: PaymentRequirements,\n context?: PaymentPayloadContext,\n ): Promise<PaymentPayloadResult> {\n const result = await createUptoPermit2Payload(this.signer, x402Version, paymentRequirements);\n\n const eip2612Extensions = await trySignEip2612PermitExtension(\n this.signer,\n this.options,\n paymentRequirements,\n result,\n context,\n );\n if (eip2612Extensions) {\n return { ...result, extensions: eip2612Extensions };\n }\n\n const erc20Extensions = await trySignErc20ApprovalExtension(\n this.signer,\n this.options,\n paymentRequirements,\n context,\n );\n if (erc20Extensions) {\n return { ...result, extensions: erc20Extensions };\n }\n\n return result;\n }\n}\n"],"mappings":";;;;;;;;;;;;;AASA,SAAS,kBAAkB;AAiB3B,eAAsB,yBACpB,QACA,aACA,qBAC+B;AAC/B,QAAM,qBAAqB,oBAAoB,OAAO;AAGtD,MAAI,CAAC,oBAAoB;AACvB,UAAM,IAAI;AAAA,MACR;AAAA,IAEF;AAAA,EACF;AAEA,QAAM,MAAM,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AACxC,QAAM,QAAQ,mBAAmB;AACjC,QAAM,cAAc,MAAM,KAAK,SAAS;AACxC,QAAM,YAAY,MAAM,oBAAoB,mBAAmB,SAAS;AAExE,MAAI,OAAO,QAAQ,KAAK,OAAO,UAAU,GAAG;AAC1C,UAAM,IAAI;AAAA,MACR,kCAAkC,QAAQ,+BAA+B,UAAU,oCAChD,oBAAoB,iBAAiB;AAAA,IAC1E;AAAA,EACF;AAEA,QAAM,uBAA2E;AAAA,IAC/E,MAAM,OAAO;AAAA,IACb,WAAW;AAAA,MACT,OAAO,WAAW,oBAAoB,KAAK;AAAA,MAC3C,QAAQ,oBAAoB;AAAA,IAC9B;AAAA,IACA,SAAS;AAAA,IACT;AAAA,IACA;AAAA,IACA,SAAS;AAAA,MACP,IAAI,WAAW,oBAAoB,KAAK;AAAA,MACxC,aAAa,WAAW,kBAAkB;AAAA,MAC1C;AAAA,IACF;AAAA,EACF;AAEA,QAAM,UAAU,cAAc,oBAAoB,OAAO;AAEzD,QAAM,YAAY,MAAM,OAAO,cAAc;AAAA,IAC3C,QAAQ,EAAE,MAAM,WAAW,SAAS,mBAAmB,gBAAgB;AAAA,IACvE,OAAO;AAAA,IACP,aAAa;AAAA,IACb,SAAS;AAAA,MACP,WAAW;AAAA,QACT,OAAO,WAAW,qBAAqB,UAAU,KAAK;AAAA,QACtD,QAAQ,OAAO,qBAAqB,UAAU,MAAM;AAAA,MACtD;AAAA,MACA,SAAS,WAAW,qBAAqB,OAAO;AAAA,MAChD,OAAO,OAAO,qBAAqB,KAAK;AAAA,MACxC,UAAU,OAAO,qBAAqB,QAAQ;AAAA,MAC9C,SAAS;AAAA,QACP,IAAI,WAAW,qBAAqB,QAAQ,EAAE;AAAA,QAC9C,aAAa,WAAW,qBAAqB,QAAQ,WAAW;AAAA,QAChE,YAAY,OAAO,qBAAqB,QAAQ,UAAU;AAAA,MAC5D;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL;AAAA,IACA,SAAS,EAAE,WAAW,qBAAqB;AAAA,EAC7C;AACF;;;AC7EO,IAAM,gBAAN,MAAmD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASxD,YACmB,QACA,SACjB;AAFiB;AACA;AAVnB,SAAS,SAAS;AAAA,EAWf;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUH,MAAM,qBACJ,aACA,qBACA,SAC+B;AAC/B,UAAM,SAAS,MAAM,yBAAyB,KAAK,QAAQ,aAAa,mBAAmB;AAE3F,UAAM,oBAAoB,MAAM;AAAA,MAC9B,KAAK;AAAA,MACL,KAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,QAAI,mBAAmB;AACrB,aAAO,EAAE,GAAG,QAAQ,YAAY,kBAAkB;AAAA,IACpD;AAEA,UAAM,kBAAkB,MAAM;AAAA,MAC5B,KAAK;AAAA,MACL,KAAK;AAAA,MACL;AAAA,MACA;AAAA,IACF;AACA,QAAI,iBAAiB;AACnB,aAAO,EAAE,GAAG,QAAQ,YAAY,gBAAgB;AAAA,IAClD;AAEA,WAAO;AAAA,EACT;AACF;","names":[]}
@@ -0,0 +1,34 @@
1
+ // src/types.ts
2
+ function isPermit2Payload(payload) {
3
+ return "permit2Authorization" in payload;
4
+ }
5
+ function isEIP3009Payload(payload) {
6
+ return "authorization" in payload;
7
+ }
8
+ function isUptoPermit2Payload(payload) {
9
+ if (typeof payload.signature !== "string") return false;
10
+ if (!("permit2Authorization" in payload)) return false;
11
+ const auth = payload.permit2Authorization;
12
+ if (typeof auth !== "object" || auth === null) return false;
13
+ const a = auth;
14
+ if (typeof a.from !== "string") return false;
15
+ if (typeof a.spender !== "string") return false;
16
+ if (typeof a.nonce !== "string") return false;
17
+ if (typeof a.deadline !== "string") return false;
18
+ const permitted = a.permitted;
19
+ if (typeof permitted !== "object" || permitted === null) return false;
20
+ const p = permitted;
21
+ if (typeof p.token !== "string") return false;
22
+ if (typeof p.amount !== "string") return false;
23
+ const witness = a.witness;
24
+ if (typeof witness !== "object" || witness === null) return false;
25
+ const w = witness;
26
+ return typeof w.facilitator === "string" && typeof w.to === "string" && typeof w.validAfter === "string";
27
+ }
28
+
29
+ export {
30
+ isPermit2Payload,
31
+ isEIP3009Payload,
32
+ isUptoPermit2Payload
33
+ };
34
+ //# sourceMappingURL=chunk-JII456TS.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/types.ts"],"sourcesContent":["/**\n * Asset transfer methods for the exact EVM scheme.\n * - eip3009: Uses transferWithAuthorization (USDC, etc.) - recommended for compatible tokens\n * - permit2: Uses Permit2 + x402Permit2Proxy - universal fallback for any ERC-20\n */\nexport type AssetTransferMethod = \"eip3009\" | \"permit2\";\n\n/**\n * EIP-3009 payload for tokens with native transferWithAuthorization support.\n */\nexport type ExactEIP3009Payload = {\n signature?: `0x${string}`;\n authorization: {\n from: `0x${string}`;\n to: `0x${string}`;\n value: string;\n validAfter: string;\n validBefore: string;\n nonce: `0x${string}`;\n };\n};\n\n/**\n * Permit2 witness data structure.\n * Matches the Witness struct in x402Permit2Proxy contract.\n * Note: Upper time bound is enforced by Permit2's `deadline` field, not a witness field.\n */\nexport type Permit2Witness = {\n to: `0x${string}`;\n validAfter: string;\n};\n\n/**\n * Permit2 authorization parameters.\n * Used to reconstruct the signed message for verification.\n */\nexport type Permit2Authorization = {\n permitted: {\n token: `0x${string}`;\n amount: string;\n };\n spender: `0x${string}`;\n nonce: string;\n deadline: string;\n witness: Permit2Witness;\n};\n\n/**\n * Permit2 payload for tokens using the Permit2 + x402Permit2Proxy flow.\n */\nexport type ExactPermit2Payload = {\n signature: `0x${string}`;\n permit2Authorization: Permit2Authorization & {\n from: `0x${string}`;\n };\n};\n\nexport type ExactEvmPayloadV1 = ExactEIP3009Payload;\n\nexport type ExactEvmPayloadV2 = ExactEIP3009Payload | ExactPermit2Payload;\n\n/**\n * Type guard to check if a payload is a Permit2 payload.\n * Permit2 payloads have a `permit2Authorization` field.\n *\n * @param payload - The payload to check.\n * @returns True if the payload is a Permit2 payload, false otherwise.\n */\nexport function isPermit2Payload(payload: ExactEvmPayloadV2): payload is ExactPermit2Payload {\n return \"permit2Authorization\" in payload;\n}\n\n/**\n * Type guard to check if a payload is an EIP-3009 payload.\n * EIP-3009 payloads have an `authorization` field.\n *\n * @param payload - The payload to check.\n * @returns True if the payload is an EIP-3009 payload, false otherwise.\n */\nexport function isEIP3009Payload(payload: ExactEvmPayloadV2): payload is ExactEIP3009Payload {\n return \"authorization\" in payload;\n}\n\n/**\n * Upto Permit2 witness — includes `facilitator` field absent from exact witness.\n * Only the address matching `witness.facilitator` can call settle() on-chain.\n */\nexport type UptoPermit2Witness = {\n to: `0x${string}`;\n facilitator: `0x${string}`;\n validAfter: string;\n};\n\nexport type UptoPermit2Authorization = {\n permitted: {\n token: `0x${string}`;\n amount: string;\n };\n spender: `0x${string}`;\n nonce: string;\n deadline: string;\n witness: UptoPermit2Witness;\n};\n\nexport type UptoPermit2Payload = {\n signature: `0x${string}`;\n permit2Authorization: UptoPermit2Authorization & {\n from: `0x${string}`;\n };\n};\n\n/**\n * Type guard to check if a payload is an upto Permit2 payload.\n * Validates structural presence of all required fields: signature, permit2Authorization\n * (with from, permitted, spender, nonce, deadline), and a witness containing facilitator.\n *\n * @param payload - The payload to check\n * @returns True if the payload is an upto Permit2 payload, false otherwise\n */\nexport function isUptoPermit2Payload(\n payload: Record<string, unknown>,\n): payload is UptoPermit2Payload {\n if (typeof payload.signature !== \"string\") return false;\n if (!(\"permit2Authorization\" in payload)) return false;\n\n const auth = payload.permit2Authorization;\n if (typeof auth !== \"object\" || auth === null) return false;\n\n const a = auth as Record<string, unknown>;\n if (typeof a.from !== \"string\") return false;\n if (typeof a.spender !== \"string\") return false;\n if (typeof a.nonce !== \"string\") return false;\n if (typeof a.deadline !== \"string\") return false;\n\n const permitted = a.permitted;\n if (typeof permitted !== \"object\" || permitted === null) return false;\n const p = permitted as Record<string, unknown>;\n if (typeof p.token !== \"string\") return false;\n if (typeof p.amount !== \"string\") return false;\n\n const witness = a.witness;\n if (typeof witness !== \"object\" || witness === null) return false;\n const w = witness as Record<string, unknown>;\n return (\n typeof w.facilitator === \"string\" &&\n typeof w.to === \"string\" &&\n typeof w.validAfter === \"string\"\n );\n}\n"],"mappings":";AAoEO,SAAS,iBAAiB,SAA4D;AAC3F,SAAO,0BAA0B;AACnC;AASO,SAAS,iBAAiB,SAA4D;AAC3F,SAAO,mBAAmB;AAC5B;AAsCO,SAAS,qBACd,SAC+B;AAC/B,MAAI,OAAO,QAAQ,cAAc,SAAU,QAAO;AAClD,MAAI,EAAE,0BAA0B,SAAU,QAAO;AAEjD,QAAM,OAAO,QAAQ;AACrB,MAAI,OAAO,SAAS,YAAY,SAAS,KAAM,QAAO;AAEtD,QAAM,IAAI;AACV,MAAI,OAAO,EAAE,SAAS,SAAU,QAAO;AACvC,MAAI,OAAO,EAAE,YAAY,SAAU,QAAO;AAC1C,MAAI,OAAO,EAAE,UAAU,SAAU,QAAO;AACxC,MAAI,OAAO,EAAE,aAAa,SAAU,QAAO;AAE3C,QAAM,YAAY,EAAE;AACpB,MAAI,OAAO,cAAc,YAAY,cAAc,KAAM,QAAO;AAChE,QAAM,IAAI;AACV,MAAI,OAAO,EAAE,UAAU,SAAU,QAAO;AACxC,MAAI,OAAO,EAAE,WAAW,SAAU,QAAO;AAEzC,QAAM,UAAU,EAAE;AAClB,MAAI,OAAO,YAAY,YAAY,YAAY,KAAM,QAAO;AAC5D,QAAM,IAAI;AACV,SACE,OAAO,EAAE,gBAAgB,YACzB,OAAO,EAAE,OAAO,YAChB,OAAO,EAAE,eAAe;AAE5B;","names":[]}
@@ -0,0 +1,80 @@
1
+ // src/shared/defaultAssets.ts
2
+ var DEFAULT_STABLECOINS = {
3
+ "eip155:8453": {
4
+ address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
5
+ name: "USD Coin",
6
+ version: "2",
7
+ decimals: 6
8
+ },
9
+ // Base mainnet USDC
10
+ "eip155:84532": {
11
+ address: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
12
+ name: "USDC",
13
+ version: "2",
14
+ decimals: 6
15
+ },
16
+ // Base Sepolia USDC
17
+ "eip155:4326": {
18
+ address: "0xFAfDdbb3FC7688494971a79cc65DCa3EF82079E7",
19
+ name: "MegaUSD",
20
+ version: "1",
21
+ decimals: 18,
22
+ assetTransferMethod: "permit2",
23
+ supportsEip2612: true
24
+ },
25
+ // MegaETH mainnet MegaUSD (no EIP-3009, supports EIP-2612)
26
+ "eip155:143": {
27
+ address: "0x754704Bc059F8C67012fEd69BC8A327a5aafb603",
28
+ name: "USD Coin",
29
+ version: "2",
30
+ decimals: 6
31
+ },
32
+ // Monad mainnet USDC
33
+ "eip155:988": {
34
+ address: "0x779Ded0c9e1022225f8E0630b35a9b54bE713736",
35
+ name: "USDT0",
36
+ version: "1",
37
+ decimals: 6
38
+ },
39
+ // Stable mainnet USDT0
40
+ "eip155:2201": {
41
+ address: "0x78Cf24370174180738C5B8E352B6D14c83a6c9A9",
42
+ name: "USDT0",
43
+ version: "1",
44
+ decimals: 6
45
+ },
46
+ // Stable testnet USDT0
47
+ "eip155:137": {
48
+ address: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
49
+ name: "USD Coin",
50
+ version: "2",
51
+ decimals: 6
52
+ },
53
+ // Polygon mainnet USDC
54
+ "eip155:42161": {
55
+ address: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
56
+ name: "USD Coin",
57
+ version: "2",
58
+ decimals: 6
59
+ },
60
+ // Arbitrum One USDC
61
+ "eip155:421614": {
62
+ address: "0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d",
63
+ name: "USD Coin",
64
+ version: "2",
65
+ decimals: 6
66
+ }
67
+ // Arbitrum Sepolia USDC
68
+ };
69
+ function getDefaultAsset(network) {
70
+ const info = DEFAULT_STABLECOINS[network];
71
+ if (!info) {
72
+ throw new Error(`No default asset configured for network ${network}`);
73
+ }
74
+ return info;
75
+ }
76
+
77
+ export {
78
+ getDefaultAsset
79
+ };
80
+ //# sourceMappingURL=chunk-NSFLAANF.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/shared/defaultAssets.ts"],"sourcesContent":["import type { Network } from \"@payai/x402/types\";\n\n/**\n * Base stablecoin asset configuration shared across all EVM payment schemes.\n * Contains the core fields needed to identify and convert tokens.\n */\nexport type DefaultAssetInfo = {\n /** Token contract address */\n address: string;\n /** EIP-712 domain name (must match the token's domain separator) */\n name: string;\n /** EIP-712 domain version (must match the token's domain separator) */\n version: string;\n /** Token decimal places (typically 6 for USDC) */\n decimals: number;\n};\n\n/**\n * Extended asset configuration for the exact scheme.\n * Includes transfer method hints that control client-side behaviour.\n */\nexport type ExactDefaultAssetInfo = DefaultAssetInfo & {\n /**\n * Transfer method override: `\"permit2\"` for tokens that don't support EIP-3009.\n * Omit for EIP-3009 tokens (default behaviour).\n */\n assetTransferMethod?: string;\n /**\n * Set to `true` for permit2 tokens that implement EIP-2612 `permit()`.\n * Controls whether name/version are included in `extra` so the client can\n * sign a gasless EIP-2612 permit for Permit2 approval.\n */\n supportsEip2612?: boolean;\n};\n\n/**\n * Default stablecoins indexed by CAIP-2 network identifier.\n *\n * Each network has the right to determine its own default stablecoin that can\n * be expressed as a USD string by calling servers. See DEFAULT_ASSET.md in\n * exact/server/ for how to add new chains.\n */\nexport const DEFAULT_STABLECOINS: Record<string, ExactDefaultAssetInfo> = {\n \"eip155:8453\": {\n address: \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\n name: \"USD Coin\",\n version: \"2\",\n decimals: 6,\n }, // Base mainnet USDC\n \"eip155:84532\": {\n address: \"0x036CbD53842c5426634e7929541eC2318f3dCF7e\",\n name: \"USDC\",\n version: \"2\",\n decimals: 6,\n }, // Base Sepolia USDC\n \"eip155:4326\": {\n address: \"0xFAfDdbb3FC7688494971a79cc65DCa3EF82079E7\",\n name: \"MegaUSD\",\n version: \"1\",\n decimals: 18,\n assetTransferMethod: \"permit2\",\n supportsEip2612: true,\n }, // MegaETH mainnet MegaUSD (no EIP-3009, supports EIP-2612)\n \"eip155:143\": {\n address: \"0x754704Bc059F8C67012fEd69BC8A327a5aafb603\",\n name: \"USD Coin\",\n version: \"2\",\n decimals: 6,\n }, // Monad mainnet USDC\n \"eip155:988\": {\n address: \"0x779Ded0c9e1022225f8E0630b35a9b54bE713736\",\n name: \"USDT0\",\n version: \"1\",\n decimals: 6,\n }, // Stable mainnet USDT0\n \"eip155:2201\": {\n address: \"0x78Cf24370174180738C5B8E352B6D14c83a6c9A9\",\n name: \"USDT0\",\n version: \"1\",\n decimals: 6,\n }, // Stable testnet USDT0\n \"eip155:137\": {\n address: \"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359\",\n name: \"USD Coin\",\n version: \"2\",\n decimals: 6,\n }, // Polygon mainnet USDC\n \"eip155:42161\": {\n address: \"0xaf88d065e77c8cC2239327C5EDb3A432268e5831\",\n name: \"USD Coin\",\n version: \"2\",\n decimals: 6,\n }, // Arbitrum One USDC\n \"eip155:421614\": {\n address: \"0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d\",\n name: \"USD Coin\",\n version: \"2\",\n decimals: 6,\n }, // Arbitrum Sepolia USDC\n};\n\n/**\n * Look up the default stablecoin for a network.\n *\n * @param network - CAIP-2 network identifier (e.g. \"eip155:8453\")\n * @returns The default asset info\n * @throws If no default asset is configured for the network\n */\nexport function getDefaultAsset(network: Network): ExactDefaultAssetInfo {\n const info = DEFAULT_STABLECOINS[network];\n if (!info) {\n throw new Error(`No default asset configured for network ${network}`);\n }\n return info;\n}\n"],"mappings":";AA0CO,IAAM,sBAA6D;AAAA,EACxE,eAAe;AAAA,IACb,SAAS;AAAA,IACT,MAAM;AAAA,IACN,SAAS;AAAA,IACT,UAAU;AAAA,EACZ;AAAA;AAAA,EACA,gBAAgB;AAAA,IACd,SAAS;AAAA,IACT,MAAM;AAAA,IACN,SAAS;AAAA,IACT,UAAU;AAAA,EACZ;AAAA;AAAA,EACA,eAAe;AAAA,IACb,SAAS;AAAA,IACT,MAAM;AAAA,IACN,SAAS;AAAA,IACT,UAAU;AAAA,IACV,qBAAqB;AAAA,IACrB,iBAAiB;AAAA,EACnB;AAAA;AAAA,EACA,cAAc;AAAA,IACZ,SAAS;AAAA,IACT,MAAM;AAAA,IACN,SAAS;AAAA,IACT,UAAU;AAAA,EACZ;AAAA;AAAA,EACA,cAAc;AAAA,IACZ,SAAS;AAAA,IACT,MAAM;AAAA,IACN,SAAS;AAAA,IACT,UAAU;AAAA,EACZ;AAAA;AAAA,EACA,eAAe;AAAA,IACb,SAAS;AAAA,IACT,MAAM;AAAA,IACN,SAAS;AAAA,IACT,UAAU;AAAA,EACZ;AAAA;AAAA,EACA,cAAc;AAAA,IACZ,SAAS;AAAA,IACT,MAAM;AAAA,IACN,SAAS;AAAA,IACT,UAAU;AAAA,EACZ;AAAA;AAAA,EACA,gBAAgB;AAAA,IACd,SAAS;AAAA,IACT,MAAM;AAAA,IACN,SAAS;AAAA,IACT,UAAU;AAAA,EACZ;AAAA;AAAA,EACA,iBAAiB;AAAA,IACf,SAAS;AAAA,IACT,MAAM;AAAA,IACN,SAAS;AAAA,IACT,UAAU;AAAA,EACZ;AAAA;AACF;AASO,SAAS,gBAAgB,SAAyC;AACvE,QAAM,OAAO,oBAAoB,OAAO;AACxC,MAAI,CAAC,MAAM;AACT,UAAM,IAAI,MAAM,2CAA2C,OAAO,EAAE;AAAA,EACtE;AACA,SAAO;AACT;","names":[]}