@payai/x402-evm 2.3.5 → 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.
- package/dist/cjs/exact/client/index.d.ts +3 -2
- package/dist/cjs/exact/client/index.js +175 -194
- package/dist/cjs/exact/client/index.js.map +1 -1
- package/dist/cjs/exact/facilitator/index.js +201 -185
- package/dist/cjs/exact/facilitator/index.js.map +1 -1
- package/dist/cjs/exact/server/index.d.ts +18 -17
- package/dist/cjs/exact/server/index.js +100 -55
- package/dist/cjs/exact/server/index.js.map +1 -1
- package/dist/cjs/exact/v1/client/index.js +5 -1
- package/dist/cjs/exact/v1/client/index.js.map +1 -1
- package/dist/cjs/exact/v1/facilitator/index.js +5 -1
- package/dist/cjs/exact/v1/facilitator/index.js.map +1 -1
- package/dist/cjs/index.d.ts +38 -2
- package/dist/cjs/index.js +443 -191
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/{permit2-U9Zolx3O.d.ts → permit2-CyZxwngN.d.ts} +278 -87
- package/dist/cjs/scheme-CXDF0D2A.d.ts +47 -0
- package/dist/cjs/upto/client/index.d.ts +32 -0
- package/dist/cjs/upto/client/index.js +507 -0
- package/dist/cjs/upto/client/index.js.map +1 -0
- package/dist/cjs/upto/facilitator/index.d.ts +52 -0
- package/dist/cjs/upto/facilitator/index.js +1233 -0
- package/dist/cjs/upto/facilitator/index.js.map +1 -0
- package/dist/cjs/upto/server/index.d.ts +77 -0
- package/dist/cjs/upto/server/index.js +246 -0
- package/dist/cjs/upto/server/index.js.map +1 -0
- package/dist/cjs/v1/index.d.ts +4 -0
- package/dist/cjs/v1/index.js +5 -1
- package/dist/cjs/v1/index.js.map +1 -1
- package/dist/esm/chunk-C4ZQMS77.mjs +629 -0
- package/dist/esm/chunk-C4ZQMS77.mjs.map +1 -0
- package/dist/esm/chunk-CRT6YNY5.mjs +529 -0
- package/dist/esm/chunk-CRT6YNY5.mjs.map +1 -0
- package/dist/esm/chunk-D6RXZXOS.mjs +158 -0
- package/dist/esm/chunk-D6RXZXOS.mjs.map +1 -0
- package/dist/esm/chunk-GJ57SZGI.mjs +121 -0
- package/dist/esm/chunk-GJ57SZGI.mjs.map +1 -0
- package/dist/esm/chunk-JII456TS.mjs +34 -0
- package/dist/esm/chunk-JII456TS.mjs.map +1 -0
- package/dist/esm/chunk-NSFLAANF.mjs +80 -0
- package/dist/esm/chunk-NSFLAANF.mjs.map +1 -0
- package/dist/esm/{chunk-IZEI7JTG.mjs → chunk-RYT6M3PA.mjs} +31 -501
- package/dist/esm/chunk-RYT6M3PA.mjs.map +1 -0
- package/dist/esm/chunk-WKBC5YMI.mjs +291 -0
- package/dist/esm/chunk-WKBC5YMI.mjs.map +1 -0
- package/dist/esm/exact/client/index.d.mts +3 -2
- package/dist/esm/exact/client/index.mjs +8 -5
- package/dist/esm/exact/facilitator/index.mjs +84 -430
- package/dist/esm/exact/facilitator/index.mjs.map +1 -1
- package/dist/esm/exact/server/index.d.mts +18 -17
- package/dist/esm/exact/server/index.mjs +28 -55
- package/dist/esm/exact/server/index.mjs.map +1 -1
- package/dist/esm/exact/v1/client/index.mjs +2 -1
- package/dist/esm/exact/v1/facilitator/index.mjs +2 -1
- package/dist/esm/index.d.mts +38 -2
- package/dist/esm/index.mjs +21 -8
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/{permit2-Bbh3a8_h.d.mts → permit2-CyZxwngN.d.mts} +278 -87
- package/dist/esm/scheme-DCR7hsa3.d.mts +47 -0
- package/dist/esm/upto/client/index.d.mts +32 -0
- package/dist/esm/upto/client/index.mjs +18 -0
- package/dist/esm/upto/client/index.mjs.map +1 -0
- package/dist/esm/upto/facilitator/index.d.mts +52 -0
- package/dist/esm/upto/facilitator/index.mjs +473 -0
- package/dist/esm/upto/facilitator/index.mjs.map +1 -0
- package/dist/esm/upto/server/index.d.mts +77 -0
- package/dist/esm/upto/server/index.mjs +145 -0
- package/dist/esm/upto/server/index.mjs.map +1 -0
- package/dist/esm/v1/index.d.mts +4 -0
- package/dist/esm/v1/index.mjs +2 -1
- package/package.json +31 -1
- package/dist/esm/chunk-GD4MKCN7.mjs +0 -57
- package/dist/esm/chunk-GD4MKCN7.mjs.map +0 -1
- package/dist/esm/chunk-IZEI7JTG.mjs.map +0 -1
- package/dist/esm/chunk-TKN5V2BV.mjs +0 -13
- package/dist/esm/chunk-TKN5V2BV.mjs.map +0 -1
- package/dist/esm/chunk-WJWNS4G4.mjs +0 -518
- package/dist/esm/chunk-WJWNS4G4.mjs.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/constants.ts","../../src/utils.ts","../../src/exact/facilitator/errors.ts","../../src/multicall.ts"],"sourcesContent":["// EIP-3009 TransferWithAuthorization types for EIP-712 signing\nexport const authorizationTypes = {\n TransferWithAuthorization: [\n { name: \"from\", type: \"address\" },\n { name: \"to\", type: \"address\" },\n { name: \"value\", type: \"uint256\" },\n { name: \"validAfter\", type: \"uint256\" },\n { name: \"validBefore\", type: \"uint256\" },\n { name: \"nonce\", type: \"bytes32\" },\n ],\n} as const;\n\n/**\n * Permit2 EIP-712 types for signing PermitWitnessTransferFrom (exact scheme).\n * Must match the exact format expected by the Permit2 contract.\n * Note: Types must be in ALPHABETICAL order after the primary type (TokenPermissions < Witness).\n */\nexport const permit2WitnessTypes = {\n PermitWitnessTransferFrom: [\n { name: \"permitted\", type: \"TokenPermissions\" },\n { name: \"spender\", type: \"address\" },\n { name: \"nonce\", type: \"uint256\" },\n { name: \"deadline\", type: \"uint256\" },\n { name: \"witness\", type: \"Witness\" },\n ],\n TokenPermissions: [\n { name: \"token\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n ],\n Witness: [\n { name: \"to\", type: \"address\" },\n { name: \"validAfter\", type: \"uint256\" },\n ],\n} as const;\n\n/**\n * Permit2 EIP-712 types for signing PermitWitnessTransferFrom (upto scheme).\n * The upto witness includes a `facilitator` field that the exact witness does not.\n * This ensures only the authorized facilitator can settle the payment.\n * Must match: Witness(address to,address facilitator,uint256 validAfter)\n */\nexport const uptoPermit2WitnessTypes = {\n PermitWitnessTransferFrom: [\n { name: \"permitted\", type: \"TokenPermissions\" },\n { name: \"spender\", type: \"address\" },\n { name: \"nonce\", type: \"uint256\" },\n { name: \"deadline\", type: \"uint256\" },\n { name: \"witness\", type: \"Witness\" },\n ],\n TokenPermissions: [\n { name: \"token\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n ],\n Witness: [\n { name: \"to\", type: \"address\" },\n { name: \"facilitator\", type: \"address\" },\n { name: \"validAfter\", type: \"uint256\" },\n ],\n} as const;\n\n// EIP3009 ABI for transferWithAuthorization function\nexport const eip3009ABI = [\n {\n inputs: [\n { name: \"from\", type: \"address\" },\n { name: \"to\", type: \"address\" },\n { name: \"value\", type: \"uint256\" },\n { name: \"validAfter\", type: \"uint256\" },\n { name: \"validBefore\", type: \"uint256\" },\n { name: \"nonce\", type: \"bytes32\" },\n { name: \"v\", type: \"uint8\" },\n { name: \"r\", type: \"bytes32\" },\n { name: \"s\", type: \"bytes32\" },\n ],\n name: \"transferWithAuthorization\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [\n { name: \"from\", type: \"address\" },\n { name: \"to\", type: \"address\" },\n { name: \"value\", type: \"uint256\" },\n { name: \"validAfter\", type: \"uint256\" },\n { name: \"validBefore\", type: \"uint256\" },\n { name: \"nonce\", type: \"bytes32\" },\n { name: \"signature\", type: \"bytes\" },\n ],\n name: \"transferWithAuthorization\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [{ name: \"account\", type: \"address\" }],\n name: \"balanceOf\",\n outputs: [{ name: \"\", type: \"uint256\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [],\n name: \"version\",\n outputs: [{ name: \"\", type: \"string\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [],\n name: \"name\",\n outputs: [{ name: \"\", type: \"string\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [\n { name: \"authorizer\", type: \"address\" },\n { name: \"nonce\", type: \"bytes32\" },\n ],\n name: \"authorizationState\",\n outputs: [{ name: \"\", type: \"bool\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n] as const;\n\n/**\n * EIP-2612 Permit EIP-712 types for signing token.permit().\n */\nexport const eip2612PermitTypes = {\n Permit: [\n { name: \"owner\", type: \"address\" },\n { name: \"spender\", type: \"address\" },\n { name: \"value\", type: \"uint256\" },\n { name: \"nonce\", type: \"uint256\" },\n { name: \"deadline\", type: \"uint256\" },\n ],\n} as const;\n\n/**\n * EIP-2612 nonces ABI for querying current nonce.\n */\nexport const eip2612NoncesAbi = [\n {\n type: \"function\",\n name: \"nonces\",\n inputs: [{ name: \"owner\", type: \"address\" }],\n outputs: [{ type: \"uint256\" }],\n stateMutability: \"view\",\n },\n] as const;\n\n/** ERC-20 approve(address,uint256) ABI for encoding/decoding approval calldata. */\nexport const erc20ApproveAbi = [\n {\n type: \"function\",\n name: \"approve\",\n inputs: [\n { name: \"spender\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n ],\n outputs: [{ type: \"bool\" }],\n stateMutability: \"nonpayable\",\n },\n] as const;\n\n/** ERC-20 allowance(address,address) ABI for checking spender approval. */\nexport const erc20AllowanceAbi = [\n {\n type: \"function\",\n name: \"allowance\",\n inputs: [\n { name: \"owner\", type: \"address\" },\n { name: \"spender\", type: \"address\" },\n ],\n outputs: [{ type: \"uint256\" }],\n stateMutability: \"view\",\n },\n] as const;\n\n/** Gas limit for a standard ERC-20 approve() transaction. */\nexport const ERC20_APPROVE_GAS_LIMIT = 70_000n;\n\n/** Fallback max fee per gas (1 gwei) when fee estimation fails. */\nexport const DEFAULT_MAX_FEE_PER_GAS = 1_000_000_000n;\n\n/** Fallback max priority fee per gas (0.1 gwei) when fee estimation fails. */\nexport const DEFAULT_MAX_PRIORITY_FEE_PER_GAS = 100_000_000n;\n\n/**\n * Canonical Permit2 contract address.\n * Same address on all EVM chains via CREATE2 deployment.\n *\n * @see https://github.com/Uniswap/permit2\n */\nexport const PERMIT2_ADDRESS = \"0x000000000022D473030F116dDEE9F6B43aC78BA3\" as const;\n\n/**\n * x402ExactPermit2Proxy contract address.\n * Vanity address: 0x4020...0001 for easy recognition.\n * This address is deterministic based on:\n * - Arachnid's deterministic deployer (0x4e59b44847b379578588920cA78FbF26c0B4956C)\n * - Vanity-mined salt for prefix 0x4020 and suffix 0001\n * - Contract bytecode + constructor args (PERMIT2_ADDRESS)\n */\nexport const x402ExactPermit2ProxyAddress = \"0x402085c248EeA27D92E8b30b2C58ed07f9E20001\" as const;\n\n/**\n * x402UptoPermit2Proxy contract address.\n * Vanity address: 0x4020...0002 for easy recognition.\n * This address is deterministic based on:\n * - Arachnid's deterministic deployer (0x4e59b44847b379578588920cA78FbF26c0B4956C)\n * - Vanity-mined salt for prefix 0x4020 and suffix 0002\n * - Contract bytecode + constructor args (PERMIT2_ADDRESS)\n */\nexport const x402UptoPermit2ProxyAddress = \"0x4020A4f3b7b90ccA423B9fabCc0CE57C6C240002\" as const;\n\n/**\n * ABI components for the exact Permit2 witness tuple: Witness(address to, uint256 validAfter).\n */\nconst permit2WitnessABIComponents = [\n { name: \"to\", type: \"address\", internalType: \"address\" },\n { name: \"validAfter\", type: \"uint256\", internalType: \"uint256\" },\n] as const;\n\n/**\n * ABI components for the upto Permit2 witness tuple:\n * Witness(address to, address facilitator, uint256 validAfter).\n */\nconst uptoPermit2WitnessABIComponents = [\n { name: \"to\", type: \"address\", internalType: \"address\" },\n { name: \"facilitator\", type: \"address\", internalType: \"address\" },\n { name: \"validAfter\", type: \"uint256\", internalType: \"uint256\" },\n] as const;\n\n/**\n * x402UptoPermit2Proxy ABI — settle/settleWithPermit for the upto payment scheme.\n * Key differences from exact: settle() takes a `uint256 amount` parameter, and the\n * Witness struct includes an `address facilitator` field.\n */\nexport const x402UptoPermit2ProxyABI = [\n {\n type: \"function\",\n name: \"PERMIT2\",\n inputs: [],\n outputs: [{ name: \"\", type: \"address\", internalType: \"contract ISignatureTransfer\" }],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"WITNESS_TYPEHASH\",\n inputs: [],\n outputs: [{ name: \"\", type: \"bytes32\", internalType: \"bytes32\" }],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"WITNESS_TYPE_STRING\",\n inputs: [],\n outputs: [{ name: \"\", type: \"string\", internalType: \"string\" }],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"settle\",\n inputs: [\n {\n name: \"permit\",\n type: \"tuple\",\n internalType: \"struct ISignatureTransfer.PermitTransferFrom\",\n components: [\n {\n name: \"permitted\",\n type: \"tuple\",\n internalType: \"struct ISignatureTransfer.TokenPermissions\",\n components: [\n { name: \"token\", type: \"address\", internalType: \"address\" },\n { name: \"amount\", type: \"uint256\", internalType: \"uint256\" },\n ],\n },\n { name: \"nonce\", type: \"uint256\", internalType: \"uint256\" },\n { name: \"deadline\", type: \"uint256\", internalType: \"uint256\" },\n ],\n },\n { name: \"amount\", type: \"uint256\", internalType: \"uint256\" },\n { name: \"owner\", type: \"address\", internalType: \"address\" },\n {\n name: \"witness\",\n type: \"tuple\",\n internalType: \"struct x402UptoPermit2Proxy.Witness\",\n components: uptoPermit2WitnessABIComponents,\n },\n { name: \"signature\", type: \"bytes\", internalType: \"bytes\" },\n ],\n outputs: [],\n stateMutability: \"nonpayable\",\n },\n {\n type: \"function\",\n name: \"settleWithPermit\",\n inputs: [\n {\n name: \"permit2612\",\n type: \"tuple\",\n internalType: \"struct x402UptoPermit2Proxy.EIP2612Permit\",\n components: [\n { name: \"value\", type: \"uint256\", internalType: \"uint256\" },\n { name: \"deadline\", type: \"uint256\", internalType: \"uint256\" },\n { name: \"r\", type: \"bytes32\", internalType: \"bytes32\" },\n { name: \"s\", type: \"bytes32\", internalType: \"bytes32\" },\n { name: \"v\", type: \"uint8\", internalType: \"uint8\" },\n ],\n },\n {\n name: \"permit\",\n type: \"tuple\",\n internalType: \"struct ISignatureTransfer.PermitTransferFrom\",\n components: [\n {\n name: \"permitted\",\n type: \"tuple\",\n internalType: \"struct ISignatureTransfer.TokenPermissions\",\n components: [\n { name: \"token\", type: \"address\", internalType: \"address\" },\n { name: \"amount\", type: \"uint256\", internalType: \"uint256\" },\n ],\n },\n { name: \"nonce\", type: \"uint256\", internalType: \"uint256\" },\n { name: \"deadline\", type: \"uint256\", internalType: \"uint256\" },\n ],\n },\n { name: \"amount\", type: \"uint256\", internalType: \"uint256\" },\n { name: \"owner\", type: \"address\", internalType: \"address\" },\n {\n name: \"witness\",\n type: \"tuple\",\n internalType: \"struct x402UptoPermit2Proxy.Witness\",\n components: uptoPermit2WitnessABIComponents,\n },\n { name: \"signature\", type: \"bytes\", internalType: \"bytes\" },\n ],\n outputs: [],\n stateMutability: \"nonpayable\",\n },\n { type: \"event\", name: \"Settled\", inputs: [], anonymous: false },\n { type: \"event\", name: \"SettledWithPermit\", inputs: [], anonymous: false },\n { type: \"error\", name: \"AmountExceedsPermitted\", inputs: [] },\n { type: \"error\", name: \"InvalidDestination\", inputs: [] },\n { type: \"error\", name: \"InvalidOwner\", inputs: [] },\n { type: \"error\", name: \"InvalidPermit2Address\", inputs: [] },\n { type: \"error\", name: \"PaymentTooEarly\", inputs: [] },\n { type: \"error\", name: \"Permit2612AmountMismatch\", inputs: [] },\n { type: \"error\", name: \"ReentrancyGuardReentrantCall\", inputs: [] },\n { type: \"error\", name: \"UnauthorizedFacilitator\", inputs: [] },\n] as const;\n\n/**\n * x402ExactPermit2Proxy ABI - settle function for exact payment scheme.\n */\nexport const x402ExactPermit2ProxyABI = [\n {\n type: \"function\",\n name: \"PERMIT2\",\n inputs: [],\n outputs: [{ name: \"\", type: \"address\", internalType: \"contract ISignatureTransfer\" }],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"WITNESS_TYPEHASH\",\n inputs: [],\n outputs: [{ name: \"\", type: \"bytes32\", internalType: \"bytes32\" }],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"WITNESS_TYPE_STRING\",\n inputs: [],\n outputs: [{ name: \"\", type: \"string\", internalType: \"string\" }],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"settle\",\n inputs: [\n {\n name: \"permit\",\n type: \"tuple\",\n internalType: \"struct ISignatureTransfer.PermitTransferFrom\",\n components: [\n {\n name: \"permitted\",\n type: \"tuple\",\n internalType: \"struct ISignatureTransfer.TokenPermissions\",\n components: [\n { name: \"token\", type: \"address\", internalType: \"address\" },\n { name: \"amount\", type: \"uint256\", internalType: \"uint256\" },\n ],\n },\n { name: \"nonce\", type: \"uint256\", internalType: \"uint256\" },\n { name: \"deadline\", type: \"uint256\", internalType: \"uint256\" },\n ],\n },\n { name: \"owner\", type: \"address\", internalType: \"address\" },\n {\n name: \"witness\",\n type: \"tuple\",\n internalType: \"struct x402ExactPermit2Proxy.Witness\",\n components: permit2WitnessABIComponents,\n },\n { name: \"signature\", type: \"bytes\", internalType: \"bytes\" },\n ],\n outputs: [],\n stateMutability: \"nonpayable\",\n },\n {\n type: \"function\",\n name: \"settleWithPermit\",\n inputs: [\n {\n name: \"permit2612\",\n type: \"tuple\",\n internalType: \"struct x402ExactPermit2Proxy.EIP2612Permit\",\n components: [\n { name: \"value\", type: \"uint256\", internalType: \"uint256\" },\n { name: \"deadline\", type: \"uint256\", internalType: \"uint256\" },\n { name: \"r\", type: \"bytes32\", internalType: \"bytes32\" },\n { name: \"s\", type: \"bytes32\", internalType: \"bytes32\" },\n { name: \"v\", type: \"uint8\", internalType: \"uint8\" },\n ],\n },\n {\n name: \"permit\",\n type: \"tuple\",\n internalType: \"struct ISignatureTransfer.PermitTransferFrom\",\n components: [\n {\n name: \"permitted\",\n type: \"tuple\",\n internalType: \"struct ISignatureTransfer.TokenPermissions\",\n components: [\n { name: \"token\", type: \"address\", internalType: \"address\" },\n { name: \"amount\", type: \"uint256\", internalType: \"uint256\" },\n ],\n },\n { name: \"nonce\", type: \"uint256\", internalType: \"uint256\" },\n { name: \"deadline\", type: \"uint256\", internalType: \"uint256\" },\n ],\n },\n { name: \"owner\", type: \"address\", internalType: \"address\" },\n {\n name: \"witness\",\n type: \"tuple\",\n internalType: \"struct x402ExactPermit2Proxy.Witness\",\n components: permit2WitnessABIComponents,\n },\n { name: \"signature\", type: \"bytes\", internalType: \"bytes\" },\n ],\n outputs: [],\n stateMutability: \"nonpayable\",\n },\n { type: \"event\", name: \"Settled\", inputs: [], anonymous: false },\n { type: \"event\", name: \"SettledWithPermit\", inputs: [], anonymous: false },\n { type: \"error\", name: \"InvalidAmount\", inputs: [] },\n { type: \"error\", name: \"InvalidDestination\", inputs: [] },\n { type: \"error\", name: \"InvalidOwner\", inputs: [] },\n { type: \"error\", name: \"InvalidPermit2Address\", inputs: [] },\n { type: \"error\", name: \"PaymentTooEarly\", inputs: [] },\n { type: \"error\", name: \"Permit2612AmountMismatch\", inputs: [] },\n { type: \"error\", name: \"ReentrancyGuardReentrantCall\", inputs: [] },\n] as const;\n","import { toHex } from \"viem\";\n\n/**\n * Extract chain ID from a CAIP-2 network identifier (eip155:CHAIN_ID).\n *\n * @param network - The network identifier in CAIP-2 format (e.g., \"eip155:8453\")\n * @returns The numeric chain ID\n * @throws Error if the network format is invalid\n */\nexport function getEvmChainId(network: string): number {\n if (network.startsWith(\"eip155:\")) {\n const idStr = network.split(\":\")[1];\n const chainId = parseInt(idStr, 10);\n if (isNaN(chainId)) {\n throw new Error(`Invalid CAIP-2 chain ID: ${network}`);\n }\n return chainId;\n }\n\n throw new Error(`Unsupported network format: ${network} (expected eip155:CHAIN_ID)`);\n}\n\n/**\n * Get the crypto object from the global scope.\n *\n * @returns The crypto object\n * @throws Error if crypto API is not available\n */\nfunction getCrypto(): Crypto {\n const cryptoObj = globalThis.crypto as Crypto | undefined;\n if (!cryptoObj) {\n throw new Error(\"Crypto API not available\");\n }\n return cryptoObj;\n}\n\n/**\n * Create a random 32-byte nonce for EIP-3009 authorization.\n *\n * @returns A hex-encoded 32-byte nonce\n */\nexport function createNonce(): `0x${string}` {\n return toHex(getCrypto().getRandomValues(new Uint8Array(32)));\n}\n\n/**\n * Creates a random 256-bit nonce for Permit2.\n * Permit2 uses uint256 nonces (not bytes32 like EIP-3009).\n *\n * @returns A string representation of the random nonce\n */\nexport function createPermit2Nonce(): string {\n const randomBytes = getCrypto().getRandomValues(new Uint8Array(32));\n return BigInt(toHex(randomBytes)).toString();\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\nexport const ErrInvalidScheme = \"invalid_exact_evm_scheme\";\nexport const ErrNetworkMismatch = \"invalid_exact_evm_network_mismatch\";\nexport const ErrMissingEip712Domain = \"invalid_exact_evm_missing_eip712_domain\";\nexport const ErrRecipientMismatch = \"invalid_exact_evm_recipient_mismatch\";\nexport const ErrInvalidSignature = \"invalid_exact_evm_signature\";\nexport const ErrValidBeforeExpired = \"invalid_exact_evm_payload_authorization_valid_before\";\nexport const ErrValidAfterInFuture = \"invalid_exact_evm_payload_authorization_valid_after\";\nexport const ErrInvalidAuthorizationValue = \"invalid_exact_evm_authorization_value\";\nexport const ErrUndeployedSmartWallet = \"invalid_exact_evm_payload_undeployed_smart_wallet\";\nexport const ErrTransactionFailed = \"invalid_exact_evm_transaction_failed\";\n\n// EIP-3009 verify errors\nexport const ErrEip3009TokenNameMismatch = \"invalid_exact_evm_token_name_mismatch\";\nexport const ErrEip3009TokenVersionMismatch = \"invalid_exact_evm_token_version_mismatch\";\nexport const ErrEip3009NotSupported = \"invalid_exact_evm_eip3009_not_supported\";\nexport const ErrEip3009NonceAlreadyUsed = \"invalid_exact_evm_nonce_already_used\";\nexport const ErrEip3009InsufficientBalance = \"invalid_exact_evm_insufficient_balance\";\nexport const ErrEip3009SimulationFailed = \"invalid_exact_evm_transaction_simulation_failed\";\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 ErrPermit2AmountMismatch = \"permit2_amount_mismatch\";\nexport const ErrPermit2TokenMismatch = \"permit2_token_mismatch\";\nexport const ErrPermit2InvalidSignature = \"invalid_permit2_signature\";\nexport const ErrPermit2AllowanceRequired = \"permit2_allowance_required\";\nexport const ErrPermit2SimulationFailed = \"permit2_simulation_failed\";\nexport const ErrPermit2InsufficientBalance = \"permit2_insufficient_balance\";\nexport const ErrPermit2ProxyNotDeployed = \"permit2_proxy_not_deployed\";\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\";\nexport const ErrErc20ApprovalTxFailed = \"erc20_approval_tx_failed\";\n\n// EIP-2612 gas sponsoring verify errors\nexport const ErrInvalidEip2612ExtensionFormat = \"invalid_eip2612_extension_format\";\nexport const ErrEip2612FromMismatch = \"eip2612_from_mismatch\";\nexport const ErrEip2612AssetMismatch = \"eip2612_asset_mismatch\";\nexport const ErrEip2612SpenderNotPermit2 = \"eip2612_spender_not_permit2\";\nexport const ErrEip2612DeadlineExpired = \"eip2612_deadline_expired\";\n\n// Shared settle errors\nexport const ErrUnsupportedPayloadType = \"unsupported_payload_type\";\nexport const ErrInvalidTransactionState = \"invalid_transaction_state\";\n","import { encodeFunctionData, decodeFunctionResult } from \"viem\";\n\n/**\n * Multicall3 contract address.\n * Same address on all EVM chains via CREATE2 deployment.\n *\n * @see https://github.com/mds1/multicall\n */\nexport const MULTICALL3_ADDRESS = \"0xcA11bde05977b3631167028862bE2a173976CA11\" as const;\n\n/** Multicall3 getEthBalance ABI for querying native token balance. */\nexport const multicall3GetEthBalanceAbi = [\n {\n name: \"getEthBalance\",\n inputs: [{ name: \"addr\", type: \"address\" }],\n outputs: [{ name: \"balance\", type: \"uint256\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n] as const;\n\n/** Multicall3 tryAggregate ABI for batching calls. */\nconst multicall3ABI = [\n {\n inputs: [\n { name: \"requireSuccess\", type: \"bool\" },\n {\n name: \"calls\",\n type: \"tuple[]\",\n components: [\n { name: \"target\", type: \"address\" },\n { name: \"callData\", type: \"bytes\" },\n ],\n },\n ],\n name: \"tryAggregate\",\n outputs: [\n {\n name: \"returnData\",\n type: \"tuple[]\",\n components: [\n { name: \"success\", type: \"bool\" },\n { name: \"returnData\", type: \"bytes\" },\n ],\n },\n ],\n stateMutability: \"payable\",\n type: \"function\",\n },\n] as const;\n\nexport type ContractCall = {\n address: `0x${string}`;\n abi: readonly unknown[];\n functionName: string;\n args?: readonly unknown[];\n};\n\nexport type RawContractCall = {\n address: `0x${string}`;\n callData: `0x${string}`;\n};\n\nexport type MulticallSuccess = { status: \"success\"; result: unknown };\nexport type MulticallFailure = { status: \"failure\"; error: Error };\nexport type MulticallResult = MulticallSuccess | MulticallFailure;\n\n/**\n * Batches contract calls via Multicall3 `tryAggregate(false, ...)`.\n *\n * Accepts a mix of typed ContractCall (ABI-encoded + decoded) and\n * RawContractCall (pre-encoded calldata, no decoding) entries.\n * Raw calls are useful for the EIP-6492 factory deployment case\n * where calldata is pre-encoded with no ABI available.\n */\ntype ReadContractFn = (args: {\n address: `0x${string}`;\n abi: readonly unknown[];\n functionName: string;\n args?: readonly unknown[];\n}) => Promise<unknown>;\n\n/**\n * Executes multiple contract read calls in a single RPC round-trip using Multicall3.\n *\n * @param readContract - Function that performs a single contract read (e.g. viem readContract)\n * @param calls - Array of contract calls to batch (ContractCall or RawContractCall)\n * @returns A promise that resolves to an array of decoded results, one per call\n */\nexport async function multicall(\n readContract: ReadContractFn,\n calls: ReadonlyArray<ContractCall | RawContractCall>,\n): Promise<MulticallResult[]> {\n const aggregateCalls = calls.map(call => {\n if (\"callData\" in call) {\n return { target: call.address, callData: call.callData };\n }\n const callData = encodeFunctionData({\n abi: call.abi,\n functionName: call.functionName,\n args: call.args as unknown[],\n });\n return { target: call.address, callData };\n });\n\n const rawResults = (await readContract({\n address: MULTICALL3_ADDRESS,\n abi: multicall3ABI,\n functionName: \"tryAggregate\",\n args: [false, aggregateCalls],\n })) as { success: boolean; returnData: `0x${string}` }[];\n\n return rawResults.map((raw, i) => {\n if (!raw.success) {\n return {\n status: \"failure\" as const,\n error: new Error(`multicall: call reverted (returnData: ${raw.returnData})`),\n };\n }\n\n const call = calls[i];\n if (\"callData\" in call) {\n return { status: \"success\" as const, result: undefined };\n }\n\n try {\n const decoded = decodeFunctionResult({\n abi: call.abi,\n functionName: call.functionName,\n data: raw.returnData,\n });\n return { status: \"success\" as const, result: decoded };\n } catch (err) {\n return {\n status: \"failure\" as const,\n error: err instanceof Error ? err : new Error(String(err)),\n };\n }\n });\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,529 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ErrEip2612AssetMismatch,
|
|
3
|
+
ErrEip2612DeadlineExpired,
|
|
4
|
+
ErrEip2612FromMismatch,
|
|
5
|
+
ErrEip2612SpenderNotPermit2,
|
|
6
|
+
ErrErc20ApprovalAssetMismatch,
|
|
7
|
+
ErrErc20ApprovalFromMismatch,
|
|
8
|
+
ErrErc20ApprovalInvalidFormat,
|
|
9
|
+
ErrErc20ApprovalSpenderNotPermit2,
|
|
10
|
+
ErrErc20ApprovalTxFailed,
|
|
11
|
+
ErrErc20ApprovalTxInvalidCalldata,
|
|
12
|
+
ErrErc20ApprovalTxInvalidSignature,
|
|
13
|
+
ErrErc20ApprovalTxParseFailed,
|
|
14
|
+
ErrErc20ApprovalTxSignerMismatch,
|
|
15
|
+
ErrErc20ApprovalTxWrongSelector,
|
|
16
|
+
ErrErc20ApprovalTxWrongSpender,
|
|
17
|
+
ErrErc20ApprovalTxWrongTarget,
|
|
18
|
+
ErrInvalidEip2612ExtensionFormat,
|
|
19
|
+
ErrInvalidTransactionState,
|
|
20
|
+
ErrPermit2612AmountMismatch,
|
|
21
|
+
ErrPermit2AllowanceRequired,
|
|
22
|
+
ErrPermit2InsufficientBalance,
|
|
23
|
+
ErrPermit2InvalidAmount,
|
|
24
|
+
ErrPermit2InvalidDestination,
|
|
25
|
+
ErrPermit2InvalidNonce,
|
|
26
|
+
ErrPermit2InvalidOwner,
|
|
27
|
+
ErrPermit2InvalidSignature,
|
|
28
|
+
ErrPermit2PaymentTooEarly,
|
|
29
|
+
ErrPermit2ProxyNotDeployed,
|
|
30
|
+
ErrPermit2SimulationFailed,
|
|
31
|
+
ErrTransactionFailed,
|
|
32
|
+
PERMIT2_ADDRESS,
|
|
33
|
+
createPermit2Nonce,
|
|
34
|
+
eip3009ABI,
|
|
35
|
+
erc20AllowanceAbi,
|
|
36
|
+
erc20ApproveAbi,
|
|
37
|
+
getEvmChainId,
|
|
38
|
+
multicall,
|
|
39
|
+
permit2WitnessTypes
|
|
40
|
+
} from "./chunk-C4ZQMS77.mjs";
|
|
41
|
+
|
|
42
|
+
// src/exact/extensions.ts
|
|
43
|
+
var EIP2612_GAS_SPONSORING_KEY = "eip2612GasSponsoring";
|
|
44
|
+
var ERC20_APPROVAL_GAS_SPONSORING_KEY = "erc20ApprovalGasSponsoring";
|
|
45
|
+
var ERC20_APPROVAL_GAS_SPONSORING_VERSION = "1";
|
|
46
|
+
function _extractInfo(payload, extensionKey) {
|
|
47
|
+
const extensions = payload.extensions;
|
|
48
|
+
if (!extensions) return null;
|
|
49
|
+
const extension = extensions[extensionKey];
|
|
50
|
+
if (!extension?.info) return null;
|
|
51
|
+
return extension.info;
|
|
52
|
+
}
|
|
53
|
+
function extractEip2612GasSponsoringInfo(payload) {
|
|
54
|
+
const info = _extractInfo(payload, EIP2612_GAS_SPONSORING_KEY);
|
|
55
|
+
if (!info) return null;
|
|
56
|
+
if (!info.from || !info.asset || !info.spender || !info.amount || !info.nonce || !info.deadline || !info.signature || !info.version) {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
return info;
|
|
60
|
+
}
|
|
61
|
+
function validateEip2612GasSponsoringInfo(info) {
|
|
62
|
+
const addressPattern = /^0x[a-fA-F0-9]{40}$/;
|
|
63
|
+
const numericPattern = /^[0-9]+$/;
|
|
64
|
+
const hexPattern = /^0x[a-fA-F0-9]+$/;
|
|
65
|
+
const versionPattern = /^[0-9]+(\.[0-9]+)*$/;
|
|
66
|
+
return addressPattern.test(info.from) && addressPattern.test(info.asset) && addressPattern.test(info.spender) && numericPattern.test(info.amount) && numericPattern.test(info.nonce) && numericPattern.test(info.deadline) && hexPattern.test(info.signature) && versionPattern.test(info.version);
|
|
67
|
+
}
|
|
68
|
+
function extractErc20ApprovalGasSponsoringInfo(payload) {
|
|
69
|
+
const info = _extractInfo(payload, ERC20_APPROVAL_GAS_SPONSORING_KEY);
|
|
70
|
+
if (!info) return null;
|
|
71
|
+
if (!info.from || !info.asset || !info.spender || !info.amount || !info.signedTransaction || !info.version) {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
return info;
|
|
75
|
+
}
|
|
76
|
+
function validateErc20ApprovalGasSponsoringInfo(info) {
|
|
77
|
+
const addressPattern = /^0x[a-fA-F0-9]{40}$/;
|
|
78
|
+
const numericPattern = /^[0-9]+$/;
|
|
79
|
+
const hexPattern = /^0x[a-fA-F0-9]+$/;
|
|
80
|
+
const versionPattern = /^[0-9]+(\.[0-9]+)*$/;
|
|
81
|
+
return addressPattern.test(info.from) && addressPattern.test(info.asset) && addressPattern.test(info.spender) && numericPattern.test(info.amount) && hexPattern.test(info.signedTransaction) && versionPattern.test(info.version);
|
|
82
|
+
}
|
|
83
|
+
function resolveErc20ApprovalExtensionSigner(extension, network) {
|
|
84
|
+
if (!extension) return void 0;
|
|
85
|
+
return extension.signerForNetwork?.(network) ?? extension.signer;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// src/shared/permit2.ts
|
|
89
|
+
import { getAddress as getAddress2, encodeFunctionData } from "viem";
|
|
90
|
+
|
|
91
|
+
// src/shared/erc20approval.ts
|
|
92
|
+
import {
|
|
93
|
+
getAddress,
|
|
94
|
+
parseTransaction,
|
|
95
|
+
decodeFunctionData,
|
|
96
|
+
recoverTransactionAddress
|
|
97
|
+
} from "viem";
|
|
98
|
+
var APPROVE_SELECTOR = "0x095ea7b3";
|
|
99
|
+
async function validateErc20ApprovalForPayment(info, payer, tokenAddress) {
|
|
100
|
+
if (!validateErc20ApprovalGasSponsoringInfo(info)) {
|
|
101
|
+
return {
|
|
102
|
+
isValid: false,
|
|
103
|
+
invalidReason: ErrErc20ApprovalInvalidFormat,
|
|
104
|
+
invalidMessage: "ERC-20 approval extension info failed schema validation"
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
if (getAddress(info.from) !== getAddress(payer)) {
|
|
108
|
+
return {
|
|
109
|
+
isValid: false,
|
|
110
|
+
invalidReason: ErrErc20ApprovalFromMismatch,
|
|
111
|
+
invalidMessage: `Expected from=${payer}, got ${info.from}`
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
if (getAddress(info.asset) !== tokenAddress) {
|
|
115
|
+
return {
|
|
116
|
+
isValid: false,
|
|
117
|
+
invalidReason: ErrErc20ApprovalAssetMismatch,
|
|
118
|
+
invalidMessage: `Expected asset=${tokenAddress}, got ${info.asset}`
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
if (getAddress(info.spender) !== getAddress(PERMIT2_ADDRESS)) {
|
|
122
|
+
return {
|
|
123
|
+
isValid: false,
|
|
124
|
+
invalidReason: ErrErc20ApprovalSpenderNotPermit2,
|
|
125
|
+
invalidMessage: `Expected spender=${PERMIT2_ADDRESS}, got ${info.spender}`
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
try {
|
|
129
|
+
const serializedTx = info.signedTransaction;
|
|
130
|
+
const tx = parseTransaction(serializedTx);
|
|
131
|
+
if (!tx.to || getAddress(tx.to) !== tokenAddress) {
|
|
132
|
+
return {
|
|
133
|
+
isValid: false,
|
|
134
|
+
invalidReason: ErrErc20ApprovalTxWrongTarget,
|
|
135
|
+
invalidMessage: `Transaction targets ${tx.to ?? "null"}, expected ${tokenAddress}`
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
const data = tx.data ?? "0x";
|
|
139
|
+
if (!data.startsWith(APPROVE_SELECTOR)) {
|
|
140
|
+
return {
|
|
141
|
+
isValid: false,
|
|
142
|
+
invalidReason: ErrErc20ApprovalTxWrongSelector,
|
|
143
|
+
invalidMessage: `Transaction calldata does not start with approve() selector ${APPROVE_SELECTOR}`
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
try {
|
|
147
|
+
const decoded = decodeFunctionData({
|
|
148
|
+
abi: erc20ApproveAbi,
|
|
149
|
+
data
|
|
150
|
+
});
|
|
151
|
+
const calldataSpender = getAddress(decoded.args[0]);
|
|
152
|
+
if (calldataSpender !== getAddress(PERMIT2_ADDRESS)) {
|
|
153
|
+
return {
|
|
154
|
+
isValid: false,
|
|
155
|
+
invalidReason: ErrErc20ApprovalTxWrongSpender,
|
|
156
|
+
invalidMessage: `approve() spender is ${calldataSpender}, expected Permit2 ${PERMIT2_ADDRESS}`
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
} catch {
|
|
160
|
+
return {
|
|
161
|
+
isValid: false,
|
|
162
|
+
invalidReason: ErrErc20ApprovalTxInvalidCalldata,
|
|
163
|
+
invalidMessage: "Failed to decode approve() calldata from the signed transaction"
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
try {
|
|
167
|
+
const recoveredAddress = await recoverTransactionAddress({
|
|
168
|
+
serializedTransaction: serializedTx
|
|
169
|
+
});
|
|
170
|
+
if (getAddress(recoveredAddress) !== getAddress(payer)) {
|
|
171
|
+
return {
|
|
172
|
+
isValid: false,
|
|
173
|
+
invalidReason: ErrErc20ApprovalTxSignerMismatch,
|
|
174
|
+
invalidMessage: `Transaction signed by ${recoveredAddress}, expected payer ${payer}`
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
} catch {
|
|
178
|
+
return {
|
|
179
|
+
isValid: false,
|
|
180
|
+
invalidReason: ErrErc20ApprovalTxInvalidSignature,
|
|
181
|
+
invalidMessage: "Failed to recover signer from the signed transaction"
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
} catch {
|
|
185
|
+
return {
|
|
186
|
+
isValid: false,
|
|
187
|
+
invalidReason: ErrErc20ApprovalTxParseFailed,
|
|
188
|
+
invalidMessage: "Failed to parse the signed transaction"
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
return { isValid: true };
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// src/upto/facilitator/errors.ts
|
|
195
|
+
var ErrUptoInvalidScheme = "invalid_upto_evm_scheme";
|
|
196
|
+
var ErrUptoNetworkMismatch = "invalid_upto_evm_network_mismatch";
|
|
197
|
+
var ErrUptoSettlementExceedsAmount = "invalid_upto_evm_payload_settlement_exceeds_amount";
|
|
198
|
+
var ErrUptoAmountExceedsPermitted = "upto_amount_exceeds_permitted";
|
|
199
|
+
var ErrUptoUnauthorizedFacilitator = "upto_unauthorized_facilitator";
|
|
200
|
+
var ErrUptoFacilitatorMismatch = "upto_facilitator_mismatch";
|
|
201
|
+
|
|
202
|
+
// src/shared/permit2.ts
|
|
203
|
+
async function waitAndReturnSettleResponse(signer, tx, payload, payer) {
|
|
204
|
+
const receipt = await signer.waitForTransactionReceipt({ hash: tx });
|
|
205
|
+
if (receipt.status !== "success") {
|
|
206
|
+
return {
|
|
207
|
+
success: false,
|
|
208
|
+
errorReason: ErrInvalidTransactionState,
|
|
209
|
+
transaction: tx,
|
|
210
|
+
network: payload.accepted.network,
|
|
211
|
+
payer
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
return {
|
|
215
|
+
success: true,
|
|
216
|
+
transaction: tx,
|
|
217
|
+
network: payload.accepted.network,
|
|
218
|
+
payer
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
function mapSettleError(error, payload, payer) {
|
|
222
|
+
let errorReason = ErrTransactionFailed;
|
|
223
|
+
if (error instanceof Error) {
|
|
224
|
+
const message = error.message;
|
|
225
|
+
if (message.includes("Permit2612AmountMismatch")) {
|
|
226
|
+
errorReason = ErrPermit2612AmountMismatch;
|
|
227
|
+
} else if (message.includes("InvalidAmount")) {
|
|
228
|
+
errorReason = ErrPermit2InvalidAmount;
|
|
229
|
+
} else if (message.includes("InvalidDestination")) {
|
|
230
|
+
errorReason = ErrPermit2InvalidDestination;
|
|
231
|
+
} else if (message.includes("InvalidOwner")) {
|
|
232
|
+
errorReason = ErrPermit2InvalidOwner;
|
|
233
|
+
} else if (message.includes("PaymentTooEarly")) {
|
|
234
|
+
errorReason = ErrPermit2PaymentTooEarly;
|
|
235
|
+
} else if (message.includes("InvalidSignature") || message.includes("SignatureExpired")) {
|
|
236
|
+
errorReason = ErrPermit2InvalidSignature;
|
|
237
|
+
} else if (message.includes("InvalidNonce")) {
|
|
238
|
+
errorReason = ErrPermit2InvalidNonce;
|
|
239
|
+
} else if (message.includes("erc20_approval_tx_failed")) {
|
|
240
|
+
errorReason = ErrErc20ApprovalTxFailed;
|
|
241
|
+
} else if (message.includes("AmountExceedsPermitted")) {
|
|
242
|
+
errorReason = ErrUptoAmountExceedsPermitted;
|
|
243
|
+
} else if (message.includes("UnauthorizedFacilitator")) {
|
|
244
|
+
errorReason = ErrUptoUnauthorizedFacilitator;
|
|
245
|
+
} else {
|
|
246
|
+
errorReason = `${ErrTransactionFailed}: ${message.slice(0, 500)}`;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
return {
|
|
250
|
+
success: false,
|
|
251
|
+
errorReason,
|
|
252
|
+
transaction: "",
|
|
253
|
+
network: payload.accepted.network,
|
|
254
|
+
payer
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
function validateEip2612PermitForPayment(info, payer, tokenAddress) {
|
|
258
|
+
if (!validateEip2612GasSponsoringInfo(info)) {
|
|
259
|
+
return { isValid: false, invalidReason: ErrInvalidEip2612ExtensionFormat };
|
|
260
|
+
}
|
|
261
|
+
if (getAddress2(info.from) !== getAddress2(payer)) {
|
|
262
|
+
return { isValid: false, invalidReason: ErrEip2612FromMismatch };
|
|
263
|
+
}
|
|
264
|
+
if (getAddress2(info.asset) !== tokenAddress) {
|
|
265
|
+
return { isValid: false, invalidReason: ErrEip2612AssetMismatch };
|
|
266
|
+
}
|
|
267
|
+
if (getAddress2(info.spender) !== getAddress2(PERMIT2_ADDRESS)) {
|
|
268
|
+
return { isValid: false, invalidReason: ErrEip2612SpenderNotPermit2 };
|
|
269
|
+
}
|
|
270
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
271
|
+
if (BigInt(info.deadline) < BigInt(now + 6)) {
|
|
272
|
+
return { isValid: false, invalidReason: ErrEip2612DeadlineExpired };
|
|
273
|
+
}
|
|
274
|
+
return { isValid: true };
|
|
275
|
+
}
|
|
276
|
+
async function simulatePermit2Settle(config, signer, settleArgs) {
|
|
277
|
+
try {
|
|
278
|
+
await signer.readContract({
|
|
279
|
+
address: config.proxyAddress,
|
|
280
|
+
abi: config.proxyABI,
|
|
281
|
+
functionName: "settle",
|
|
282
|
+
args: settleArgs
|
|
283
|
+
});
|
|
284
|
+
return true;
|
|
285
|
+
} catch {
|
|
286
|
+
return false;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
async function simulatePermit2SettleWithPermit(config, signer, settleArgs, eip2612Info) {
|
|
290
|
+
try {
|
|
291
|
+
const { v, r, s } = splitEip2612Signature(eip2612Info.signature);
|
|
292
|
+
await signer.readContract({
|
|
293
|
+
address: config.proxyAddress,
|
|
294
|
+
abi: config.proxyABI,
|
|
295
|
+
functionName: "settleWithPermit",
|
|
296
|
+
args: [
|
|
297
|
+
{
|
|
298
|
+
value: BigInt(eip2612Info.amount),
|
|
299
|
+
deadline: BigInt(eip2612Info.deadline),
|
|
300
|
+
r,
|
|
301
|
+
s,
|
|
302
|
+
v
|
|
303
|
+
},
|
|
304
|
+
...settleArgs
|
|
305
|
+
]
|
|
306
|
+
});
|
|
307
|
+
return true;
|
|
308
|
+
} catch {
|
|
309
|
+
return false;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
async function simulatePermit2SettleWithErc20Approval(config, extensionSigner, settleArgs, erc20Info) {
|
|
313
|
+
if (!extensionSigner.simulateTransactions) {
|
|
314
|
+
return false;
|
|
315
|
+
}
|
|
316
|
+
try {
|
|
317
|
+
const settleData = encodeFunctionData({
|
|
318
|
+
abi: config.proxyABI,
|
|
319
|
+
functionName: "settle",
|
|
320
|
+
args: settleArgs
|
|
321
|
+
});
|
|
322
|
+
return await extensionSigner.simulateTransactions([
|
|
323
|
+
erc20Info.signedTransaction,
|
|
324
|
+
{ to: config.proxyAddress, data: settleData, gas: BigInt(3e5) }
|
|
325
|
+
]);
|
|
326
|
+
} catch {
|
|
327
|
+
return false;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
async function diagnosePermit2SimulationFailure(config, signer, tokenAddress, permit2Payload, amountRequired) {
|
|
331
|
+
const payer = permit2Payload.permit2Authorization.from;
|
|
332
|
+
const diagnosticCalls = [
|
|
333
|
+
{
|
|
334
|
+
address: config.proxyAddress,
|
|
335
|
+
abi: config.proxyABI,
|
|
336
|
+
functionName: "PERMIT2"
|
|
337
|
+
},
|
|
338
|
+
{
|
|
339
|
+
address: tokenAddress,
|
|
340
|
+
abi: eip3009ABI,
|
|
341
|
+
functionName: "balanceOf",
|
|
342
|
+
args: [payer]
|
|
343
|
+
},
|
|
344
|
+
{
|
|
345
|
+
address: tokenAddress,
|
|
346
|
+
abi: erc20AllowanceAbi,
|
|
347
|
+
functionName: "allowance",
|
|
348
|
+
args: [payer, PERMIT2_ADDRESS]
|
|
349
|
+
}
|
|
350
|
+
];
|
|
351
|
+
try {
|
|
352
|
+
const results = await multicall(signer.readContract.bind(signer), diagnosticCalls);
|
|
353
|
+
const [proxyResult, balanceResult, allowanceResult] = results;
|
|
354
|
+
if (proxyResult.status === "failure") {
|
|
355
|
+
return { isValid: false, invalidReason: ErrPermit2ProxyNotDeployed, payer };
|
|
356
|
+
}
|
|
357
|
+
if (balanceResult.status === "success") {
|
|
358
|
+
const balance = balanceResult.result;
|
|
359
|
+
if (balance < BigInt(amountRequired)) {
|
|
360
|
+
return { isValid: false, invalidReason: ErrPermit2InsufficientBalance, payer };
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
if (allowanceResult.status === "success") {
|
|
364
|
+
const allowance = allowanceResult.result;
|
|
365
|
+
if (allowance < BigInt(amountRequired)) {
|
|
366
|
+
return { isValid: false, invalidReason: ErrPermit2AllowanceRequired, payer };
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
} catch {
|
|
370
|
+
}
|
|
371
|
+
return { isValid: false, invalidReason: ErrPermit2SimulationFailed, payer };
|
|
372
|
+
}
|
|
373
|
+
async function checkPermit2Prerequisites(config, signer, tokenAddress, payer, amountRequired) {
|
|
374
|
+
const diagnosticCalls = [
|
|
375
|
+
{
|
|
376
|
+
address: config.proxyAddress,
|
|
377
|
+
abi: config.proxyABI,
|
|
378
|
+
functionName: "PERMIT2"
|
|
379
|
+
},
|
|
380
|
+
{
|
|
381
|
+
address: tokenAddress,
|
|
382
|
+
abi: eip3009ABI,
|
|
383
|
+
functionName: "balanceOf",
|
|
384
|
+
args: [payer]
|
|
385
|
+
}
|
|
386
|
+
];
|
|
387
|
+
try {
|
|
388
|
+
const results = await multicall(signer.readContract.bind(signer), diagnosticCalls);
|
|
389
|
+
const [proxyResult, balanceResult] = results;
|
|
390
|
+
if (proxyResult.status === "failure") {
|
|
391
|
+
return { isValid: false, invalidReason: ErrPermit2ProxyNotDeployed, payer };
|
|
392
|
+
}
|
|
393
|
+
if (balanceResult.status === "success") {
|
|
394
|
+
const balance = balanceResult.result;
|
|
395
|
+
if (balance < BigInt(amountRequired)) {
|
|
396
|
+
return { isValid: false, invalidReason: ErrPermit2InsufficientBalance, payer };
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
} catch {
|
|
400
|
+
}
|
|
401
|
+
return { isValid: true, invalidReason: void 0, payer };
|
|
402
|
+
}
|
|
403
|
+
function buildExactPermit2SettleArgs(permit2Payload) {
|
|
404
|
+
return [
|
|
405
|
+
{
|
|
406
|
+
permitted: {
|
|
407
|
+
token: getAddress2(permit2Payload.permit2Authorization.permitted.token),
|
|
408
|
+
amount: BigInt(permit2Payload.permit2Authorization.permitted.amount)
|
|
409
|
+
},
|
|
410
|
+
nonce: BigInt(permit2Payload.permit2Authorization.nonce),
|
|
411
|
+
deadline: BigInt(permit2Payload.permit2Authorization.deadline)
|
|
412
|
+
},
|
|
413
|
+
getAddress2(permit2Payload.permit2Authorization.from),
|
|
414
|
+
{
|
|
415
|
+
to: getAddress2(permit2Payload.permit2Authorization.witness.to),
|
|
416
|
+
validAfter: BigInt(permit2Payload.permit2Authorization.witness.validAfter)
|
|
417
|
+
},
|
|
418
|
+
permit2Payload.signature
|
|
419
|
+
];
|
|
420
|
+
}
|
|
421
|
+
function buildUptoPermit2SettleArgs(permit2Payload, settlementAmount, facilitatorAddress) {
|
|
422
|
+
return [
|
|
423
|
+
{
|
|
424
|
+
permitted: {
|
|
425
|
+
token: getAddress2(permit2Payload.permit2Authorization.permitted.token),
|
|
426
|
+
amount: BigInt(permit2Payload.permit2Authorization.permitted.amount)
|
|
427
|
+
},
|
|
428
|
+
nonce: BigInt(permit2Payload.permit2Authorization.nonce),
|
|
429
|
+
deadline: BigInt(permit2Payload.permit2Authorization.deadline)
|
|
430
|
+
},
|
|
431
|
+
settlementAmount,
|
|
432
|
+
getAddress2(permit2Payload.permit2Authorization.from),
|
|
433
|
+
{
|
|
434
|
+
to: getAddress2(permit2Payload.permit2Authorization.witness.to),
|
|
435
|
+
facilitator: getAddress2(facilitatorAddress),
|
|
436
|
+
validAfter: BigInt(permit2Payload.permit2Authorization.witness.validAfter)
|
|
437
|
+
},
|
|
438
|
+
permit2Payload.signature
|
|
439
|
+
];
|
|
440
|
+
}
|
|
441
|
+
function splitEip2612Signature(signature) {
|
|
442
|
+
const sig = signature.startsWith("0x") ? signature.slice(2) : signature;
|
|
443
|
+
if (sig.length !== 130) {
|
|
444
|
+
throw new Error(
|
|
445
|
+
`invalid EIP-2612 signature length: expected 65 bytes (130 hex chars), got ${sig.length / 2} bytes`
|
|
446
|
+
);
|
|
447
|
+
}
|
|
448
|
+
const r = `0x${sig.slice(0, 64)}`;
|
|
449
|
+
const s = `0x${sig.slice(64, 128)}`;
|
|
450
|
+
const v = parseInt(sig.slice(128, 130), 16);
|
|
451
|
+
return { v, r, s };
|
|
452
|
+
}
|
|
453
|
+
async function createPermit2PayloadForProxy(proxyAddress, signer, x402Version, paymentRequirements) {
|
|
454
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
455
|
+
const nonce = createPermit2Nonce();
|
|
456
|
+
const validAfter = (now - 600).toString();
|
|
457
|
+
const deadline = (now + paymentRequirements.maxTimeoutSeconds).toString();
|
|
458
|
+
const permit2Authorization = {
|
|
459
|
+
from: signer.address,
|
|
460
|
+
permitted: {
|
|
461
|
+
token: getAddress2(paymentRequirements.asset),
|
|
462
|
+
amount: paymentRequirements.amount
|
|
463
|
+
},
|
|
464
|
+
spender: proxyAddress,
|
|
465
|
+
nonce,
|
|
466
|
+
deadline,
|
|
467
|
+
witness: {
|
|
468
|
+
to: getAddress2(paymentRequirements.payTo),
|
|
469
|
+
validAfter
|
|
470
|
+
}
|
|
471
|
+
};
|
|
472
|
+
const signature = await signPermit2Authorization(
|
|
473
|
+
signer,
|
|
474
|
+
permit2Authorization,
|
|
475
|
+
paymentRequirements
|
|
476
|
+
);
|
|
477
|
+
return {
|
|
478
|
+
x402Version,
|
|
479
|
+
payload: { signature, permit2Authorization }
|
|
480
|
+
};
|
|
481
|
+
}
|
|
482
|
+
async function signPermit2Authorization(signer, permit2Authorization, requirements) {
|
|
483
|
+
const chainId = getEvmChainId(requirements.network);
|
|
484
|
+
return await signer.signTypedData({
|
|
485
|
+
domain: { name: "Permit2", chainId, verifyingContract: PERMIT2_ADDRESS },
|
|
486
|
+
types: permit2WitnessTypes,
|
|
487
|
+
primaryType: "PermitWitnessTransferFrom",
|
|
488
|
+
message: {
|
|
489
|
+
permitted: {
|
|
490
|
+
token: getAddress2(permit2Authorization.permitted.token),
|
|
491
|
+
amount: BigInt(permit2Authorization.permitted.amount)
|
|
492
|
+
},
|
|
493
|
+
spender: getAddress2(permit2Authorization.spender),
|
|
494
|
+
nonce: BigInt(permit2Authorization.nonce),
|
|
495
|
+
deadline: BigInt(permit2Authorization.deadline),
|
|
496
|
+
witness: {
|
|
497
|
+
to: getAddress2(permit2Authorization.witness.to),
|
|
498
|
+
validAfter: BigInt(permit2Authorization.witness.validAfter)
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
});
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
export {
|
|
505
|
+
EIP2612_GAS_SPONSORING_KEY,
|
|
506
|
+
ERC20_APPROVAL_GAS_SPONSORING_KEY,
|
|
507
|
+
ERC20_APPROVAL_GAS_SPONSORING_VERSION,
|
|
508
|
+
extractEip2612GasSponsoringInfo,
|
|
509
|
+
extractErc20ApprovalGasSponsoringInfo,
|
|
510
|
+
resolveErc20ApprovalExtensionSigner,
|
|
511
|
+
validateErc20ApprovalForPayment,
|
|
512
|
+
ErrUptoInvalidScheme,
|
|
513
|
+
ErrUptoNetworkMismatch,
|
|
514
|
+
ErrUptoSettlementExceedsAmount,
|
|
515
|
+
ErrUptoFacilitatorMismatch,
|
|
516
|
+
waitAndReturnSettleResponse,
|
|
517
|
+
mapSettleError,
|
|
518
|
+
validateEip2612PermitForPayment,
|
|
519
|
+
simulatePermit2Settle,
|
|
520
|
+
simulatePermit2SettleWithPermit,
|
|
521
|
+
simulatePermit2SettleWithErc20Approval,
|
|
522
|
+
diagnosePermit2SimulationFailure,
|
|
523
|
+
checkPermit2Prerequisites,
|
|
524
|
+
buildExactPermit2SettleArgs,
|
|
525
|
+
buildUptoPermit2SettleArgs,
|
|
526
|
+
splitEip2612Signature,
|
|
527
|
+
createPermit2PayloadForProxy
|
|
528
|
+
};
|
|
529
|
+
//# sourceMappingURL=chunk-CRT6YNY5.mjs.map
|