uvd-x402-sdk 2.97.0 → 2.99.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -8
- package/dist/backend/index.d.mts +1 -1
- package/dist/backend/index.d.ts +1 -1
- package/dist/backend/index.js +238 -6
- package/dist/backend/index.js.map +1 -1
- package/dist/backend/index.mjs +232 -7
- package/dist/backend/index.mjs.map +1 -1
- package/dist/{index-DNTFp6WT.d.ts → index-BiL4seGs.d.ts} +124 -7
- package/dist/{index-ClOAmprt.d.mts → index-SaqboHsK.d.mts} +124 -7
- package/dist/index.d.mts +28 -6
- package/dist/index.d.ts +28 -6
- package/dist/index.js +38 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +38 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/backend/index.ts +343 -15
- package/src/escrow-preauth.arc-vector.json +101 -0
- package/src/escrow-preauth.ts +45 -4
- package/src/fixtures/arc-escrow-d.rpc.json +553 -0
- package/src/fixtures/escrow-operator-snapshot.json +1254 -0
- package/src/index.ts +1 -0
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/chains/index.ts","../src/types/index.ts","../src/utils/base64.ts","../src/utils/x402.ts","../src/utils/token-metadata.ts","../src/utils/validation.ts","../src/utils/personal-sign.ts","../src/utils/validity.ts","../src/utils/index.ts","../src/providers/solana/index.ts","../src/dx402.ts","../src/receipts.ts","../src/client/X402Client.ts","../src/policy.ts","../src/index.ts","../src/adapters/env-key.ts","../src/adapters/ows.ts","../src/facilitator.ts","../src/events.ts","../src/erc8128.ts","../src/escrow-preauth.ts","../src/erc7702.ts","../src/lifecycle-auth.ts","../src/providers/hedera/index.ts","../src/backend/index.ts","../src/backend/facilitator-error.ts"],"names":["SUPPORTED_CHAINS","DEFAULT_FACILITATOR_URL","DEFAULT_CHAIN","CAIP2_IDENTIFIERS","CAIP2_TO_CHAIN","DEFAULT_CONFIG","X402Error","DEFAULT_PAYMENT_HEADER","PAYMENT_HEADER_NAMES","DEFAULT_VALIDITY_SECONDS","MAX_VALIDITY_SECONDS","publicKeyString","nobleHexToBytes","bytesToHex","keccak_256","secp256k1","sha512","x25519","hkdf","sha256","gcm","edwardsToMontgomeryPub","digest","randomBytes","paymentId","contentHash","ed25519","ethers","SVMProvider","account","decoder","ZERO_ADDRESS","parseUnits","formatUnits","requirements","reqOptions"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * uvd-x402-sdk - Chain Registry\n *\n * Complete configuration for all 29 supported blockchain networks.\n * EVM chains (17): Use ERC-3009 TransferWithAuthorization (includes Scroll, SKALE Base, Robinhood Chain mainnet + testnet, Arc mainnet + testnet)\n * BSC is registered but disabled (Binance-Peg USDC has no ERC-3009), so it is not in those counts.\n * SVM chains (2): Solana and Fogo - Use SPL tokens with partially-signed transactions\n * Stellar (1): Uses Soroban authorization entries\n * NEAR (1): Uses NEP-366 meta-transactions\n * Algorand (2): Uses ASA transfers with atomic transaction groups\n * Sui (2): Uses sponsored transactions (facilitator pays gas)\n * XRPL (2): Native XRP via pre-signed Payment transaction blobs (facilitator pays fee)\n */\n\nimport type { ChainConfig, NetworkType, TokenType, TokenConfig } from '../types';\n\n/**\n * Default facilitator URL for x402 payments\n */\nexport const DEFAULT_FACILITATOR_URL = 'https://facilitator.ultravioletadao.xyz';\n\n/**\n * All supported chains configuration\n *\n * To add a new chain:\n * 1. Add chain config below with all required fields\n * 2. Verify USDC contract supports ERC-3009 (transferWithAuthorization) for EVM chains\n * 3. Test on testnet first before enabling\n */\nexport const SUPPORTED_CHAINS: Record<string, ChainConfig> = {\n 'hedera:mainnet': {\n chainId: 0, chainIdHex: '0x0', name: 'hedera:mainnet',\n displayName: 'Hedera', networkType: 'hedera',\n rpcUrl: 'https://mainnet-public.mirrornode.hedera.com', explorerUrl: 'https://hashscan.io/mainnet',\n nativeCurrency: { name: 'HBAR', symbol: 'HBAR', decimals: 8 },\n usdc: { address: '0.0.456858', decimals: 6, name: 'USDC', version: '' },\n tokens: {\n usdc: { address: '0.0.456858', decimals: 6, name: 'USDC', version: '' },\n },\n x402: { facilitatorUrl: DEFAULT_FACILITATOR_URL, enabled: true },\n },\n 'hedera:testnet': {\n chainId: 0, chainIdHex: '0x0', name: 'hedera:testnet',\n displayName: 'Hedera Testnet', networkType: 'hedera',\n rpcUrl: 'https://testnet.mirrornode.hedera.com', explorerUrl: 'https://hashscan.io/testnet',\n nativeCurrency: { name: 'HBAR', symbol: 'HBAR', decimals: 8 },\n usdc: { address: '0.0.429274', decimals: 6, name: 'USDC', version: '' },\n tokens: {\n usdc: { address: '0.0.429274', decimals: 6, name: 'USDC', version: '' },\n },\n x402: { facilitatorUrl: DEFAULT_FACILITATOR_URL, enabled: true },\n },\n\n // ============================================================================\n // EVM CHAINS (16 enabled + BSC, disabled)\n // ============================================================================\n\n base: {\n chainId: 8453,\n chainIdHex: '0x2105',\n name: 'base',\n displayName: 'Base',\n networkType: 'evm',\n rpcUrl: 'https://mainnet.base.org',\n explorerUrl: 'https://basescan.org',\n nativeCurrency: {\n name: 'Ethereum',\n symbol: 'ETH',\n decimals: 18,\n },\n usdc: {\n address: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\n decimals: 6,\n name: 'USD Coin',\n version: '2',\n },\n tokens: {\n usdc: {\n address: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\n decimals: 6,\n name: 'USD Coin',\n version: '2',\n },\n eurc: {\n address: '0x60a3E35Cc302bFA44Cb288Bc5a4F316Fdb1adb42',\n decimals: 6,\n name: 'EURC',\n version: '2',\n usdPegged: false,\n },\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true,\n },\n },\n\n avalanche: {\n chainId: 43114,\n chainIdHex: '0xa86a',\n name: 'avalanche',\n displayName: 'Avalanche C-Chain',\n networkType: 'evm',\n rpcUrl: 'https://avalanche-c-chain-rpc.publicnode.com',\n explorerUrl: 'https://snowtrace.io',\n nativeCurrency: {\n name: 'Avalanche',\n symbol: 'AVAX',\n decimals: 18,\n },\n usdc: {\n address: '0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E',\n decimals: 6,\n name: 'USD Coin',\n version: '2',\n },\n tokens: {\n usdc: {\n address: '0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E',\n decimals: 6,\n name: 'USD Coin',\n version: '2',\n },\n eurc: {\n address: '0xC891EB4cbdEFf6e073e859e987815Ed1505c2ACD',\n decimals: 6,\n name: 'EURC',\n version: '2',\n usdPegged: false,\n },\n ausd: {\n address: '0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a',\n decimals: 6,\n name: 'Agora Dollar',\n version: '1',\n },\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true,\n },\n },\n\n ethereum: {\n chainId: 1,\n chainIdHex: '0x1',\n name: 'ethereum',\n displayName: 'Ethereum',\n networkType: 'evm',\n rpcUrl: 'https://eth.llamarpc.com',\n explorerUrl: 'https://etherscan.io',\n nativeCurrency: {\n name: 'Ethereum',\n symbol: 'ETH',\n decimals: 18,\n },\n usdc: {\n address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',\n decimals: 6,\n name: 'USD Coin',\n version: '2',\n },\n tokens: {\n usdc: {\n address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',\n decimals: 6,\n name: 'USD Coin',\n version: '2',\n },\n eurc: {\n address: '0x1aBaEA1f7C830bD89Acc67eC4af516284b1bC33c',\n decimals: 6,\n name: 'Euro Coin',\n version: '2',\n usdPegged: false,\n },\n ausd: {\n address: '0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a',\n decimals: 6,\n name: 'Agora Dollar',\n version: '1',\n },\n pyusd: {\n address: '0x6c3ea9036406852006290770BEdFcAbA0e23A0e8',\n decimals: 6,\n name: 'PayPal USD',\n version: '1',\n },\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true,\n },\n },\n\n polygon: {\n chainId: 137,\n chainIdHex: '0x89',\n name: 'polygon',\n displayName: 'Polygon',\n networkType: 'evm',\n rpcUrl: 'https://polygon-rpc.com',\n explorerUrl: 'https://polygonscan.com',\n nativeCurrency: {\n name: 'Polygon',\n symbol: 'POL',\n decimals: 18,\n },\n usdc: {\n address: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',\n decimals: 6,\n name: 'USD Coin',\n version: '2',\n },\n tokens: {\n usdc: {\n address: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',\n decimals: 6,\n name: 'USD Coin',\n version: '2',\n },\n ausd: {\n address: '0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a',\n decimals: 6,\n name: 'Agora Dollar',\n version: '1',\n },\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true,\n },\n },\n\n arbitrum: {\n chainId: 42161,\n chainIdHex: '0xa4b1',\n name: 'arbitrum',\n displayName: 'Arbitrum One',\n networkType: 'evm',\n rpcUrl: 'https://arb1.arbitrum.io/rpc',\n explorerUrl: 'https://arbiscan.io',\n nativeCurrency: {\n name: 'Ethereum',\n symbol: 'ETH',\n decimals: 18,\n },\n usdc: {\n address: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',\n decimals: 6,\n name: 'USD Coin',\n version: '2',\n },\n tokens: {\n usdc: {\n address: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',\n decimals: 6,\n name: 'USD Coin',\n version: '2',\n },\n ausd: {\n address: '0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a',\n decimals: 6,\n name: 'Agora Dollar',\n version: '1',\n },\n usdt: {\n address: '0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9',\n decimals: 6,\n name: 'USD₮0',\n version: '1',\n },\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true,\n },\n },\n\n optimism: {\n chainId: 10,\n chainIdHex: '0xa',\n name: 'optimism',\n displayName: 'Optimism',\n networkType: 'evm',\n rpcUrl: 'https://mainnet.optimism.io',\n explorerUrl: 'https://optimistic.etherscan.io',\n nativeCurrency: {\n name: 'Ethereum',\n symbol: 'ETH',\n decimals: 18,\n },\n usdc: {\n address: '0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85',\n decimals: 6,\n name: 'USD Coin',\n version: '2',\n },\n tokens: {\n usdc: {\n address: '0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85',\n decimals: 6,\n name: 'USD Coin',\n version: '2',\n },\n usdt: {\n address: '0x01bff41798a0bcf287b996046ca68b395dbc1071',\n decimals: 6,\n name: 'USD₮0',\n version: '1',\n },\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true,\n },\n },\n\n celo: {\n chainId: 42220,\n chainIdHex: '0xa4ec',\n name: 'celo',\n displayName: 'Celo',\n networkType: 'evm',\n rpcUrl: 'https://forno.celo.org',\n explorerUrl: 'https://celoscan.io',\n nativeCurrency: {\n name: 'Celo',\n symbol: 'CELO',\n decimals: 18,\n },\n usdc: {\n address: '0xcebA9300f2b948710d2653dD7B07f33A8B32118C',\n decimals: 6,\n name: 'USDC', // Celo uses \"USDC\" not \"USD Coin\" for EIP-712\n version: '2',\n },\n tokens: {\n usdc: {\n address: '0xcebA9300f2b948710d2653dD7B07f33A8B32118C',\n decimals: 6,\n name: 'USDC', // Celo uses \"USDC\" not \"USD Coin\" for EIP-712\n version: '2',\n },\n usdt: {\n address: '0x48065fbBE25f71C9282ddf5e1cD6D6A887483D5e',\n decimals: 6,\n name: 'Tether USD', // Celo USDT uses \"Tether USD\" for EIP-712\n version: '1',\n },\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true,\n },\n },\n\n hyperevm: {\n chainId: 999,\n chainIdHex: '0x3e7',\n name: 'hyperevm',\n displayName: 'HyperEVM',\n networkType: 'evm',\n rpcUrl: 'https://rpc.hyperliquid.xyz/evm',\n explorerUrl: 'https://hyperevmscan.io',\n nativeCurrency: {\n name: 'Ethereum',\n symbol: 'ETH',\n decimals: 18,\n },\n usdc: {\n address: '0xb88339CB7199b77E23DB6E890353E22632Ba630f',\n decimals: 6,\n name: 'USDC', // HyperEVM uses \"USDC\" not \"USD Coin\"\n version: '2',\n },\n tokens: {\n usdc: {\n address: '0xb88339CB7199b77E23DB6E890353E22632Ba630f',\n decimals: 6,\n name: 'USDC', // HyperEVM uses \"USDC\" not \"USD Coin\"\n version: '2',\n },\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true,\n },\n },\n\n unichain: {\n chainId: 130,\n chainIdHex: '0x82',\n name: 'unichain',\n displayName: 'Unichain',\n networkType: 'evm',\n rpcUrl: 'https://unichain-rpc.publicnode.com',\n explorerUrl: 'https://uniscan.xyz',\n nativeCurrency: {\n name: 'Ethereum',\n symbol: 'ETH',\n decimals: 18,\n },\n usdc: {\n address: '0x078d782b760474a361dda0af3839290b0ef57ad6',\n decimals: 6,\n name: 'USDC', // Unichain uses \"USDC\" not \"USD Coin\"\n version: '2',\n },\n tokens: {\n usdc: {\n address: '0x078d782b760474a361dda0af3839290b0ef57ad6',\n decimals: 6,\n name: 'USDC', // Unichain uses \"USDC\" not \"USD Coin\"\n version: '2',\n },\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true,\n },\n },\n\n monad: {\n chainId: 143,\n chainIdHex: '0x8f',\n name: 'monad',\n displayName: 'Monad',\n networkType: 'evm',\n rpcUrl: 'https://rpc.monad.xyz',\n explorerUrl: 'https://monad.socialscan.io',\n nativeCurrency: {\n name: 'Monad',\n symbol: 'MON',\n decimals: 18,\n },\n usdc: {\n address: '0x754704bc059f8c67012fed69bc8a327a5aafb603',\n decimals: 6,\n name: 'USDC', // Monad uses \"USDC\" not \"USD Coin\"\n version: '2',\n },\n tokens: {\n usdc: {\n address: '0x754704bc059f8c67012fed69bc8a327a5aafb603',\n decimals: 6,\n name: 'USDC', // Monad uses \"USDC\" not \"USD Coin\"\n version: '2',\n },\n ausd: {\n address: '0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a',\n decimals: 6,\n name: 'Agora Dollar',\n version: '1',\n },\n usdt: {\n address: '0xe7cd86e13AC4309349F30B3435a9d337750fC82D',\n decimals: 6,\n name: 'USD\\u20AE0', // USD₮0 (USDT0 omnichain via LayerZero)\n version: '1',\n },\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true,\n },\n },\n\n bsc: {\n chainId: 56,\n chainIdHex: '0x38',\n name: 'bsc',\n displayName: 'BNB Smart Chain',\n networkType: 'evm',\n rpcUrl: 'https://binance.llamarpc.com',\n explorerUrl: 'https://bscscan.com',\n nativeCurrency: {\n name: 'Binance Coin',\n symbol: 'BNB',\n decimals: 18,\n },\n usdc: {\n // Binance-Peg USDC — 18 decimals, NOT the 6 every other chain uses.\n address: '0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d',\n decimals: 18,\n name: 'USD Coin',\n version: '2',\n },\n tokens: {\n usdc: {\n address: '0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d',\n decimals: 18,\n name: 'USD Coin',\n version: '2',\n },\n ausd: {\n address: '0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a',\n decimals: 6,\n name: 'Agora Dollar',\n version: '1',\n },\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n // Disabled on purpose: Binance-Peg USDC does not implement ERC-3009\n // `transferWithAuthorization`, so the exact scheme cannot settle it. The\n // entry exists so the 18-decimal figure is on record — assuming the usual\n // 6 here mis-prices a payment by 12 orders of magnitude.\n enabled: false,\n },\n },\n\n scroll: {\n chainId: 534352,\n chainIdHex: '0x82750',\n name: 'scroll',\n displayName: 'Scroll',\n networkType: 'evm',\n rpcUrl: 'https://rpc.scroll.io',\n explorerUrl: 'https://scrollscan.com',\n nativeCurrency: {\n name: 'Ethereum',\n symbol: 'ETH',\n decimals: 18,\n },\n usdc: {\n address: '0x06eFdBFf2a14a7c8E15944D1F4A48F9F95F663A4',\n decimals: 6,\n name: 'USD Coin',\n version: '2',\n },\n tokens: {\n usdc: {\n address: '0x06eFdBFf2a14a7c8E15944D1F4A48F9F95F663A4',\n decimals: 6,\n name: 'USD Coin',\n version: '2',\n },\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true,\n },\n },\n\n 'skale-base': {\n chainId: 1187947933,\n chainIdHex: '0x46cea59d',\n name: 'skale-base',\n displayName: 'SKALE Base',\n networkType: 'evm',\n rpcUrl: 'https://skale-base.skalenodes.com/v1/base',\n explorerUrl: 'https://skale-base-explorer.skalenodes.com',\n nativeCurrency: {\n name: 'CREDIT',\n symbol: 'CREDIT',\n decimals: 18,\n },\n usdc: {\n address: '0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20',\n decimals: 6,\n name: 'Bridged USDC (SKALE Bridge)', // Must match on-chain EIP-712 domain exactly\n version: '2',\n },\n tokens: {\n usdc: {\n address: '0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20',\n decimals: 6,\n name: 'Bridged USDC (SKALE Bridge)', // Must match on-chain EIP-712 domain exactly\n version: '2',\n },\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true,\n },\n },\n\n 'skale-base-sepolia': {\n chainId: 324705682,\n chainIdHex: '0x135a9d92',\n name: 'skale-base-sepolia',\n displayName: 'SKALE Base Sepolia',\n networkType: 'evm',\n rpcUrl: 'https://base-sepolia-testnet.skalenodes.com/v1/jubilant-horrible-ancha',\n explorerUrl: 'https://base-sepolia-testnet-explorer.skalenodes.com',\n nativeCurrency: {\n name: 'CREDIT',\n symbol: 'CREDIT',\n decimals: 18,\n },\n usdc: {\n address: '0x2e08028E3C4c2356572E096d8EF835cD5C6030bD',\n decimals: 6,\n name: 'Bridged USDC (SKALE Bridge)', // Must match on-chain EIP-712 domain exactly\n version: '2',\n },\n tokens: {\n usdc: {\n address: '0x2e08028E3C4c2356572E096d8EF835cD5C6030bD',\n decimals: 6,\n name: 'Bridged USDC (SKALE Bridge)', // Must match on-chain EIP-712 domain exactly\n version: '2',\n },\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true,\n },\n },\n\n // Robinhood Chain (Arbitrum Orbit L2). NOTE: there is NO USDC on this chain -\n // the settlement stablecoin is Paxos USDG (Global Dollar). The `usdc` field\n // below carries USDG for interface compatibility (same pattern as XRPL's native\n // asset), and `tokens.usdg` is the canonical entry.\n // CRITICAL: USDG's on-chain version() getter REVERTS, so the EIP-712 domain\n // { name: 'Global Dollar', version: '1' } can NEVER be resolved on-chain and\n // MUST come from this config (mirrored into PaymentRequirements.extra by callers).\n robinhood: {\n chainId: 4663,\n chainIdHex: '0x1237',\n name: 'robinhood',\n displayName: 'Robinhood Chain',\n networkType: 'evm',\n rpcUrl: 'https://rpc.mainnet.chain.robinhood.com',\n explorerUrl: 'https://robinhoodchain.blockscout.com',\n nativeCurrency: {\n name: 'Ethereum',\n symbol: 'ETH',\n decimals: 18,\n },\n usdc: {\n address: '0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168', // Paxos USDG (no USDC on this chain)\n decimals: 6,\n name: 'Global Dollar', // on-chain version() reverts; domain must be supplied off-chain\n version: '1',\n },\n tokens: {\n usdg: {\n address: '0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168',\n decimals: 6,\n name: 'Global Dollar', // on-chain version() reverts; domain must be supplied off-chain\n version: '1',\n },\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true,\n },\n },\n\n 'robinhood-testnet': {\n chainId: 46630,\n chainIdHex: '0xb626',\n name: 'robinhood-testnet',\n displayName: 'Robinhood Chain Testnet',\n networkType: 'evm',\n rpcUrl: 'https://rpc.testnet.chain.robinhood.com',\n explorerUrl: 'https://explorer.testnet.chain.robinhood.com',\n nativeCurrency: {\n name: 'Ethereum',\n symbol: 'ETH',\n decimals: 18,\n },\n usdc: {\n address: '0x7E955252E15c84f5768B83c41a71F9eba181802F', // Paxos USDG testnet (no USDC on this chain)\n decimals: 6,\n name: 'Global Dollar', // on-chain version() reverts; domain must be supplied off-chain\n version: '1',\n },\n tokens: {\n usdg: {\n address: '0x7E955252E15c84f5768B83c41a71F9eba181802F',\n decimals: 6,\n name: 'Global Dollar', // on-chain version() reverts; domain must be supplied off-chain\n version: '1',\n },\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true,\n },\n },\n\n // Arc testnet (Circle). The stablecoin IS the chain's native asset, so the SAME\n // balance is readable at TWO precisions:\n // - native / gas, via eth_getBalance and EIP-1559 fees: 18 decimals\n // - ERC-20 interface, via balanceOf and transferWithAuthorization: 6 decimals\n // (the ERC-20 view is floor(native / 10^12))\n // An x402 payment is an EIP-3009 authorization against the ERC-20 interface, so\n // its `value` is ALWAYS in the 6 of `tokens.usdc.decimals`. Scaling a price with\n // `nativeCurrency.decimals` instead charges 10^12 times the amount: $0.01 would\n // be signed as 10000000000000000 units, i.e. 10 billion USDC. `nativeCurrency`\n // below is correct where it is actually used -- the wallet_addEthereumChain\n // params -- and must never reach `parseUnits` for a payment.\n // Pinned by src/arc-testnet.test.ts.\n //\n // Mainnet (5042) and testnet (5042002) were verified independently against\n // their official RPCs on 2026-09-16. EURC domains checked on 2026-09-17; funded EURC payments settled on Arc mainnet on\n // 2026-09-22 (x402 v1/v2, docs/networks/arc.md); testnet pending.\n arc: {\n chainId: 5042,\n chainIdHex: '0x13b2',\n name: 'arc',\n displayName: 'Arc',\n networkType: 'evm',\n rpcUrl: 'https://rpc.mainnet.arc.io',\n explorerUrl: 'https://explorer.arc.io',\n nativeCurrency: {\n name: 'USD Coin',\n symbol: 'USDC',\n decimals: 18, // gas precision ONLY -- never the scale of a payment\n },\n usdc: {\n address: '0x3600000000000000000000000000000000000000',\n decimals: 6, // ERC-20 interface, which is what an EIP-3009 value is denominated in\n name: 'USDC', // on-chain name(); must match the EIP-712 domain exactly\n version: '2',\n },\n tokens: {\n usdc: {\n address: '0x3600000000000000000000000000000000000000',\n decimals: 6,\n name: 'USDC',\n version: '2',\n },\n eurc: {\n address: '0xbEf5f6d51CB62b58e6A8f77868681825C6fe21c1',\n decimals: 6,\n name: 'EURC',\n version: '2',\n usdPegged: false,\n },\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true,\n },\n },\n\n 'arc-testnet': {\n chainId: 5042002,\n chainIdHex: '0x4cef52',\n name: 'arc-testnet',\n displayName: 'Arc Testnet',\n networkType: 'evm',\n rpcUrl: 'https://rpc.testnet.arc.io',\n explorerUrl: 'https://explorer.testnet.arc.io',\n nativeCurrency: {\n name: 'USD Coin',\n symbol: 'USDC',\n decimals: 18, // gas precision ONLY -- never the scale of a payment\n },\n usdc: {\n address: '0x3600000000000000000000000000000000000000',\n decimals: 6, // ERC-20 interface, which is what an EIP-3009 value is denominated in\n name: 'USDC', // on-chain name(); must match the EIP-712 domain exactly\n version: '2',\n },\n tokens: {\n usdc: {\n address: '0x3600000000000000000000000000000000000000',\n decimals: 6,\n name: 'USDC',\n version: '2',\n },\n eurc: {\n address: '0x89B50855Aa3bE2F677cD6303Cec089B5F319D72a',\n decimals: 6,\n name: 'EURC',\n version: '2',\n usdPegged: false,\n },\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true,\n },\n },\n\n // ============================================================================\n // SVM CHAINS (2 networks) - Solana Virtual Machine\n // ============================================================================\n\n solana: {\n chainId: 0, // Non-EVM\n chainIdHex: '0x0',\n name: 'solana',\n displayName: 'Solana',\n networkType: 'svm',\n rpcUrl: 'https://api.mainnet-beta.solana.com',\n explorerUrl: 'https://solscan.io',\n nativeCurrency: {\n name: 'Solana',\n symbol: 'SOL',\n decimals: 9,\n },\n usdc: {\n address: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', // USDC SPL token mint\n decimals: 6,\n name: 'USD Coin',\n version: '1',\n },\n tokens: {\n usdc: {\n address: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', // USDC SPL token mint\n decimals: 6,\n name: 'USD Coin',\n version: '1',\n },\n ausd: {\n address: 'AUSD1jCcCyPLybk1YnvPWsHQSrZ46dxwoMniN4N2UEB9', // AUSD Token2022 mint\n decimals: 6,\n name: 'Agora Dollar',\n version: '1',\n },\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true,\n },\n },\n\n fogo: {\n chainId: 0, // Non-EVM (SVM)\n chainIdHex: '0x0',\n name: 'fogo',\n displayName: 'Fogo',\n networkType: 'svm',\n rpcUrl: 'https://rpc.fogo.nightly.app/',\n explorerUrl: 'https://explorer.fogo.nightly.app',\n nativeCurrency: {\n name: 'Fogo',\n symbol: 'FOGO',\n decimals: 9,\n },\n usdc: {\n address: 'uSd2czE61Evaf76RNbq4KPpXnkiL3irdzgLFUMe3NoG', // Fogo USDC mint\n decimals: 6,\n name: 'USDC',\n version: '1',\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true,\n },\n },\n\n // ============================================================================\n // STELLAR (1 network)\n // ============================================================================\n\n stellar: {\n chainId: 0, // Non-EVM\n chainIdHex: '0x0',\n name: 'stellar',\n displayName: 'Stellar',\n networkType: 'stellar',\n rpcUrl: 'https://horizon.stellar.org',\n explorerUrl: 'https://stellar.expert/explorer/public',\n nativeCurrency: {\n name: 'Lumens',\n symbol: 'XLM',\n decimals: 7, // Stellar uses 7 decimals (stroops)\n },\n usdc: {\n address: 'CCW67TSZV3SSS2HXMBQ5JFGCKJNXKZM7UQUWUZPUTHXSTZLEO7SJMI75', // Soroban Asset Contract\n decimals: 7, // Stellar USDC uses 7 decimals\n name: 'USDC',\n version: '1',\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true,\n },\n },\n\n // ============================================================================\n // NEAR (1 network) - Uses NEP-366 meta-transactions\n // ============================================================================\n\n near: {\n chainId: 0, // Non-EVM\n chainIdHex: '0x0',\n name: 'near',\n displayName: 'NEAR Protocol',\n networkType: 'near',\n rpcUrl: 'https://rpc.mainnet.near.org',\n explorerUrl: 'https://nearblocks.io',\n nativeCurrency: {\n name: 'NEAR',\n symbol: 'NEAR',\n decimals: 24, // NEAR uses 24 decimals (yoctoNEAR)\n },\n usdc: {\n address: '17208628f84f5d6ad33f0da3bbbeb27ffcb398eac501a31bd6ad2011e36133a1', // Native Circle USDC\n decimals: 6,\n name: 'USDC',\n version: '1',\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true, // NEP-366 meta-transactions supported\n },\n },\n\n // ============================================================================\n // ALGORAND (2 networks) - Uses ASA transfers with atomic transaction groups\n // ============================================================================\n\n algorand: {\n chainId: 0, // Non-EVM (Algorand uses genesis hash for network identification)\n chainIdHex: '0x0',\n name: 'algorand',\n displayName: 'Algorand',\n networkType: 'algorand',\n rpcUrl: 'https://mainnet-api.algonode.cloud',\n explorerUrl: 'https://allo.info',\n nativeCurrency: {\n name: 'Algo',\n symbol: 'ALGO',\n decimals: 6, // Algorand uses 6 decimals (microAlgos)\n },\n usdc: {\n address: '31566704', // USDC ASA ID on Algorand mainnet\n decimals: 6,\n name: 'USDC',\n version: '1',\n },\n tokens: {\n usdc: {\n address: '31566704', // USDC ASA ID on Algorand mainnet\n decimals: 6,\n name: 'USDC',\n version: '1',\n },\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true,\n },\n },\n\n 'algorand-testnet': {\n chainId: 0, // Non-EVM\n chainIdHex: '0x0',\n name: 'algorand-testnet',\n displayName: 'Algorand Testnet',\n networkType: 'algorand',\n rpcUrl: 'https://testnet-api.algonode.cloud',\n explorerUrl: 'https://testnet.allo.info',\n nativeCurrency: {\n name: 'Algo',\n symbol: 'ALGO',\n decimals: 6,\n },\n usdc: {\n address: '10458941', // USDC ASA ID on Algorand testnet\n decimals: 6,\n name: 'USDC',\n version: '1',\n },\n tokens: {\n usdc: {\n address: '10458941', // USDC ASA ID on Algorand testnet\n decimals: 6,\n name: 'USDC',\n version: '1',\n },\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true,\n },\n },\n\n // ============================================================================\n // SUI (2 networks) - Uses sponsored transactions (facilitator pays gas)\n // ============================================================================\n\n sui: {\n chainId: 0, // Non-EVM\n chainIdHex: '0x0',\n name: 'sui',\n displayName: 'Sui',\n networkType: 'sui',\n rpcUrl: 'https://fullnode.mainnet.sui.io:443',\n explorerUrl: 'https://suiscan.xyz/mainnet',\n nativeCurrency: {\n name: 'Sui',\n symbol: 'SUI',\n decimals: 9,\n },\n usdc: {\n // USDC coin type on Sui mainnet\n address: '0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC',\n decimals: 6,\n name: 'USDC',\n version: '1',\n },\n tokens: {\n usdc: {\n address: '0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC',\n decimals: 6,\n name: 'USDC',\n version: '1',\n },\n ausd: {\n // AUSD (Agora USD) coin type on Sui mainnet\n address: '0x2053d08c1e2bd02791056171aab0fd12bd7cd7efad2ab8f6b9c8902f14df2ff2::ausd::AUSD',\n decimals: 6,\n name: 'AUSD',\n version: '1',\n },\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true,\n },\n },\n\n 'sui-testnet': {\n chainId: 0, // Non-EVM\n chainIdHex: '0x0',\n name: 'sui-testnet',\n displayName: 'Sui Testnet',\n networkType: 'sui',\n rpcUrl: 'https://fullnode.testnet.sui.io:443',\n explorerUrl: 'https://suiscan.xyz/testnet',\n nativeCurrency: {\n name: 'Sui',\n symbol: 'SUI',\n decimals: 9,\n },\n usdc: {\n // USDC coin type on Sui testnet\n address: '0xa1ec7fc00a6f40db9693ad1415d0c193ad3906494428cf252621037bd7117e29::usdc::USDC',\n decimals: 6,\n name: 'USDC',\n version: '1',\n },\n tokens: {\n usdc: {\n address: '0xa1ec7fc00a6f40db9693ad1415d0c193ad3906494428cf252621037bd7117e29::usdc::USDC',\n decimals: 6,\n name: 'USDC',\n version: '1',\n },\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true,\n },\n },\n\n // ============================================================================\n // XRPL (2 networks) - XRP Ledger, native XRP via pre-signed Payment blobs\n // ============================================================================\n\n // Named `xrpl`, which is the only spelling the facilitator puts on the wire\n // (x402-rs/src/network.rs:189). `xrpl-mainnet` still resolves, as an alias.\n xrpl: {\n chainId: 0, // Non-EVM (XRPL uses network id strings, no numeric chain ID)\n chainIdHex: '0x0',\n name: 'xrpl',\n displayName: 'XRP Ledger',\n networkType: 'xrpl',\n rpcUrl: 'https://xrplcluster.com',\n explorerUrl: 'https://livenet.xrpl.org',\n nativeCurrency: {\n name: 'XRP',\n symbol: 'XRP',\n decimals: 6, // XRPL uses 6 decimals (drops); 1 XRP = 1,000,000 drops\n },\n // XRPL settles in native XRP - there is no USDC/token contract.\n // The `usdc` field describes the native asset for interface compatibility.\n // `usdPegged: false` is what stops that compatibility shim from being read\n // as a price: the key says usdc, the value is XRP, and a caller who writes\n // \"10.00\" means ten dollars. See TokenConfig.usdPegged.\n usdc: {\n address: 'XRP', // Native asset - no token contract\n decimals: 6,\n name: 'XRP',\n version: '1',\n usdPegged: false,\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true,\n },\n },\n\n 'xrpl-testnet': {\n chainId: 0, // Non-EVM\n chainIdHex: '0x0',\n name: 'xrpl-testnet',\n displayName: 'XRP Ledger Testnet',\n networkType: 'xrpl',\n rpcUrl: 'https://s.altnet.rippletest.net:51234',\n explorerUrl: 'https://testnet.xrpl.org',\n nativeCurrency: {\n name: 'XRP',\n symbol: 'XRP',\n decimals: 6,\n },\n // XRPL settles in native XRP - there is no USDC/token contract.\n usdc: {\n address: 'XRP', // Native asset - no token contract\n decimals: 6,\n name: 'XRP',\n version: '1',\n usdPegged: false,\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true,\n },\n },\n};\n\n/**\n * Alternate spellings that resolve to a registry entry without becoming one.\n *\n * A caller may WRITE these; the SDK never puts one on the wire, and they are\n * not separate networks, so counts and listings stay honest. The facilitator\n * keeps exactly this distinction: its `FromStr` takes `xrpl-mainnet` while\n * everything it publishes says `xrpl`, and the comment there calls that\n * spelling \"right for a lookup and wrong for a wire format\"\n * (`x402-rs/src/network.rs:251,189,719`).\n *\n * Mirrors `_NETWORK_ALIASES` in the Python SDK (`networks/base.py:199`).\n */\nexport const CHAIN_ALIASES: Record<string, string> = {\n hedera: 'hedera:mainnet',\n 'hedera-testnet': 'hedera:testnet',\n // Renamed in 2.85.0: the facilitator advertises the mainnet as `xrpl`.\n 'xrpl-mainnet': 'xrpl',\n};\n\n/**\n * Default chain for new users\n */\nexport const DEFAULT_CHAIN = 'base';\n\n/**\n * Get chain config by chain ID\n */\nexport function getChainById(chainId: number): ChainConfig | undefined {\n return Object.values(SUPPORTED_CHAINS).find(chain => chain.chainId === chainId);\n}\n\n/**\n * Get chain config by name (case-insensitive)\n */\nexport function getChainByName(name: string): ChainConfig | undefined {\n const key = name.toLowerCase();\n return SUPPORTED_CHAINS[key] ?? SUPPORTED_CHAINS[CHAIN_ALIASES[key] ?? ''];\n}\n\n/**\n * Check if a chain is supported\n */\nexport function isChainSupported(chainIdOrName: number | string): boolean {\n if (typeof chainIdOrName === 'number') {\n return Object.values(SUPPORTED_CHAINS).some(chain => chain.chainId === chainIdOrName);\n }\n return getChainByName(chainIdOrName) !== undefined;\n}\n\n/**\n * Get list of enabled chains\n */\nexport function getEnabledChains(): ChainConfig[] {\n return Object.values(SUPPORTED_CHAINS).filter(chain => chain.x402.enabled);\n}\n\n/**\n * Get list of chains by network type\n */\nexport function getChainsByNetworkType(networkType: NetworkType): ChainConfig[] {\n return Object.values(SUPPORTED_CHAINS).filter(\n chain => chain.networkType === networkType && chain.x402.enabled\n );\n}\n\n/**\n * Get all EVM chain IDs (for wallet_switchEthereumChain)\n */\nexport function getEVMChainIds(): number[] {\n return getChainsByNetworkType('evm').map(chain => chain.chainId);\n}\n\n/**\n * Get list of SVM chains (Solana, Fogo)\n */\nexport function getSVMChains(): ChainConfig[] {\n return Object.values(SUPPORTED_CHAINS).filter(\n chain => chain.networkType === 'svm' && chain.x402.enabled\n );\n}\n\n/**\n * Check if a chain is SVM-based (Solana Virtual Machine)\n */\nexport function isSVMChain(chainName: string): boolean {\n const chain = getChainByName(chainName);\n return chain?.networkType === 'svm';\n}\n\n/**\n * Get list of Sui chains\n */\nexport function getSuiChains(): ChainConfig[] {\n return Object.values(SUPPORTED_CHAINS).filter(\n chain => chain.networkType === 'sui' && chain.x402.enabled\n );\n}\n\n/**\n * Check if a chain is Sui-based\n */\nexport function isSuiChain(chainName: string): boolean {\n const chain = getChainByName(chainName);\n return chain?.networkType === 'sui';\n}\n\n/**\n * Get network type from chain name\n */\nexport function getNetworkType(chainName: string): NetworkType | undefined {\n const chain = getChainByName(chainName);\n return chain?.networkType;\n}\n\n/**\n * Format transaction URL for block explorer\n */\nexport function getExplorerTxUrl(chainName: string, txHash: string): string | null {\n const chain = getChainByName(chainName);\n if (!chain) return null;\n\n switch (chain.networkType) {\n case 'evm':\n return `${chain.explorerUrl}/tx/${txHash}`;\n case 'svm':\n case 'solana': // @deprecated\n return `${chain.explorerUrl}/tx/${txHash}`;\n case 'stellar':\n return `${chain.explorerUrl}/tx/${txHash}`;\n case 'near':\n return `${chain.explorerUrl}/txns/${txHash}`;\n case 'algorand':\n return `${chain.explorerUrl}/tx/${txHash}`;\n case 'sui':\n return `${chain.explorerUrl}/tx/${txHash}`;\n case 'hedera':\n return `${chain.explorerUrl}/transaction/${txHash.replace(/^(0\\.0\\.\\d+)@(\\d+)\\.(\\d+)$/, '$1-$2-$3')}`;\n case 'xrpl':\n return `${chain.explorerUrl}/transactions/${txHash}`;\n default:\n return null;\n }\n}\n\n/**\n * Format address URL for block explorer\n */\nexport function getExplorerAddressUrl(chainName: string, address: string): string | null {\n const chain = getChainByName(chainName);\n if (!chain) return null;\n\n switch (chain.networkType) {\n case 'evm':\n return `${chain.explorerUrl}/address/${address}`;\n case 'svm':\n case 'solana': // @deprecated\n return `${chain.explorerUrl}/account/${address}`;\n case 'stellar':\n return `${chain.explorerUrl}/account/${address}`;\n case 'near':\n return `${chain.explorerUrl}/address/${address}`;\n case 'algorand':\n return `${chain.explorerUrl}/account/${address}`;\n case 'sui':\n return `${chain.explorerUrl}/account/${address}`;\n case 'hedera':\n return `${chain.explorerUrl}/account/${address}`;\n case 'xrpl':\n return `${chain.explorerUrl}/accounts/${address}`;\n default:\n return null;\n }\n}\n\n/**\n * Get list of Algorand chains\n */\nexport function getAlgorandChains(): ChainConfig[] {\n return Object.values(SUPPORTED_CHAINS).filter(\n chain => chain.networkType === 'algorand' && chain.x402.enabled\n );\n}\n\n/**\n * Check if a chain is Algorand-based\n */\nexport function isAlgorandChain(chainName: string): boolean {\n const chain = getChainByName(chainName);\n return chain?.networkType === 'algorand';\n}\n\n/**\n * Get list of XRPL chains (XRP Ledger mainnet/testnet)\n */\nexport function getXRPLChains(): ChainConfig[] {\n return Object.values(SUPPORTED_CHAINS).filter(\n chain => chain.networkType === 'xrpl' && chain.x402.enabled\n );\n}\n\n/**\n * Check if a chain is XRPL-based (XRP Ledger)\n */\nexport function isXRPLChain(chainName: string): boolean {\n const chain = getChainByName(chainName);\n return chain?.networkType === 'xrpl';\n}\n\n// ============================================================================\n// MULTI-TOKEN SUPPORT FUNCTIONS\n// ============================================================================\n\n/**\n * Get token configuration for a specific chain and token type\n * Falls back to USDC config if token not found (for backward compatibility)\n *\n * @param chainName - Chain name (e.g., 'ethereum', 'base')\n * @param tokenType - Token type (e.g., 'usdc', 'eurc', 'pyusd')\n * @returns Token configuration or undefined if chain not found\n */\nexport function getTokenConfig(\n chainName: string,\n tokenType: TokenType = 'usdc'\n): TokenConfig | undefined {\n const chain = getChainByName(chainName);\n if (!chain) return undefined;\n\n // Try to get from tokens map first (new multi-token support)\n if (chain.tokens && chain.tokens[tokenType]) {\n return chain.tokens[tokenType];\n }\n\n // Fall back to usdc config for backward compatibility\n if (tokenType === 'usdc') {\n return chain.usdc;\n }\n\n return undefined;\n}\n\n/**\n * Whether a price written in dollars can be scaled into this token's base\n * units. Absent `usdPegged` means yes, so every stablecoin keeps its behaviour.\n *\n * @param token - Token configuration, or undefined\n * @returns True when one whole unit of the token is one dollar\n */\nexport function isUsdPegged(token: TokenConfig | undefined): boolean {\n return token?.usdPegged !== false;\n}\n\n/**\n * The sentence for refusing to price a network in dollars.\n *\n * Refusing without saying where to look only moves the dead end one layer up,\n * so this names the asset, states what the old code would have charged, and\n * points at the one place that lists the alternatives. Same shape as the Python\n * SDK's `NetworkConfig.usd_conversion_error()` (`networks/base.py:158`, 0.77.0)\n * so a team hitting this in either language reads the same explanation.\n *\n * @param chainName - Chain the price was written for\n * @param token - The settlement token that carries no dollar peg\n * @returns Message naming the asset and the way out\n */\nexport function usdConversionError(chainName: string, token: TokenConfig): string {\n const symbol = token.name || token.address;\n return (\n `${chainName} settles in ${symbol}, which is not pegged to the dollar, so an ` +\n `amount written in USD cannot be converted with its ${token.decimals} decimals: ` +\n `$1.00 would be charged as 1 ${symbol}. Name a dollar-pegged token this ` +\n `network's facilitator settles (GET /supported lists them; on XRPL that is the ` +\n `Circle USDC issued by rGm7WCVp9gb4jZHWTEtGUr4dd74z2XuWhE) and register it under ` +\n `the chain's \\`tokens\\`, or price the call in ${symbol} units yourself.`\n );\n}\n\n/**\n * Find which token of a chain a contract address belongs to.\n *\n * The signed payload carries the token *address*, but a server that accepts\n * several stablecoins on the same chain needs the symbol, the decimals and the\n * EIP-712 domain to rebuild the payment requirements. This resolves the address\n * back to the registry entry so that metadata can travel with the payment.\n *\n * @param chainName - Chain name (e.g., 'optimism')\n * @param address - Token contract address (case-insensitive on EVM)\n * @returns The token type and its config, or undefined if the address is not in the registry\n */\nexport function getTokenByAddress(\n chainName: string,\n address: string\n): { tokenType: TokenType; config: TokenConfig } | undefined {\n const chain = getChainByName(chainName);\n if (!chain || !address) return undefined;\n\n const wanted = address.startsWith('0x') ? address.toLowerCase() : address;\n const matches = (candidate: string): boolean =>\n (candidate.startsWith('0x') ? candidate.toLowerCase() : candidate) === wanted;\n\n if (chain.tokens) {\n for (const [tokenType, config] of Object.entries(chain.tokens)) {\n if (config && matches(config.address)) {\n return { tokenType: tokenType as TokenType, config };\n }\n }\n }\n\n if (chain.usdc && matches(chain.usdc.address)) {\n return { tokenType: 'usdc', config: chain.usdc };\n }\n\n return undefined;\n}\n\n/**\n * Get list of supported tokens for a chain\n *\n * @param chainName - Chain name (e.g., 'ethereum', 'base')\n * @returns Array of supported token types, or empty array if chain not found\n */\nexport function getSupportedTokens(chainName: string): TokenType[] {\n const chain = getChainByName(chainName);\n if (!chain) return [];\n\n // If tokens map exists, return its keys\n if (chain.tokens) {\n return Object.keys(chain.tokens) as TokenType[];\n }\n\n // Default to just USDC for chains without explicit tokens map\n return ['usdc'];\n}\n\n/**\n * Check if a token is supported on a specific chain\n *\n * @param chainName - Chain name (e.g., 'ethereum', 'base')\n * @param tokenType - Token type (e.g., 'usdc', 'eurc', 'pyusd')\n * @returns true if token is supported on the chain\n */\nexport function isTokenSupported(chainName: string, tokenType: TokenType): boolean {\n const chain = getChainByName(chainName);\n if (!chain) return false;\n\n // Check tokens map\n if (chain.tokens && chain.tokens[tokenType]) {\n return true;\n }\n\n // USDC is always supported (backward compatibility)\n if (tokenType === 'usdc') {\n return true;\n }\n\n return false;\n}\n\n/**\n * Get all chains that support a specific token\n *\n * @param tokenType - Token type (e.g., 'usdc', 'eurc', 'pyusd')\n * @returns Array of chain configs that support the token\n */\nexport function getChainsByToken(tokenType: TokenType): ChainConfig[] {\n return Object.values(SUPPORTED_CHAINS).filter(chain => {\n if (!chain.x402.enabled) return false;\n if (chain.tokens && chain.tokens[tokenType]) return true;\n if (tokenType === 'usdc') return true; // USDC is universal\n return false;\n });\n}\n","/**\n * uvd-x402-sdk - Type Definitions\n *\n * Core TypeScript interfaces for the x402 payment SDK.\n * These types define the contract between the SDK and consuming applications.\n */\n\n// Type-only, so it is erased at compile time and no runtime cycle exists between\n// this module and `policy.ts` (which imports `X402Error` from here as a value).\nimport type { AdvertisedQuote, PolicyApproval, PurchasePolicy } from '../policy';\n\n// ============================================================================\n// CHAIN CONFIGURATION TYPES\n// ============================================================================\n\n/**\n * Network type categorization\n * - 'evm': Ethereum Virtual Machine compatible chains (use EIP-712)\n * - 'svm': Solana Virtual Machine chains (Solana, Fogo) (use SPL tokens)\n * - 'stellar': Stellar network (use Soroban)\n * - 'near': NEAR Protocol (use NEP-366)\n * - 'algorand': Algorand network (use ASA transfers with atomic transactions)\n * - 'sui': Sui blockchain (use sponsored transactions)\n * - 'xrpl': XRP Ledger (use pre-signed Payment transaction blobs)\n *\n * @deprecated 'solana' type is deprecated, use 'svm' instead\n */\nexport type NetworkType = 'evm' | 'svm' | 'solana' | 'stellar' | 'near' | 'algorand' | 'sui' | 'xrpl' | 'hedera';\n\n/**\n * Supported x402 payment schemes\n * - 'exact': Standard one-shot payment (default)\n * - 'escrow': Escrow-based payment with verify/settle/refund\n * - 'commerce': Commerce alias for escrow (marketplace integrations)\n */\nexport type X402Scheme = 'exact' | 'escrow' | 'commerce';\n\n/**\n * Supported stablecoin token types\n * - usdc: USD Coin (Circle) - 6 decimals\n * - eurc: Euro Coin (Circle) - 6 decimals\n * - ausd: Agora USD (Agora Finance) - 6 decimals\n * - pyusd: PayPal USD (PayPal/Paxos) - 6 decimals\n * - usdt: Tether USD (USDT0 omnichain via LayerZero) - 6 decimals\n * - usdg: Global Dollar (Paxos) - 6 decimals; settlement stablecoin on Robinhood Chain\n */\nexport type TokenType = 'usdc' | 'eurc' | 'ausd' | 'pyusd' | 'usdt' | 'usdg' | 'hbar';\n\n/**\n * Token configuration for EIP-712 signing and transfers\n */\nexport interface TokenConfig {\n /** Contract/mint address */\n address: string;\n /** Token decimals (6 for all supported stablecoins) */\n decimals: number;\n /** Token name for EIP-712 domain (e.g., \"USD Coin\" or \"USDC\") */\n name: string;\n /** Token version for EIP-712 domain */\n version: string;\n /**\n * Whether one whole unit of this token IS one dollar.\n *\n * Absent means yes, so every stablecoin entry in the registry keeps the\n * behaviour it had. It is `false` for EURC (euros), native XRP and HBAR.\n *\n * **The distinction is unit, not scale.** `decimals` already handles scale --\n * BSC USDC has 18 of them and prices correctly. But scaling a price by the\n * decimals only turns dollars into base units when one whole unit is one\n * dollar. XRP has six real decimals and is still not a dollar, so\n * `$1.00 -> 10**6` charges **1 XRP**, which is whatever XRP happens to cost.\n * Six decimals of XRP are still XRP.\n *\n * The SDK refuses to price in USD against a token carrying `false` rather\n * than converting at a rate nobody agreed to. Mirrors `NetworkConfig\n * .usd_pegged` in the Python SDK (`networks/base.py:129`, 0.77.0).\n */\n usdPegged?: boolean;\n}\n\n/**\n * USDC token configuration for a specific chain\n * @deprecated Use TokenConfig instead. This is kept for backward compatibility.\n */\nexport interface USDCConfig {\n /** Contract/mint address */\n address: string;\n /** Token decimals (6 for most chains, 7 for Stellar) */\n decimals: number;\n /** Token name for EIP-712 domain (e.g., \"USD Coin\" or \"USDC\") */\n name: string;\n /** Token version for EIP-712 domain */\n version: string;\n /**\n * Whether one whole unit of this token IS one dollar. Absent means yes.\n *\n * See {@link TokenConfig.usdPegged}. It matters here because this field is\n * also where a chain that settles in its own native asset describes that\n * asset -- XRPL keeps native XRP under the key `usdc`, so the key promises a\n * dollar the value does not deliver.\n */\n usdPegged?: boolean;\n}\n\n/**\n * Native currency configuration\n */\nexport interface NativeCurrency {\n name: string;\n symbol: string;\n decimals: number;\n}\n\n/**\n * Complete chain configuration\n */\nexport interface ChainConfig {\n /** Numeric chain ID (0 for non-EVM chains) */\n chainId: number;\n /** Hex-encoded chain ID for wallet_switchEthereumChain */\n chainIdHex: string;\n /** Internal chain identifier (e.g., 'base', 'solana') */\n name: string;\n /** Human-readable display name */\n displayName: string;\n /** Network type for routing */\n networkType: NetworkType;\n /** Primary RPC endpoint URL */\n rpcUrl: string;\n /** Block explorer base URL */\n explorerUrl: string;\n /** Native currency info */\n nativeCurrency: NativeCurrency;\n /** USDC token configuration */\n usdc: USDCConfig;\n /**\n * Multi-token configurations (EVM chains only)\n * Maps token type to its configuration for this chain.\n * Not all tokens are available on all chains.\n */\n tokens?: Partial<Record<TokenType, TokenConfig>>;\n /** x402 facilitator configuration */\n x402: {\n facilitatorUrl: string;\n enabled: boolean;\n };\n}\n\n// ============================================================================\n// WALLET TYPES\n// ============================================================================\n\n/**\n * Current wallet connection state\n */\nexport interface WalletState {\n /** Whether a wallet is currently connected */\n connected: boolean;\n /** Connected wallet address (null if not connected) */\n address: string | null;\n /** Current chain ID (null for non-EVM or disconnected) */\n chainId: number | null;\n /** Current network name */\n network: string | null;\n /** Network type of connected wallet */\n networkType: NetworkType | null;\n /** USDC balance on current chain (null if unknown) */\n balance: string | null;\n}\n\n/**\n * Wallet adapter interface for different wallet types\n */\nexport interface WalletAdapter {\n /** Unique identifier for this wallet type */\n readonly id: string;\n /** Display name */\n readonly name: string;\n /** Network type this adapter supports */\n readonly networkType: NetworkType;\n\n /** Check if this wallet is available/installed */\n isAvailable(): boolean;\n\n /** Connect to the wallet */\n connect(chainName?: string): Promise<string>;\n\n /** Disconnect from the wallet */\n disconnect(): Promise<void>;\n\n /** Switch to a different chain (EVM only) */\n switchChain?(chainName: string): Promise<void>;\n\n /**\n * Sign a payment payload\n * For EVM chains, supports multi-token via paymentInfo.tokenType\n */\n signPayment(paymentInfo: PaymentInfo, chainConfig: ChainConfig): Promise<string>;\n\n /**\n * Check token balance (defaults to USDC for backward compatibility)\n * EVM providers may accept optional tokenType parameter\n */\n getBalance(chainConfig: ChainConfig, tokenType?: TokenType): Promise<string>;\n\n /** Get current address */\n getAddress(): string | null;\n\n /** Get current chain ID (EVM only) */\n getChainId?(): number | null;\n}\n\n/**\n * EIP-712 domain for typed data signing\n */\nexport interface EIP712Domain {\n name: string;\n version: string;\n chainId: number;\n verifyingContract: string;\n}\n\n/**\n * EIP-712 type definitions\n */\nexport interface EIP712Types {\n [typeName: string]: Array<{ name: string; type: string }>;\n}\n\n// ============================================================================\n// PAYMENT TYPES\n// ============================================================================\n\n/**\n * Payment information returned by backend on 402 response\n */\nexport interface PaymentInfo {\n /** Exact v2 offer/resource, required by native Hedera. */\n accepted?: Record<string, unknown>;\n resource?: { url: string; description?: string; mimeType?: string };\n extensions?: Record<string, unknown>;\n /** Default recipient address */\n recipient: string;\n /** Network-specific recipient addresses */\n recipients?: {\n evm?: string;\n solana?: string;\n near?: string;\n stellar?: string;\n algorand?: string;\n sui?: string;\n xrpl?: string;\n hedera?: string;\n };\n /** Facilitator address (for Solana fee payer) */\n facilitator?: string;\n /**\n * Amount in whole units of the settlement asset (e.g., \"10.00\").\n *\n * For dollar-pegged tokens that is dollars; for EURC it is **euros**.\n * On XRPL it is **XRP**, because XRPL settles in its own native asset:\n * the provider spends this through `xrpToDrops` and bills whole XRP\n * (`src/providers/xrpl/index.ts`). This used to be documented as USD, which\n * made the type and its only XRPL consumer disagree about the unit -- and the\n * consumer won, so a \"10.00\" written as ten dollars left as ten XRP. The SDK\n * now refuses to build a dollar price for an asset with no dollar peg rather\n * than let the two readings meet on the wire; see\n * {@link TokenConfig.usdPegged}.\n */\n amount: string;\n /** Token symbol (usually \"USDC\") */\n token?: string;\n /**\n * Token type for multi-token support\n * Defaults to 'usdc' if not specified for backward compatibility\n */\n tokenType?: TokenType;\n /** Network hint from backend */\n network?: string;\n /** Supported chain IDs */\n supportedChains?: number[];\n /**\n * Envelope version the resource asked for, as read off its own 402.\n *\n * This is what makes the client's `x402Version: 'auto'` mean something: the\n * buyer loop reads the version out of the challenge and hands it down here,\n * so the header is built in the shape the server said it accepts. Left\n * undefined by callers who build a payment by hand -- then the client config\n * decides, exactly as before.\n */\n x402Version?: X402Version;\n /**\n * Seconds this EIP-3009 authorization stays settleable\n * (`validBefore = now + validitySeconds`).\n *\n * Set it when the seller settles **async** -- verify, hand over the resource,\n * settle afterwards -- and needs the authorization alive for longer than the\n * default. Left undefined, `X402ClientConfig.validitySeconds` decides, and\n * failing that `DEFAULT_VALIDITY_SECONDS` (300 s, the timeout this SDK's own\n * seller side announces by default). `X402Client.fetch()` fills it from the\n * seller's `maxTimeoutSeconds` when the 402 declares one.\n *\n * Must be a whole number of seconds between 1 and `MAX_VALIDITY_SECONDS`\n * (3600); anything else is refused with `INVALID_CONFIG` before anything is\n * signed. The ceiling is here because this type is shaped like a parsed 402:\n * a caller that hands a seller's response straight to `createPayment` would\n * otherwise let the SELLER decide how long the payer's authorization stays\n * claimable. The facilitator also keeps a 6 s clock-skew grace, so the payer\n * really has `validitySeconds - 6` to sign.\n */\n validitySeconds?: number;\n}\n\n/**\n * One payment option read off a resource's `402`, normalised.\n *\n * The 402 body speaks two dialects -- v1 spells the price `maxAmountRequired`\n * and names the chain `base`, v2 spells it `amount` and names it `eip155:8453`\n * -- and a buyer that only learned one of them silently ignores half the\n * offers. This is the shape after both have been read.\n */\nexport interface X402PaymentOffer {\n /** Network exactly as the 402 wrote it (plain name or CAIP-2). */\n network: string;\n /** SDK chain name the network resolved to, or null when unknown. */\n chainName: string | null;\n /** Token contract address the resource wants paid, when it named one. */\n asset?: string;\n /** Price in the token's own atomic units. */\n amount: string;\n /** Decimals used to read `amount`. */\n decimals: number;\n /** Recipient of the payment. */\n payTo: string;\n /**\n * The seller's `maxTimeoutSeconds`, when its 402 entry declared a finite number.\n *\n * `X402Client.fetch()` signs this window -- clamped to `1..MAX_VALIDITY_SECONDS`\n * -- instead of the client's own, because the seller is the one party that\n * knows how long its settlement takes. Undefined when the entry declared none,\n * or declared something that is not a number.\n */\n maxTimeoutSeconds?: number;\n /** The accept object verbatim -- echoed back for v2. */\n raw: Record<string, unknown>;\n}\n\n/**\n * Options for {@link X402Client.fetch} -- the buyer loop.\n */\nexport interface X402FetchOptions {\n /** HTTP method for both the probe and the paid retry (default `GET`). */\n method?: string;\n /**\n * Hard ceiling in token units (e.g. `'0.05'`). A 402 that asks for more\n * throws instead of signing. Undefined = no ceiling, which means paying\n * whatever an untrusted resource asks: discouraged.\n */\n maxAmount?: string;\n /** Token to pay with (default `usdc`). */\n tokenType?: TokenType;\n /** Override the default cheapest-offer selection. */\n select?: (offers: X402PaymentOffer[]) => X402PaymentOffer | null | undefined;\n /** Passed through to both requests (`headers`, `body`, `signal`, ...). */\n init?: RequestInit;\n /** Injectable `fetch` (tests, or a runtime without a global one). */\n fetchImpl?: typeof globalThis.fetch;\n /**\n * What a catalog listing advertised, when the caller read one.\n *\n * The comparison NEVER decides anything -- a seller repricing inside a policy\n * the operator already authorised is ordinary commerce -- but handing it over\n * gets the divergence reported on the approval instead of having to diff the\n * two by hand. See `PolicyApproval.versusQuote`.\n */\n advertised?: AdvertisedQuote;\n /**\n * Called once the paid retry came back with something other than a 402, i.e.\n * the seller accepted the payment.\n *\n * This is where a caller calls `client.policy.recordSpend(...)`. Evaluating\n * deliberately does not spend: signing can fail and a settlement can be\n * refused, and a cumulative limit that counted attempts would lock a caller\n * out of money it never spent. Nothing here is automatic, so a caller that\n * wants a cumulative limit to mean something has to say so.\n */\n onPaid?: (approval: PolicyApproval) => void;\n}\n\n/**\n * Simple payment request from application\n */\nexport interface PaymentRequest {\n /** Amount in USDC (e.g., \"10.00\") */\n amount: string;\n /** Override recipient address (optional) */\n recipient?: string;\n /** Application-specific metadata */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * x402 payment header names\n *\n * - 'X-PAYMENT': v1 header name (default, most compatible)\n * - 'PAYMENT-SIGNATURE': v2 header name (newer standard)\n *\n * Both headers use the same base64-encoded JSON payload format.\n * The facilitator accepts both headers.\n */\nexport type X402HeaderName = 'X-PAYMENT' | 'PAYMENT-SIGNATURE';\n\n/**\n * Payment headers object containing both v1 and v2 header formats\n */\nexport interface PaymentHeaders {\n /** v1 header: X-PAYMENT */\n 'X-PAYMENT': string;\n /** v2 header: PAYMENT-SIGNATURE (same value, different header name) */\n 'PAYMENT-SIGNATURE': string;\n}\n\n/**\n * Result of a payment operation\n */\nexport interface PaymentResult {\n /** Whether payment was successful */\n success: boolean;\n /** Base64-encoded X-PAYMENT header value */\n paymentHeader: string;\n /**\n * Payment headers object for easy use with fetch/axios\n *\n * @example\n * ```ts\n * // Use v1 header\n * fetch(url, { headers: { 'X-PAYMENT': result.headers['X-PAYMENT'] } });\n *\n * // Use v2 header\n * fetch(url, { headers: { 'PAYMENT-SIGNATURE': result.headers['PAYMENT-SIGNATURE'] } });\n * ```\n */\n headers: PaymentHeaders;\n /** Transaction hash (if available) */\n transactionHash?: string;\n /** Network where payment was made */\n network: string;\n /** Payer address */\n payer?: string;\n /** Error message (if success is false) */\n error?: string;\n}\n\n// ============================================================================\n// PAYLOAD TYPES (Internal)\n// ============================================================================\n\n/**\n * EVM payment payload (ERC-3009 TransferWithAuthorization)\n */\nexport interface EVMPaymentPayload {\n from: string;\n to: string;\n value: string;\n validAfter: number;\n validBefore: number;\n nonce: string;\n v: number;\n r: string;\n s: string;\n chainId: number;\n token: string;\n}\n\n/**\n * Token info for non-USDC stablecoins (e.g., Token2022 like AUSD)\n * Required in payload for facilitator to verify Token2022 transfers correctly.\n */\nexport interface TokenInfo {\n /** Token mint address */\n address: string;\n /** Token symbol (e.g., 'AUSD') */\n symbol: string;\n /** Token decimals (e.g., 6) */\n decimals: number;\n}\n\n/**\n * Solana payment payload (partially-signed transaction)\n */\nexport interface SolanaPaymentPayload {\n /** Base64-encoded serialized transaction */\n transaction: string;\n /**\n * Token info for non-USDC tokens (e.g., Token2022 like AUSD)\n * CRITICAL: Must be included for Token2022 tokens for facilitator verification\n */\n token?: TokenInfo;\n}\n\n/**\n * Stellar payment payload (Soroban authorization)\n */\nexport interface StellarPaymentPayload {\n /** Sender G... public key */\n from: string;\n /** Recipient G... public key */\n to: string;\n /** Amount in stroops (7 decimals) */\n amount: string;\n /** USDC SAC contract address */\n tokenContract: string;\n /** Base64 XDR-encoded SorobanAuthorizationEntry */\n authorizationEntryXdr: string;\n /** Random 64-bit nonce */\n nonce: number;\n /** Ledger when authorization expires */\n signatureExpirationLedger: number;\n}\n\n/**\n * NEAR payment payload (NEP-366 meta-transaction)\n */\nexport interface NEARPaymentPayload {\n /** Base64 Borsh-encoded SignedDelegateAction */\n signedDelegateAction: string;\n network: 'near';\n}\n\n/**\n * Algorand payment payload (atomic transaction group)\n *\n * Follows the GoPlausible x402-avm spec for atomic groups:\n * - Transaction 0: Fee payment (UNSIGNED) - facilitator -> facilitator, covers all fees\n * - Transaction 1: ASA transfer (SIGNED) - client -> merchant\n *\n * The facilitator signs transaction 0 and submits the complete atomic group.\n */\nexport interface AlgorandPaymentPayload {\n /** Index of the payment transaction in the group (always 1) */\n paymentIndex: number;\n /**\n * Array of base64-encoded msgpack transactions forming the atomic group:\n * - [0]: Unsigned fee transaction (facilitator signs)\n * - [1]: Signed ASA transfer (client signed)\n */\n paymentGroup: string[];\n}\n\n/**\n * Sui payment payload (sponsored transaction)\n *\n * Uses Sui sponsored transactions where:\n * - User creates a programmable transaction for USDC transfer\n * - User signs the transaction\n * - Facilitator sponsors (pays gas in SUI) and submits\n *\n * User pays: ZERO SUI\n */\nexport interface SuiPaymentPayload {\n /** Base64-encoded BCS serialized TransactionData */\n transactionBytes: string;\n /** Base64-encoded user signature */\n senderSignature: string;\n /** Sender address (0x + 64 hex chars) */\n from: string;\n /** Recipient address (0x + 64 hex chars) */\n to: string;\n /** Amount in base units (string to handle large numbers) */\n amount: string;\n /** Coin object ID used for the transfer (REQUIRED by facilitator) */\n coinObjectId: string;\n}\n\n/**\n * XRPL payment payload (pre-signed Payment transaction blob)\n *\n * Uses the t54 \"pre-signed Payment blob\" scheme on the XRP Ledger:\n * - The client builds and FULLY signs a Payment transaction off-chain,\n * paying its own XRP network fee.\n * - The single `signedTxBlob` field (hex-encoded fully-signed XRPL tx blob)\n * is sent to the facilitator, which decodes it to re-derive payer/amount/\n * destination and submits it.\n *\n * All payment-level fields (destination, amount, InvoiceID, SourceTag, etc.)\n * come from PaymentRequirements/extra, NOT from this payload.\n *\n * XRP is the native asset (6 decimals / drops). There is no token contract.\n *\n * The JSON field name is EXACTLY `signedTxBlob` (camelCase).\n */\nexport interface XRPLPaymentPayload {\n /** Hex-encoded fully-signed XRPL Payment transaction blob (tx_blob) */\n signedTxBlob: string;\n}\n\n/**\n * Union type for all payment payloads\n */\nexport type PaymentPayload =\n | EVMPaymentPayload\n | SolanaPaymentPayload\n | StellarPaymentPayload\n | NEARPaymentPayload\n | AlgorandPaymentPayload\n | SuiPaymentPayload\n | XRPLPaymentPayload;\n\n// ============================================================================\n// X402 HEADER TYPES (v1 and v2)\n// ============================================================================\n\n/**\n * x402 protocol version\n */\nexport type X402Version = 1 | 2;\n\n/**\n * CAIP-2 chain identifiers for x402 v2\n * @see https://github.com/ChainAgnostic/CAIPs/blob/master/CAIPs/caip-2.md\n */\nexport const CAIP2_IDENTIFIERS: Record<string, string> = {\n 'hedera:mainnet': 'hedera:mainnet',\n 'hedera:testnet': 'hedera:testnet',\n // EVM chains\n base: 'eip155:8453',\n ethereum: 'eip155:1',\n polygon: 'eip155:137',\n arbitrum: 'eip155:42161',\n optimism: 'eip155:10',\n avalanche: 'eip155:43114',\n celo: 'eip155:42220',\n hyperevm: 'eip155:999',\n unichain: 'eip155:130',\n monad: 'eip155:143',\n bsc: 'eip155:56',\n scroll: 'eip155:534352',\n 'skale-base': 'eip155:1187947933',\n 'skale-base-sepolia': 'eip155:324705682',\n robinhood: 'eip155:4663',\n 'robinhood-testnet': 'eip155:46630',\n arc: 'eip155:5042',\n 'arc-testnet': 'eip155:5042002',\n // SVM chains\n solana: 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp',\n fogo: 'svm:fogo',\n // Stellar\n stellar: 'stellar:pubnet',\n // NEAR\n near: 'near:mainnet',\n // Algorand\n algorand: 'algorand:mainnet',\n 'algorand-testnet': 'algorand:testnet',\n // Sui\n sui: 'sui:mainnet',\n 'sui-testnet': 'sui:testnet',\n // XRPL (XRP Ledger)\n xrpl: 'xrpl',\n 'xrpl-testnet': 'xrpl-testnet',\n};\n\n/**\n * Reverse mapping from CAIP-2 to chain name\n */\nexport const CAIP2_TO_CHAIN: Record<string, string> = Object.fromEntries(\n Object.entries(CAIP2_IDENTIFIERS).map(([k, v]) => [v, k])\n);\n\n/**\n * x402 v1 header structure (network as string)\n */\nexport interface X402HeaderV1 {\n x402Version: 1;\n scheme: X402Scheme;\n network: string;\n payload: X402PayloadData;\n}\n\n/**\n * x402 v2 payment option\n */\nexport interface X402PaymentOption {\n network: string; // CAIP-2 format\n asset: string;\n amount: string;\n facilitator?: string;\n}\n\n/**\n * x402 v2 header structure (CAIP-2 network, accepts array)\n */\nexport interface X402HeaderV2 {\n x402Version: 2;\n scheme: X402Scheme;\n network: string; // CAIP-2 format\n payload: X402PayloadData;\n accepts?: X402PaymentOption[];\n}\n\n/**\n * Union type for both v1 and v2 headers\n */\nexport type X402Header = X402HeaderV1 | X402HeaderV2;\n\n/**\n * EVM-specific payload in x402 header\n */\nexport interface X402EVMPayload {\n signature: string;\n authorization: {\n from: string;\n to: string;\n value: string;\n validAfter: string;\n validBefore: string;\n nonce: string;\n };\n /**\n * Which token was actually paid.\n *\n * Only present when the payment is created with `includeTokenMetadata`. The\n * signature alone does not say which stablecoin it authorizes — a server that\n * accepts several tokens on the same chain cannot rebuild the payment\n * requirements without this. Omitted by default so existing v1 wire formats\n * stay byte-identical.\n */\n token?: PaymentTokenMetadata;\n}\n\n/**\n * Token identification carried inside an x402 payload.\n *\n * Mirrors what a resource server needs to build `paymentRequirements`: the\n * `asset` it must charge and the `extra` EIP-712 domain the facilitator needs\n * to recover the signature.\n */\nexport interface PaymentTokenMetadata {\n /** Token contract address (the `asset` of the payment requirements) */\n address: string;\n /** Uppercase token symbol, e.g. `USDC`, `EURC`, `USDT` */\n symbol: string;\n /** Token decimals — the amount in the authorization is in these units */\n decimals: number;\n /** EIP-712 domain of the token contract (the `extra` of the requirements) */\n eip712: {\n name: string;\n version: string;\n };\n}\n\n/**\n * Solana-specific payload in x402 header\n */\nexport interface X402SolanaPayload {\n transaction: string;\n}\n\n/**\n * Settlement account payload for Crossmint and other custodial wallets\n * that can only sendTransaction (not signTransaction).\n *\n * In this mode, the client already submitted the transaction on-chain.\n * The facilitator verifies the on-chain tx, then sweeps USDC from the\n * settlement account to the payTo address.\n *\n * Used by: Crossmint smart wallets via @faremeter/wallet-crossmint\n */\nexport interface X402SettlementAccountPayload {\n /** On-chain transaction signature (already submitted) */\n transactionSignature: string;\n /** Base58 secret key for sweeping settlement account (optional) */\n settleSecretKey?: string;\n /** Address to receive rent from closed settlement ATA (optional) */\n settlementRentDestination?: string;\n}\n\n/**\n * Stellar-specific payload in x402 header\n */\nexport interface X402StellarPayload {\n from: string;\n to: string;\n amount: string;\n tokenContract: string;\n authorizationEntryXdr: string;\n nonce: number;\n signatureExpirationLedger: number;\n}\n\n/**\n * NEAR-specific payload in x402 header\n */\nexport interface X402NEARPayload {\n signedDelegateAction: string;\n}\n\n/**\n * Algorand-specific payload in x402 header (atomic group format)\n */\nexport interface X402AlgorandPayload {\n /** Index of the payment transaction in the group (always 1) */\n paymentIndex: number;\n /** Array of base64-encoded msgpack transactions */\n paymentGroup: string[];\n}\n\n/**\n * Sui-specific payload in x402 header (sponsored transaction)\n */\nexport interface X402SuiPayload {\n /** BCS-encoded transaction bytes (base64) */\n transactionBytes: string;\n /** User's signature on the transaction (base64) */\n senderSignature: string;\n /** Sender's Sui address (0x...) */\n from: string;\n /** Recipient's Sui address (0x...) */\n to: string;\n /** Amount in smallest unit (string to avoid precision issues) */\n amount: string;\n /** Coin object ID used for the transfer (REQUIRED by facilitator) */\n coinObjectId: string;\n}\n\n/**\n * XRPL-specific payload in x402 header (t54 pre-signed Payment blob)\n *\n * The JSON field name is EXACTLY `signedTxBlob` (camelCase). The facilitator\n * decodes the blob to re-derive payer/amount/destination; no other fields are\n * carried in the payload.\n */\nexport interface X402XRPLPayload {\n /** Hex-encoded fully-signed XRPL Payment transaction blob (tx_blob) */\n signedTxBlob: string;\n}\n\n/**\n * Union of all x402 payload types\n */\nexport type X402PayloadData =\n | X402EVMPayload\n | X402SolanaPayload\n | X402SettlementAccountPayload\n | X402StellarPayload\n | X402NEARPayload\n | X402AlgorandPayload\n | X402SuiPayload\n | X402XRPLPayload;\n\n// ============================================================================\n// CLIENT CONFIGURATION\n// ============================================================================\n\n/**\n * Multi-payment configuration for supporting multiple networks\n */\nexport interface MultiPaymentConfig {\n /** Networks to support (e.g., ['base', 'solana', 'stellar', 'near']) */\n networks: string[];\n /** Default network if user hasn't selected one */\n defaultNetwork?: string;\n /** Whether to auto-detect user's preferred network based on wallet */\n autoDetect?: boolean;\n}\n\n/**\n * SDK client configuration options\n */\nexport interface X402ClientConfig {\n /** Facilitator URL (default: https://facilitator.ultravioletadao.xyz) */\n facilitatorUrl?: string;\n /** Default chain to connect to */\n defaultChain?: string;\n /** Auto-connect on initialization */\n autoConnect?: boolean;\n /** Enable debug logging */\n debug?: boolean;\n /** Custom chain configurations (override defaults) */\n customChains?: Record<string, Partial<ChainConfig>>;\n /** Wallet preference order */\n walletPreference?: string[];\n /** Custom RPC URLs (override defaults) */\n rpcOverrides?: Record<string, string>;\n /**\n * x402 protocol version to use\n * - 1: Classic format with network as string (e.g., \"base\")\n * - 2: CAIP-2 format with accepts array (e.g., \"eip155:8453\")\n * - 'auto': Auto-detect from 402 response (default)\n */\n x402Version?: X402Version | 'auto';\n /** Multi-payment configuration for supporting multiple networks */\n multiPayment?: MultiPaymentConfig;\n /**\n * What this buyer is allowed to sign, decided before it signs.\n *\n * Left undefined, the client holds `PurchasePolicy.permissive()`: this SDK had\n * no budget before 2.89.0 and turning one on silently would refuse payments\n * callers are making today. A policy built with `PurchasePolicy.create()`\n * denies any asset it was not given a ceiling for.\n *\n * @see {@link PurchasePolicy}\n */\n policy?: PurchasePolicy;\n /**\n * Include a `token` block in the payload naming the asset, its decimals and\n * its EIP-712 domain.\n *\n * Needed when the resource accepts more than one stablecoin on the same\n * chain: the signature alone does not say which one was paid, so the server\n * cannot rebuild `paymentRequirements`. Off by default — the emitted header\n * stays byte-identical to previous versions.\n */\n includeTokenMetadata?: boolean;\n /**\n * Seconds every EIP-3009 authorization this client signs stays settleable\n * (`validBefore = now + validitySeconds`).\n *\n * The per-payment {@link PaymentInfo.validitySeconds} overrides it; with\n * neither, `DEFAULT_VALIDITY_SECONDS` (300 s) applies, and `MAX_VALIDITY_SECONDS`\n * (3600 s) is the ceiling for both. Until 2.91.0 this\n * was not configurable at all: the window was 300 s on Base and 60 s on every\n * other EVM network, decided by the payer's SDK, which is exactly the party\n * that does not know how long the seller's settlement takes.\n */\n validitySeconds?: number;\n}\n\n/**\n * Default configuration values\n */\nexport const DEFAULT_CONFIG: Required<Pick<X402ClientConfig, 'facilitatorUrl' | 'defaultChain' | 'autoConnect' | 'debug' | 'x402Version'>> = {\n facilitatorUrl: 'https://facilitator.ultravioletadao.xyz',\n defaultChain: 'base',\n autoConnect: false,\n debug: false,\n x402Version: 'auto',\n};\n\n// ============================================================================\n// BALANCE TYPES\n// ============================================================================\n\n/**\n * Balance information for a single network\n */\nexport interface NetworkBalance {\n /** Chain name */\n chainName: string;\n /** Human-readable display name */\n displayName: string;\n /** Formatted balance (e.g., \"15.50\") or null if loading/error */\n balance: string | null;\n /** Whether balance is currently being fetched */\n isLoading: boolean;\n /** Error message if fetch failed */\n error: string | null;\n}\n\n// ============================================================================\n// EVENT TYPES\n// ============================================================================\n\n/**\n * Events emitted by the SDK client\n */\nexport type X402Event =\n | 'connect'\n | 'disconnect'\n | 'chainChanged'\n | 'accountChanged'\n | 'balanceChanged'\n | 'paymentStarted'\n | 'paymentSigned'\n | 'paymentCompleted'\n | 'paymentFailed';\n\n/**\n * Event data types\n */\nexport interface X402EventData {\n connect: WalletState;\n disconnect: void;\n chainChanged: { chainId: number; chainName: string };\n accountChanged: { address: string };\n balanceChanged: { balance: string };\n paymentStarted: { amount: string; network: string };\n paymentSigned: { paymentHeader: string };\n paymentCompleted: PaymentResult;\n paymentFailed: { error: string; code: X402ErrorCode };\n}\n\n/**\n * Event handler type\n */\nexport type X402EventHandler<E extends X402Event> = (data: X402EventData[E]) => void;\n\n// ============================================================================\n// ERROR TYPES\n// ============================================================================\n\n/**\n * Error codes for categorizing errors\n */\nexport type X402ErrorCode =\n | 'WALLET_NOT_FOUND'\n | 'WALLET_NOT_CONNECTED'\n | 'WALLET_NOT_SUPPORTED'\n | 'WALLET_CONNECTION_FAILED'\n | 'WALLET_CONNECTION_REJECTED'\n | 'WALLET_CONNECTION_TIMEOUT'\n | 'CHAIN_NOT_SUPPORTED'\n | 'CHAIN_SWITCH_REJECTED'\n | 'INSUFFICIENT_BALANCE'\n | 'SIGNATURE_REJECTED'\n | 'PAYMENT_FAILED'\n | 'PAYMENT_TIMEOUT'\n | 'NETWORK_ERROR'\n | 'INVALID_CONFIG'\n | 'INVALID_AMOUNT'\n | 'INVALID_RECIPIENT'\n | 'PAYMENT_EXCEEDS_MAX'\n | 'NO_ACCEPTABLE_PAYMENT'\n /**\n * The buyer's own policy refused the offer before anything was signed. The\n * concrete cause is on `PolicyRefusedError.refusal.code` -- see\n * {@link PurchasePolicy}.\n */\n | 'POLICY_REFUSED'\n | 'UNKNOWN_ERROR';\n\n/**\n * SDK-specific error class\n */\nexport class X402Error extends Error {\n public readonly code: X402ErrorCode;\n public readonly details?: unknown;\n\n constructor(message: string, code: X402ErrorCode, details?: unknown) {\n super(message);\n this.name = 'X402Error';\n this.code = code;\n this.details = details;\n\n // Maintains proper stack trace for where error was thrown (V8 engines)\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, X402Error);\n }\n }\n}\n","/**\n * uvd-x402-sdk - UTF-8 safe base64\n *\n * `btoa()` only accepts code points 0-255. Any character above that throws\n * `InvalidCharacterError`, and the X-PAYMENT payload is not guaranteed to be\n * ASCII: the EIP-712 domain name of USDT on Optimism and Arbitrum is literally\n * `USD₮0` (U+20AE). A header carrying that name crashes a plain `btoa()`.\n *\n * So the JSON is UTF-8 encoded to bytes first, and only then base64'd. Decoding\n * reverses it. For ASCII-only input the output is byte-identical to\n * `btoa(json)`, which is why swapping this in cannot change any existing header.\n *\n * `TextEncoder`/`TextDecoder` are available in every browser the SDK targets and\n * in Node 11+; `btoa`/`atob` are used for the byte<->base64 step because they\n * exist in both environments without pulling in `Buffer`.\n */\n\n/**\n * Encode a string as base64, handling non-ASCII characters correctly.\n *\n * @param value - Any UTF-8 string\n * @returns Base64-encoded value\n */\nexport function encodeBase64Utf8(value: string): string {\n const bytes = new TextEncoder().encode(value);\n let binary = '';\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary);\n}\n\n/**\n * Decode a base64 string produced by {@link encodeBase64Utf8}.\n *\n * @param encoded - Base64-encoded value\n * @returns The original UTF-8 string\n */\nexport function decodeBase64Utf8(encoded: string): string {\n const binary = atob(encoded);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return new TextDecoder().decode(bytes);\n}\n\n/**\n * JSON-serialize a value and encode it as UTF-8 safe base64.\n *\n * This is the encoder for every X-PAYMENT header the SDK emits.\n *\n * @param value - Value to serialize\n * @returns Base64-encoded JSON\n */\nexport function encodeBase64Json(value: unknown): string {\n return encodeBase64Utf8(JSON.stringify(value));\n}\n","/**\n * uvd-x402-sdk - x402 Protocol Utilities\n *\n * Utilities for working with x402 v1 and v2 protocols.\n * Handles version detection, payload encoding, and CAIP-2 conversions.\n */\n\nimport type {\n X402Header,\n X402HeaderV1,\n X402HeaderV2,\n X402PayloadData,\n X402PaymentOption,\n X402Version,\n ChainConfig,\n TokenType,\n} from '../types';\nimport { CAIP2_IDENTIFIERS, CAIP2_TO_CHAIN } from '../types';\nimport { getChainByName, getTokenConfig, isUsdPegged } from '../chains';\nimport { decodeBase64Utf8, encodeBase64Json } from './base64';\n\n/**\n * Detect x402 version from a response header or body\n *\n * @param data - The 402 response data (parsed JSON or header value)\n * @returns The detected version (1 or 2)\n */\nexport function detectX402Version(data: unknown): X402Version {\n if (typeof data === 'string') {\n // A `PAYMENT-REQUIRED` header value is base64 JSON, and the doc above\n // invites one. Returning 1 without decoding misread every v2 challenge as\n // v1 — silently, as a plausible value rather than an error, and the two\n // wire forms are structurally incompatible.\n //\n // This is not hypothetical: measured 2026-08-20, 36 of 36 live Bazaar\n // resources answering 402 carry the challenge in the header, and several\n // put a free content preview in the body, so the header is the only place\n // the version signal exists.\n const trimmed = data.trim();\n if (!trimmed) return 1;\n for (const decode of [\n () => JSON.parse(decodeBase64Utf8(trimmed)),\n () => JSON.parse(trimmed),\n ]) {\n try {\n const parsed = decode();\n if (typeof parsed === 'object' && parsed !== null) {\n return detectX402Version(parsed);\n }\n } catch {\n // not this encoding; try the next\n }\n }\n return 1; // undecodable: fall back to v1, as before\n }\n\n if (typeof data !== 'object' || data === null) {\n return 1; // Default to v1\n }\n\n const obj = data as Record<string, unknown>;\n\n // Check explicit version field\n if (obj.x402Version === 2) {\n return 2;\n }\n\n // Check for v2 indicators\n if (obj.accepts && Array.isArray(obj.accepts)) {\n return 2;\n }\n\n // `paymentRequirements` is the v1 spelling, so its presence points at v1 --\n // but only when there is no v2 signal, which the checks above already ruled\n // out. Recognised so the value is not treated as an unknown shape.\n if (Array.isArray(obj.paymentRequirements)) {\n return 1;\n }\n\n // Check if network is in CAIP-2 format\n if (typeof obj.network === 'string') {\n if (obj.network.includes(':')) {\n return 2;\n }\n }\n\n return 1;\n}\n\n/**\n * Convert chain name to CAIP-2 identifier\n *\n * @param chainName - Chain name (e.g., 'base', 'solana')\n * @returns CAIP-2 identifier (e.g., 'eip155:8453', 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp')\n */\nexport function chainToCAIP2(chainName: string): string {\n // Resolve through the registry FIRST, so an alias answers with the canonical\n // chain's id rather than one built out of the alias. Without this, asking\n // with `xrpl-mainnet` fell past the lookup into the fallback below and\n // manufactured `xrpl:xrpl-mainnet` -- a well-formed CAIP-2 string that no\n // facilitator has ever accepted, and one that PASSES the colon test every v2\n // guard in this SDK uses. A fabricated id is worse than a missing one: the\n // missing one is refused loudly, the fabricated one ships.\n const chain = getChainByName(chainName);\n const caip2 = CAIP2_IDENTIFIERS[(chain?.name ?? chainName).toLowerCase()];\n if (caip2) {\n return caip2;\n }\n\n // Try to construct from chain config\n if (chain) {\n if (chain.networkType === 'evm') {\n return `eip155:${chain.chainId}`;\n }\n // For non-EVM, return the canonical name with the network prefix\n return `${chain.networkType}:${chain.name}`;\n }\n\n return chainName; // Return as-is if unknown\n}\n\n/**\n * Convert CAIP-2 identifier to chain name\n *\n * @param caip2 - CAIP-2 identifier\n * @returns Chain name or null if unknown\n */\nexport function caip2ToChain(caip2: string): string | null {\n // Check direct mapping\n if (CAIP2_TO_CHAIN[caip2]) {\n return CAIP2_TO_CHAIN[caip2];\n }\n\n // Try to extract from EIP-155 format\n const match = caip2.match(/^eip155:(\\d+)$/);\n if (match) {\n const chainId = parseInt(match[1], 10);\n // Find chain by ID\n for (const [name, _config] of Object.entries(CAIP2_IDENTIFIERS)) {\n const chain = getChainByName(name);\n if (chain?.chainId === chainId) {\n return name;\n }\n }\n }\n\n // Try to extract from network:name format\n const parts = caip2.split(':');\n if (parts.length === 2) {\n const networkName = parts[1];\n if (getChainByName(networkName)) {\n return networkName;\n }\n }\n\n return null;\n}\n\n/**\n * Parse network identifier from either v1 or v2 format\n *\n * @param network - Network identifier (v1 string or v2 CAIP-2)\n * @returns Normalized chain name\n */\nexport function parseNetworkIdentifier(network: string): string {\n // If it contains a colon, it's likely CAIP-2\n if (network.includes(':')) {\n return caip2ToChain(network) || network;\n }\n return network.toLowerCase();\n}\n\n/**\n * Encode x402 payload as base64 header value\n *\n * @param header - The x402 header object\n * @returns Base64-encoded string\n */\nexport function encodeX402Header(header: X402Header): string {\n return encodeBase64Json(header);\n}\n\n/**\n * Decode x402 header from base64 string\n *\n * @param encoded - Base64-encoded header value\n * @returns Parsed x402 header\n */\nexport function decodeX402Header(encoded: string): X402Header {\n const json = decodeBase64Utf8(encoded);\n return JSON.parse(json) as X402Header;\n}\n\n/**\n * Create x402 v1 header\n *\n * @param network - Chain name (e.g., 'base')\n * @param payload - Network-specific payload\n * @returns x402 v1 header object\n */\nexport function createX402V1Header(\n network: string,\n payload: X402PayloadData\n): X402HeaderV1 {\n if (getChainByName(network)?.networkType === 'hedera') throw new Error('Native Hedera supports only x402 v2');\n return {\n x402Version: 1,\n scheme: 'exact',\n network,\n payload,\n };\n}\n\n/**\n * Create x402 v2 header\n *\n * @param network - CAIP-2 network identifier\n * @param payload - Network-specific payload\n * @param accepts - Optional array of payment options\n * @returns x402 v2 header object\n */\nexport function createX402V2Header(\n network: string,\n payload: X402PayloadData,\n accepts?: X402PaymentOption[]\n): X402HeaderV2 {\n const header: X402HeaderV2 = {\n x402Version: 2,\n scheme: 'exact',\n network: network.includes(':') ? network : chainToCAIP2(network),\n payload,\n };\n\n if (accepts && accepts.length > 0) {\n header.accepts = accepts;\n }\n\n return header;\n}\n\n/**\n * Create x402 header with automatic version selection\n *\n * @param chainConfig - Chain configuration\n * @param payload - Network-specific payload\n * @param version - Version to use (1, 2, or 'auto')\n * @returns x402 header object\n */\nexport function createX402Header(\n chainConfig: ChainConfig,\n payload: X402PayloadData,\n version: X402Version | 'auto' = 'auto'\n): X402Header {\n // Default to v1 for maximum compatibility\n const effectiveVersion = version === 'auto' ? 1 : version;\n\n if (effectiveVersion === 2) {\n return createX402V2Header(chainConfig.name, payload);\n }\n\n return createX402V1Header(chainConfig.name, payload);\n}\n\n/**\n * Generate payment options array for multi-network support\n *\n * One entry per (chain, token) pair. By default the token is USDC on every\n * chain, which is exactly what this emitted before `tokens` existed.\n *\n * **`tokens` is opt-in on purpose, and the reason is money.** The chain\n * registry knows more stablecoins than USDC (Base also has EURC), and it is\n * tempting to just emit all of them. But this array becomes the `accepts` of a\n * `402`, so every entry is a currency the seller has publicly agreed to be paid\n * in -- at `amount` units of it. Emitting EURC for a seller who priced in\n * dollars would quietly sell at a 1:1 EUR/USD rate nobody agreed to. So the\n * caller names the tokens it actually accepts, and `amount` is read as units of\n * each named token, NOT converted between them.\n *\n * A token a chain does not have is skipped: an option is only emitted for pairs\n * the registry can actually price.\n *\n * @param chainConfigs - Array of chain configurations\n * @param amount - Amount in units of each token (e.g., \"10.00\")\n * @param facilitator - Optional facilitator URL override\n * @param tokens - Tokens to offer per chain (default: `['usdc']`)\n * @returns Array of x402 v2 payment options\n *\n * @example\n * ```ts\n * // Dollars only -- the default, and what every existing caller gets.\n * generatePaymentOptions([base], '5.00');\n *\n * // Dollars or euros, priced separately and both genuinely accepted.\n * generatePaymentOptions([base], '5.00', undefined, ['usdc', 'eurc']);\n * ```\n */\nexport function generatePaymentOptions(\n chainConfigs: ChainConfig[],\n amount: string,\n facilitator?: string,\n tokens: TokenType[] = ['usdc']\n): X402PaymentOption[] {\n const options: X402PaymentOption[] = [];\n\n for (const chain of chainConfigs) {\n if (!chain.x402.enabled) continue;\n\n for (const tokenType of tokens) {\n const token = getTokenConfig(chain.name, tokenType);\n if (!token) continue;\n\n // A token with no dollar peg is skipped for the same reason a missing one\n // is: this array can only carry pairs the registry can actually price.\n // XRPL reaches here because it files native XRP under the key `usdc`, so\n // the loop would otherwise emit \"5 XRP\" for a seller who wrote `'5.00'`\n // and asked for dollars.\n //\n // SKIP, not throw, and that is deliberate. This builds the `accepts` of\n // ONE 402 covering MANY chains -- the usual call is every enabled chain\n // at once -- so throwing would take the whole response down over a single\n // unpriceable pair and cost the seller the chains that were fine.\n // `buildPaymentRequirements` names one chain and therefore throws there.\n // EURC is available only through an explicitly named token: the caller\n // has chosen euros here. The default USDC path still excludes native XRP.\n if (!isUsdPegged(token) && tokenType !== 'eurc') continue;\n\n // Atomic units in THIS token's decimals -- BSC USDC has 18, not 6.\n const atomicAmount = Math.floor(\n parseFloat(amount) * Math.pow(10, token.decimals)\n ).toString();\n\n options.push({\n network: chainToCAIP2(chain.name),\n asset: token.address,\n amount: atomicAmount,\n facilitator: facilitator || chain.x402.facilitatorUrl,\n });\n }\n }\n\n return options;\n}\n\n/**\n * Check if a network string is in CAIP-2 format\n *\n * @param network - Network identifier\n * @returns True if CAIP-2 format\n */\nexport function isCAIP2Format(network: string): boolean {\n return network.includes(':');\n}\n\n/**\n * Convert between x402 v1 and v2 header formats\n *\n * @param header - Source header\n * @param targetVersion - Target version\n * @returns Converted header\n */\nexport function convertX402Header(\n header: X402Header,\n targetVersion: X402Version\n): X402Header {\n if (header.x402Version === targetVersion) {\n return header;\n }\n\n if (targetVersion === 2) {\n // v1 -> v2\n return {\n x402Version: 2,\n scheme: 'exact',\n network: chainToCAIP2(header.network),\n payload: header.payload,\n };\n } else {\n // v2 -> v1\n const chainName = isCAIP2Format(header.network)\n ? caip2ToChain(header.network) || header.network\n : header.network;\n\n return {\n x402Version: 1,\n scheme: 'exact',\n network: chainName,\n payload: header.payload,\n };\n }\n}\n\n/**\n * Read a 402 payment challenge from wherever the seller put it.\n *\n * x402 allows BOTH transports and sellers pick freely:\n *\n * - base64 JSON in the `PAYMENT-REQUIRED` (or `X-PAYMENT-REQUIRED`) header\n * - JSON in the response body\n *\n * Measured against production on 2026-08-20: of 40 live Bazaar resources,\n * **36 of 36 that answered 402 carried the challenge in the header, and none in\n * the body**. Worse, sellers like Tenjin use the 402 body for a free preview of\n * the paid content — so the body is valid JSON that simply has no `accepts`, and\n * a body-only reader parses it happily and finds nothing.\n *\n * Reads the header first because that is where live sellers put it, and falls\n * back to the body so the sellers who use it keep working.\n *\n * Returns `null` when neither transport carries a challenge — a real \"no terms\n * here\", distinct from a challenge we failed to decode.\n */\nexport function paymentChallengeFrom(\n headers: { get(name: string): string | null } | Record<string, string>,\n body?: unknown,\n): Record<string, unknown> | null {\n const read = (name: string): string | null => {\n if (typeof (headers as { get?: unknown }).get === 'function') {\n return (headers as { get(n: string): string | null }).get(name);\n }\n const rec = headers as Record<string, string>;\n return rec[name] ?? rec[name.toLowerCase()] ?? rec[name.toUpperCase()] ?? null;\n };\n\n const raw = read('payment-required') ?? read('x-payment-required');\n if (raw) {\n const trimmed = raw.trim();\n for (const decode of [\n () => JSON.parse(decodeBase64Utf8(trimmed)),\n () => JSON.parse(trimmed),\n ]) {\n try {\n const parsed = decode();\n if (isChallenge(parsed)) return parsed as Record<string, unknown>;\n } catch {\n // not this encoding; try the next\n }\n }\n }\n\n const parsedBody = typeof body === 'string' ? tryJson(body) : body;\n return isChallenge(parsedBody) ? (parsedBody as Record<string, unknown>) : null;\n}\n\n/**\n * Whether a value actually looks like an x402 challenge.\n *\n * Deliberately stricter than \"is an object\": a 402 body carrying a free preview\n * is valid JSON with no payment terms in it, and treating that as a challenge is\n * how a body-only reader concludes it looked and found nothing wrong.\n */\nfunction isChallenge(v: unknown): boolean {\n if (typeof v !== 'object' || v === null) return false;\n const o = v as Record<string, unknown>;\n // `paymentRequirements` is the v1 spelling of `accepts`. Missing it made a\n // seller using it look like \"no terms here\" — the exact false negative this\n // function exists to prevent. Found in the Python SDK by KarmaKadabra's\n // buyer, which matched both keys in production, 2026-08-20.\n return (\n Array.isArray(o.accepts) ||\n Array.isArray(o.paymentRequirements) ||\n typeof o.payTo === 'string'\n );\n}\n\nfunction tryJson(s: string): unknown {\n try {\n return JSON.parse(s);\n } catch {\n return null;\n }\n}\n","/**\n * uvd-x402-sdk - Token metadata for payment payloads\n *\n * An EIP-3009 authorization is signed against a token contract, but the encoded\n * payload only carries the signature and the transfer fields. The token itself\n * is implicit — the server is expected to already know which asset it asked\n * for.\n *\n * That holds when a resource accepts exactly one token per chain. It breaks as\n * soon as it accepts several: a EURC payment and a USDC payment on Base produce\n * indistinguishable payloads, and the server cannot build the\n * `paymentRequirements` (`asset` + `extra`) the facilitator needs to settle.\n *\n * So the payment can opt into carrying the token with it.\n */\n\nimport { getTokenByAddress } from '../chains';\nimport type { PaymentTokenMetadata } from '../types';\n\n/**\n * Build the token metadata block for a payload, resolving the address against\n * the chain registry.\n *\n * @param chainName - Chain the payment was signed for\n * @param address - Token contract address from the signed payload\n * @returns Metadata block, or undefined if the address is not in the registry\n */\nexport function buildTokenMetadata(\n chainName: string,\n address: string\n): PaymentTokenMetadata | undefined {\n const match = getTokenByAddress(chainName, address);\n if (!match) return undefined;\n\n return {\n address: match.config.address,\n symbol: match.tokenType.toUpperCase(),\n decimals: match.config.decimals,\n eip712: {\n name: match.config.name,\n version: match.config.version,\n },\n };\n}\n","/**\n * uvd-x402-sdk - Validation and Payment Header Utilities\n *\n * Functions for validating payment parameters and creating\n * payment headers for HTTP requests.\n */\n\nimport type { X402HeaderName, PaymentHeaders } from '../types';\nimport { X402Error } from '../types';\n\n/**\n * Regular expression for validating Ethereum addresses\n */\nconst ETH_ADDRESS_REGEX = /^0x[a-fA-F0-9]{40}$/;\n\n/**\n * Regular expression for validating Solana addresses (base58, 32-44 chars)\n */\nconst SOLANA_ADDRESS_REGEX = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/;\n\n/**\n * Regular expression for validating Stellar addresses (G... format)\n */\nconst STELLAR_ADDRESS_REGEX = /^G[A-Z2-7]{55}$/;\n\n/**\n * Regular expression for validating NEAR addresses\n */\nconst NEAR_ADDRESS_REGEX = /^[a-z0-9._-]+$/;\n\n/**\n * Regular expression for validating XRPL classic addresses (r... base58, Ripple alphabet)\n */\nconst XRPL_ADDRESS_REGEX = /^r[1-9A-HJ-NP-Za-km-z]{24,34}$/;\n\n/**\n * Validate that a recipient address is present and valid\n *\n * This function ensures that:\n * 1. The recipient is not null, undefined, or empty\n * 2. The recipient is not just whitespace\n * 3. For EVM, it's a valid checksummed or lowercase 0x address\n *\n * @param recipient - The recipient address to validate\n * @param networkType - Optional network type for format validation\n * @throws X402Error with code 'INVALID_RECIPIENT' if validation fails\n */\nexport function validateRecipient(\n recipient: string | undefined | null,\n networkType?: 'evm' | 'svm' | 'solana' | 'stellar' | 'near' | 'xrpl' | 'hedera'\n): asserts recipient is string {\n // Check for null, undefined, or empty\n if (!recipient) {\n throw new X402Error(\n 'Recipient address is required. The payTo/recipient field cannot be empty. ' +\n 'Please provide a valid recipient address where payments should be sent.',\n 'INVALID_RECIPIENT'\n );\n }\n\n // Check for whitespace-only\n const trimmed = recipient.trim();\n if (trimmed === '') {\n throw new X402Error(\n 'Recipient address cannot be empty or whitespace. ' +\n 'Please provide a valid recipient address.',\n 'INVALID_RECIPIENT'\n );\n }\n\n // Network-specific validation\n if (networkType) {\n switch (networkType) {\n case 'evm':\n if (!ETH_ADDRESS_REGEX.test(trimmed)) {\n throw new X402Error(\n `Invalid EVM recipient address: \"${trimmed}\". ` +\n 'Expected a 40-character hexadecimal address starting with 0x.',\n 'INVALID_RECIPIENT'\n );\n }\n break;\n\n case 'svm':\n case 'solana':\n if (!SOLANA_ADDRESS_REGEX.test(trimmed)) {\n throw new X402Error(\n `Invalid Solana recipient address: \"${trimmed}\". ` +\n 'Expected a base58-encoded public key (32-44 characters).',\n 'INVALID_RECIPIENT'\n );\n }\n break;\n\n case 'stellar':\n if (!STELLAR_ADDRESS_REGEX.test(trimmed)) {\n throw new X402Error(\n `Invalid Stellar recipient address: \"${trimmed}\". ` +\n 'Expected a G-prefixed public key (56 characters).',\n 'INVALID_RECIPIENT'\n );\n }\n break;\n\n case 'near':\n if (!NEAR_ADDRESS_REGEX.test(trimmed) || trimmed.length > 64) {\n throw new X402Error(\n `Invalid NEAR recipient address: \"${trimmed}\". ` +\n 'Expected a valid NEAR account ID.',\n 'INVALID_RECIPIENT'\n );\n }\n break;\n\n case 'hedera':\n if (!/^0\\.0\\.[1-9][0-9]*$/.test(trimmed)) {\n throw new X402Error('Hedera recipient must be a native numeric account ID', 'INVALID_RECIPIENT');\n }\n break;\n\n case 'xrpl':\n if (!XRPL_ADDRESS_REGEX.test(trimmed)) {\n throw new X402Error(\n `Invalid XRPL recipient address: \"${trimmed}\". ` +\n 'Expected a classic r-address (base58, Ripple alphabet).',\n 'INVALID_RECIPIENT'\n );\n }\n break;\n }\n }\n}\n\n/**\n * Validate payment amount\n *\n * Ensures the amount is a valid positive number string\n *\n * @param amount - The amount string to validate\n * @throws X402Error with code 'INVALID_AMOUNT' if validation fails\n */\nexport function validateAmount(amount: string | undefined | null): asserts amount is string {\n if (!amount) {\n throw new X402Error(\n 'Payment amount is required.',\n 'INVALID_AMOUNT'\n );\n }\n\n const trimmed = amount.trim();\n if (trimmed === '') {\n throw new X402Error(\n 'Payment amount cannot be empty.',\n 'INVALID_AMOUNT'\n );\n }\n\n // Parse as number\n const num = parseFloat(trimmed);\n if (isNaN(num)) {\n throw new X402Error(\n `Invalid payment amount: \"${trimmed}\". Expected a valid number.`,\n 'INVALID_AMOUNT'\n );\n }\n\n if (num <= 0) {\n throw new X402Error(\n `Payment amount must be positive. Got: ${trimmed}`,\n 'INVALID_AMOUNT'\n );\n }\n}\n\n// ============================================================================\n// PAYMENT HEADER UTILITIES\n// ============================================================================\n\n/**\n * Create payment headers object from a base64-encoded payload\n *\n * Returns an object with both X-PAYMENT and PAYMENT-SIGNATURE headers,\n * making it easy to use either header format.\n *\n * @param paymentHeader - Base64-encoded payment payload\n * @returns PaymentHeaders object with both header formats\n *\n * @example\n * ```ts\n * const headers = createPaymentHeaders(paymentHeader);\n *\n * // Use v1 header (most compatible)\n * fetch(url, { headers: { 'X-PAYMENT': headers['X-PAYMENT'] } });\n *\n * // Use v2 header\n * fetch(url, { headers: { 'PAYMENT-SIGNATURE': headers['PAYMENT-SIGNATURE'] } });\n * ```\n */\nexport function createPaymentHeaders(paymentHeader: string): PaymentHeaders {\n return {\n 'X-PAYMENT': paymentHeader,\n 'PAYMENT-SIGNATURE': paymentHeader,\n };\n}\n\n/**\n * Get a single payment header by name\n *\n * @param paymentHeader - Base64-encoded payment payload\n * @param headerName - Header name to use ('X-PAYMENT' or 'PAYMENT-SIGNATURE')\n * @returns Object with a single header entry\n *\n * @example\n * ```ts\n * // Use with fetch spread operator\n * fetch(url, {\n * headers: {\n * 'Content-Type': 'application/json',\n * ...getPaymentHeader(result.paymentHeader, 'X-PAYMENT'),\n * },\n * });\n * ```\n */\nexport function getPaymentHeader(\n paymentHeader: string,\n headerName: X402HeaderName = 'X-PAYMENT'\n): Record<X402HeaderName, string> {\n return { [headerName]: paymentHeader } as Record<X402HeaderName, string>;\n}\n\n/**\n * Default x402 payment header name\n *\n * Use 'X-PAYMENT' for maximum compatibility with all facilitators.\n * Use 'PAYMENT-SIGNATURE' for x402 v2 compliance.\n */\nexport const DEFAULT_PAYMENT_HEADER: X402HeaderName = 'X-PAYMENT';\n\n/**\n * All supported x402 payment header names\n */\nexport const PAYMENT_HEADER_NAMES: readonly X402HeaderName[] = [\n 'X-PAYMENT',\n 'PAYMENT-SIGNATURE',\n] as const;\n","/**\n * uvd-x402-sdk - EIP-191 personal_sign helpers\n *\n * Generic recover/verify for an EIP-191 `personal_sign` over an arbitrary\n * string message — the shape a wallet produces for `eth_sign`/`personal_sign`\n * and `cast wallet sign <message>`.\n *\n * This is deliberately NOT the ERC-8128 machinery (`verifyRequest`), which\n * verifies an RFC 9421 SIGNED HTTP REQUEST (method;url;headers;content-digest).\n * A challenge/response flow — a service hands out a nonce string, the wallet\n * signs that string, the service recovers the signer — is a different, simpler\n * case that the ERC-8128 path does not cover. Consumers doing wallet-ownership\n * challenges (e.g. MeshRelay's IRC `VERIFY`/`VERIFY-SIG`) needed this and were\n * each reaching for `ethers.verifyMessage` directly; this centralizes it.\n */\n\nimport { ethers } from 'ethers';\n\n/**\n * Recover the address that produced an EIP-191 `personal_sign` over `message`.\n *\n * @param message - the exact string that was signed\n * @param signature - the 0x-prefixed signature\n * @returns the checksummed recovered address\n * @throws if the signature is malformed (propagates ethers' error)\n */\nexport function recoverPersonalSignAddress(message: string, signature: string): string {\n return ethers.verifyMessage(message, signature);\n}\n\n/**\n * Whether `signature` over `message` was produced by `expected`.\n *\n * Compares case-insensitively (recovered addresses are checksummed, linked\n * wallets are often stored lower-cased) and never throws: a malformed\n * signature is a failed verification, not an exception to handle at every\n * call site.\n *\n * @returns true iff the recovered signer equals `expected`\n */\nexport function verifyPersonalSign(params: {\n message: string;\n signature: string;\n expected: string;\n}): boolean {\n const { message, signature, expected } = params;\n if (!expected) return false;\n try {\n const recovered = recoverPersonalSignAddress(message, signature);\n return recovered.toLowerCase() === expected.toLowerCase();\n } catch {\n return false;\n }\n}\n","/**\n * uvd-x402-sdk - EIP-3009 validity window\n *\n * How long a signed authorization stays settleable: `validBefore = now +\n * validitySeconds`. One definition, read by every EVM signing path, because the\n * number used to be written twice — `X402Client.createEVMPayment` and\n * `EVMProvider.signPayment` each carried their own copy of a per-chain ternary:\n * 300 s on Base, 60 s on every other network.\n *\n * Why the per-chain ternary is gone: the window is not a property of the chain,\n * it is how long the SELLER needs to settle, and the seller is the one party\n * that could not set it. A seller that settles async — verify, hand over the\n * resource, settle afterwards — has to land the settlement inside this window\n * or the authorization expires by itself and a paid-for resource gets revoked.\n * That is MeshRelay Turnstile's exact flow. On Base (300 s) nobody ever felt it;\n * on the other eleven EVM networks the buyer had 60 s, minus the facilitator's\n * 6 s clock-skew grace, to open a wallet and sign.\n *\n * Why 300 and not 60 or 3600 — where the number actually comes from:\n * - it is the timeout the seller side of THIS SDK announces by default\n * (`DEFAULT_PAYMENT_TIMEOUT_SECONDS` in `src/backend/index.ts`), so a buyer\n * and a seller both built on `uvd-x402-sdk` agree without configuring\n * anything;\n * - it is what MeshRelay Turnstile, the async seller that surfaced this,\n * announces (`timeoutSeconds: 300` in its `turnstile/payments.js`);\n * - it is the fallback the facilitator's catalog applies to a seller entry\n * that omits the field (`DEFAULT_MAX_TIMEOUT_SECS` in `x402-rs`\n * `src/discovery_price.rs`). That is a catalog default, not a timeout the\n * facilitator enforces or advertises for itself: its `/supported` carries\n * no timeout at all.\n *\n * The facilitator only ever rejects a window for being too SHORT — `assert_time`\n * (`x402-rs`, `src/chain/evm.rs`), which runs in both verify and settle, refuses\n * `valid_before < now + 6 s` — and compares `valid_before` against no ceiling.\n * That is why the ceiling below lives in the payer's SDK, and why signing LESS\n * than a seller declared is the failure that bites.\n *\n * When the seller's 402 declares `maxTimeoutSeconds`, `X402Client.fetch()` signs\n * that window instead of the client's own; see {@link clampValiditySeconds}.\n *\n * The Python SDK's equivalent (`valid_duration`, 3600 s) stays where it is: the\n * two SDKs still differ, but both are configurable now.\n */\n\nimport { X402Error } from '../types';\n\n/**\n * Seconds an EIP-3009 authorization stays valid when nobody says otherwise.\n *\n * Exported so a consumer can READ the effective default instead of re-typing\n * `300` in its own timeout math.\n */\nexport const DEFAULT_VALIDITY_SECONDS = 300;\n\n/**\n * Longest window this SDK will sign, one hour.\n *\n * A ceiling exists because the seller gets a say in the window: `fetch()`\n * honours the `maxTimeoutSeconds` a 402 declares, and {@link PaymentInfo} is\n * shaped like \"what the backend returned on its 402\", so a caller that hands a\n * parsed 402 body straight to `createPayment` lets the seller pick too. Without\n * a limit, a year-long window is a standing claim on the payer's balance: the\n * resource is never delivered, the authorization looks expired to a buyer who\n * assumed minutes, and it settles months later against a funded wallet.\n * Cancelling one costs gas and knowing the nonce.\n *\n * 3600 and not something rounder: it is the largest window anything in this\n * stack signs today — the Python SDK's `valid_duration` default — so nothing\n * that works now is refused by this limit.\n */\nexport const MAX_VALIDITY_SECONDS = 3600;\n\n/**\n * Pick the validity window for one payment, most specific source first.\n *\n * @param perPayment - `PaymentInfo.validitySeconds`, the window for this single\n * payment. Wins over everything.\n * @param clientDefault - `X402ClientConfig.validitySeconds`, the window this\n * client signs with when a payment does not ask for one.\n * @returns The window in whole seconds; {@link DEFAULT_VALIDITY_SECONDS} when\n * neither source named one.\n * @throws {X402Error} `INVALID_CONFIG` when a source named something that is not\n * a positive whole number of seconds, or more than\n * {@link MAX_VALIDITY_SECONDS}. Thrown rather than silently falling back to\n * the default: a caller that asked for a window and got a different one would\n * be signing an authorization it did not choose, and the mistake would only\n * surface as a failed settlement much later.\n */\nexport function resolveValiditySeconds(\n perPayment?: number,\n clientDefault?: number\n): number {\n const chosen = perPayment ?? clientDefault ?? DEFAULT_VALIDITY_SECONDS;\n\n // `Number.isInteger` is false for NaN, Infinity and 1.5 alike, and a\n // fractional window would reach `validBefore` as a fractional unix timestamp\n // that the EIP-712 uint256 encoder rejects anyway — just later, and with a\n // message about the signature rather than about the window.\n if (!Number.isInteger(chosen) || chosen <= 0) {\n throw new X402Error(\n `validitySeconds must be a positive whole number of seconds, got ${String(chosen)}`,\n 'INVALID_CONFIG',\n { validitySeconds: chosen }\n );\n }\n\n if (chosen > MAX_VALIDITY_SECONDS) {\n throw new X402Error(\n `validitySeconds must be at most ${MAX_VALIDITY_SECONDS} seconds, got ${String(chosen)}. ` +\n 'A longer window is a standing claim on the payer: it can be settled long ' +\n 'after the payer gave the payment up for expired.',\n 'INVALID_CONFIG',\n { validitySeconds: chosen, max: MAX_VALIDITY_SECONDS }\n );\n }\n\n return chosen;\n}\n\n/**\n * The window to sign when a seller's 402 declared `maxTimeoutSeconds`.\n *\n * The seller's number wins over the client's configured window: it is the one\n * party that knows how long its settlement takes, and since the facilitator\n * never rejects a window for being long, signing less than it declared only\n * produces an authorization that dies before the seller's own settle.\n *\n * Clamped to `[1, MAX_VALIDITY_SECONDS]` rather than refused, because a 402 is\n * the seller's declaration and not the buyer's config: a seller asking for a\n * day still gets paid, inside the payer's ceiling. A fractional declaration is\n * floored.\n */\nexport function clampValiditySeconds(maxTimeoutSeconds: number): number {\n return Math.min(MAX_VALIDITY_SECONDS, Math.max(1, Math.floor(maxTimeoutSeconds)));\n}\n","/**\n * uvd-x402-sdk - Utilities\n *\n * Re-exports all utility functions.\n */\n\nexport {\n detectX402Version,\n paymentChallengeFrom,\n chainToCAIP2,\n caip2ToChain,\n parseNetworkIdentifier,\n encodeX402Header,\n decodeX402Header,\n createX402V1Header,\n createX402V2Header,\n createX402Header,\n generatePaymentOptions,\n isCAIP2Format,\n convertX402Header,\n} from './x402';\n\nexport { buildTokenMetadata } from './token-metadata';\n\nexport {\n encodeBase64Utf8,\n decodeBase64Utf8,\n encodeBase64Json,\n} from './base64';\n\nexport {\n validateRecipient,\n validateAmount,\n createPaymentHeaders,\n getPaymentHeader,\n DEFAULT_PAYMENT_HEADER,\n PAYMENT_HEADER_NAMES,\n} from './validation';\n\nexport {\n recoverPersonalSignAddress,\n verifyPersonalSign,\n} from './personal-sign';\n\nexport {\n DEFAULT_VALIDITY_SECONDS,\n MAX_VALIDITY_SECONDS,\n resolveValiditySeconds,\n clampValiditySeconds,\n} from './validity';\n","/**\n * uvd-x402-sdk - SVM Provider (Solana Virtual Machine)\n *\n * Provides wallet connection and payment creation for SVM-based chains via Phantom.\n * Supports: Solana, Fogo\n * Uses partially-signed transactions where the facilitator is the fee payer.\n *\n * @example Solana\n * ```ts\n * import { SVMProvider } from 'uvd-x402-sdk/solana';\n * import { getChainByName } from 'uvd-x402-sdk';\n *\n * const svm = new SVMProvider();\n *\n * // Connect\n * const address = await svm.connect();\n *\n * // Create Solana payment\n * const chainConfig = getChainByName('solana')!;\n * const paymentPayload = await svm.signPayment(paymentInfo, chainConfig);\n * const header = svm.encodePaymentHeader(paymentPayload, chainConfig);\n * ```\n *\n * @example Fogo\n * ```ts\n * import { SVMProvider } from 'uvd-x402-sdk/solana';\n * import { getChainByName } from 'uvd-x402-sdk';\n *\n * const svm = new SVMProvider();\n *\n * // Connect (same wallet works for all SVM chains)\n * const address = await svm.connect();\n *\n * // Create Fogo payment\n * const chainConfig = getChainByName('fogo')!;\n * const paymentPayload = await svm.signPayment(paymentInfo, chainConfig);\n * const header = svm.encodePaymentHeader(paymentPayload, chainConfig);\n * ```\n */\n\nimport type {\n ChainConfig,\n PaymentInfo,\n SolanaPaymentPayload,\n TokenInfo,\n WalletAdapter,\n X402Version,\n} from '../../types';\nimport { X402Error } from '../../types';\nimport { getChainByName } from '../../chains';\nimport { chainToCAIP2, encodeBase64Json } from '../../utils';\n\n/**\n * Browser-compatible base64 encoding for Uint8Array\n * Avoids Node.js Buffer dependency for browser bundlers\n */\nfunction uint8ArrayToBase64(bytes: Uint8Array): string {\n let binary = '';\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary);\n}\n\n// Lazy import Solana dependencies to avoid bundling when not used\nlet Connection: typeof import('@solana/web3.js').Connection;\nlet PublicKey: typeof import('@solana/web3.js').PublicKey;\nlet TransactionMessage: typeof import('@solana/web3.js').TransactionMessage;\nlet VersionedTransaction: typeof import('@solana/web3.js').VersionedTransaction;\nlet ComputeBudgetProgram: typeof import('@solana/web3.js').ComputeBudgetProgram;\nlet getAssociatedTokenAddress: typeof import('@solana/spl-token').getAssociatedTokenAddress;\nlet createTransferCheckedInstruction: typeof import('@solana/spl-token').createTransferCheckedInstruction;\nlet createAssociatedTokenAccountIdempotentInstruction: typeof import('@solana/spl-token').createAssociatedTokenAccountIdempotentInstruction;\nlet TOKEN_PROGRAM_ID: typeof import('@solana/spl-token').TOKEN_PROGRAM_ID;\n\nasync function loadSolanaDeps() {\n if (!Connection) {\n const web3 = await import('@solana/web3.js');\n const splToken = await import('@solana/spl-token');\n Connection = web3.Connection;\n PublicKey = web3.PublicKey;\n TransactionMessage = web3.TransactionMessage;\n VersionedTransaction = web3.VersionedTransaction;\n ComputeBudgetProgram = web3.ComputeBudgetProgram;\n getAssociatedTokenAddress = splToken.getAssociatedTokenAddress;\n createTransferCheckedInstruction = splToken.createTransferCheckedInstruction;\n createAssociatedTokenAccountIdempotentInstruction = splToken.createAssociatedTokenAccountIdempotentInstruction;\n TOKEN_PROGRAM_ID = splToken.TOKEN_PROGRAM_ID;\n }\n}\n\n/**\n * Phantom wallet provider interface\n */\ninterface PhantomProvider {\n isPhantom?: boolean;\n isConnected?: boolean;\n publicKey?: { toBase58(): string };\n connect(): Promise<{ publicKey: { toBase58(): string } }>;\n disconnect(): Promise<void>;\n signTransaction<T>(transaction: T): Promise<T>;\n}\n\n/**\n * SVMProvider - Wallet adapter for SVM chains (Solana, Fogo) via Phantom\n *\n * @alias SolanaProvider for backward compatibility\n */\nexport class SVMProvider implements WalletAdapter {\n readonly id = 'phantom';\n readonly name = 'Phantom';\n readonly networkType = 'svm' as const;\n\n private provider: PhantomProvider | null = null;\n private publicKey: InstanceType<typeof PublicKey> | null = null;\n private connections: Map<string, InstanceType<typeof Connection>> = new Map();\n private address: string | null = null;\n\n /**\n * Check if Phantom wallet is available\n */\n isAvailable(): boolean {\n if (typeof window === 'undefined') return false;\n return !!(\n (window as Window & { phantom?: { solana?: PhantomProvider } }).phantom?.solana?.isPhantom ||\n (window as Window & { solana?: PhantomProvider }).solana?.isPhantom\n );\n }\n\n /**\n * Connect to Phantom wallet\n */\n async connect(): Promise<string> {\n await loadSolanaDeps();\n\n // Get Phantom provider\n this.provider = await this.getPhantomProvider();\n if (!this.provider) {\n throw new X402Error(\n 'Phantom wallet not installed. Please install from phantom.app',\n 'WALLET_NOT_FOUND'\n );\n }\n\n try {\n // Check if already connected\n if (this.provider.publicKey && this.provider.isConnected) {\n const publicKeyString = this.provider.publicKey.toBase58();\n this.publicKey = new PublicKey(publicKeyString);\n this.address = publicKeyString;\n await this.initConnection();\n return publicKeyString;\n }\n\n // Connect\n const resp = await this.provider.connect();\n const publicKeyString = resp.publicKey.toBase58();\n\n this.publicKey = new PublicKey(publicKeyString);\n this.address = publicKeyString;\n\n await this.initConnection();\n\n return publicKeyString;\n } catch (error: unknown) {\n if (error instanceof Error) {\n if (error.message.includes('User rejected') || (error as { code?: number }).code === 4001) {\n throw new X402Error('Connection rejected by user', 'WALLET_CONNECTION_REJECTED');\n }\n }\n throw new X402Error(\n `Failed to connect Phantom: ${error instanceof Error ? error.message : 'Unknown error'}`,\n 'UNKNOWN_ERROR',\n error\n );\n }\n }\n\n /**\n * Disconnect from Phantom\n */\n async disconnect(): Promise<void> {\n if (this.provider) {\n try {\n await this.provider.disconnect();\n } catch {\n // Ignore disconnect errors\n }\n }\n this.provider = null;\n this.publicKey = null;\n this.connections.clear();\n this.address = null;\n }\n\n /**\n * Get current address\n */\n getAddress(): string | null {\n return this.address;\n }\n\n /**\n * Get USDC balance\n */\n async getBalance(chainConfig: ChainConfig): Promise<string> {\n await loadSolanaDeps();\n\n if (!this.address) {\n throw new X402Error('Wallet not connected', 'WALLET_NOT_CONNECTED');\n }\n\n await this.initConnection(chainConfig);\n const connection = this.connections.get(chainConfig.name);\n if (!connection) {\n throw new X402Error('Failed to connect to Solana RPC', 'NETWORK_ERROR');\n }\n\n try {\n const response = await fetch(chainConfig.rpcUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n jsonrpc: '2.0',\n id: 1,\n method: 'getTokenAccountsByOwner',\n params: [\n this.address,\n { mint: chainConfig.usdc.address },\n { encoding: 'jsonParsed' },\n ],\n }),\n });\n\n const data = await response.json();\n\n if (!data.result?.value?.length) {\n return '0.00';\n }\n\n const tokenAccountInfo = data.result.value[0].account.data.parsed.info;\n const balance = Number(tokenAccountInfo.tokenAmount.amount) / Math.pow(10, tokenAccountInfo.tokenAmount.decimals);\n\n return balance.toFixed(2);\n } catch {\n return '0.00';\n }\n }\n\n /**\n * Create SVM payment (partially-signed transaction)\n *\n * Works for both Solana and Fogo chains.\n *\n * Transaction structure required by facilitator:\n * 1. SetComputeUnitLimit\n * 2. SetComputeUnitPrice\n * 3. (Optional) CreateAssociatedTokenAccount if recipient ATA doesn't exist\n * 4. TransferChecked (USDC transfer)\n *\n * Fee payer: Facilitator (not user)\n * User pays: ZERO SOL/FOGO\n */\n async signPayment(paymentInfo: PaymentInfo, chainConfig: ChainConfig): Promise<string> {\n await loadSolanaDeps();\n\n if (!this.provider || !this.publicKey || !this.address) {\n throw new X402Error('Wallet not connected', 'WALLET_NOT_CONNECTED');\n }\n\n const connection = await this.getConnection(chainConfig);\n if (!connection) {\n throw new X402Error(`Failed to connect to ${chainConfig.displayName} RPC`, 'NETWORK_ERROR');\n }\n\n // Get recipient and facilitator addresses\n const recipient = paymentInfo.recipients?.solana || paymentInfo.recipient;\n const facilitatorAddress = paymentInfo.facilitator;\n\n if (!facilitatorAddress) {\n throw new X402Error('Facilitator address not provided', 'INVALID_CONFIG');\n }\n\n const recipientPubkey = new PublicKey(recipient);\n const facilitatorPubkey = new PublicKey(facilitatorAddress);\n const usdcMint = new PublicKey(chainConfig.usdc.address);\n\n // Parse amount (6 decimals for USDC)\n const amount = Math.floor(parseFloat(paymentInfo.amount) * 1_000_000);\n\n // Get token accounts\n const fromTokenAccount = await getAssociatedTokenAddress(\n usdcMint,\n this.publicKey,\n true,\n TOKEN_PROGRAM_ID\n );\n\n const toTokenAccount = await getAssociatedTokenAddress(\n usdcMint,\n recipientPubkey,\n true,\n TOKEN_PROGRAM_ID\n );\n\n // Check if recipient ATA exists\n const toTokenAccountInfo = await connection.getAccountInfo(toTokenAccount);\n const needsATACreation = toTokenAccountInfo === null;\n\n // Get recent blockhash\n const { blockhash } = await connection.getLatestBlockhash('finalized');\n\n // Build instructions in exact order required by facilitator\n const instructions = [];\n\n // Instruction 0: SetComputeUnitLimit\n instructions.push(\n ComputeBudgetProgram.setComputeUnitLimit({\n units: needsATACreation ? 50_000 : 20_000,\n })\n );\n\n // Instruction 1: SetComputeUnitPrice\n // Use 100k microlamports/CU for fast landing on mainnet\n // Lower values (like 1) cause transactions to be deprioritized and time out\n instructions.push(\n ComputeBudgetProgram.setComputeUnitPrice({\n microLamports: 100_000,\n })\n );\n\n // Instruction 2 (optional): CreateAssociatedTokenAccountIdempotent\n // User pays for ATA creation (not facilitator - security check in x402-rs)\n if (needsATACreation) {\n instructions.push(\n createAssociatedTokenAccountIdempotentInstruction(\n this.publicKey, // User pays for ATA creation\n toTokenAccount,\n recipientPubkey,\n usdcMint,\n TOKEN_PROGRAM_ID\n )\n );\n }\n\n // Instruction 2/3: TransferChecked\n instructions.push(\n createTransferCheckedInstruction(\n fromTokenAccount,\n usdcMint,\n toTokenAccount,\n this.publicKey,\n amount,\n 6,\n [],\n TOKEN_PROGRAM_ID\n )\n );\n\n // Build VersionedTransaction with facilitator as fee payer\n const messageV0 = new TransactionMessage({\n payerKey: facilitatorPubkey,\n recentBlockhash: blockhash,\n instructions,\n }).compileToV0Message();\n\n const transaction = new VersionedTransaction(messageV0);\n\n // User signs (partial signature - facilitator will co-sign)\n // IMPORTANT: Phantom may modify the transaction (add memo instruction).\n // We send the FULL signed transaction to the facilitator, which will use it\n // exactly as signed (not reconstruct it). This ensures signature validity.\n let signedTransaction: InstanceType<typeof VersionedTransaction>;\n try {\n signedTransaction = await this.provider.signTransaction(transaction);\n } catch (error: unknown) {\n if (error instanceof Error && error.message.includes('User rejected')) {\n throw new X402Error('Signature rejected by user', 'SIGNATURE_REJECTED');\n }\n throw new X402Error(\n `Failed to sign transaction: ${error instanceof Error ? error.message : 'Unknown error'}`,\n 'PAYMENT_FAILED',\n error\n );\n }\n\n // Serialize the FULL signed transaction (including any wallet modifications)\n // The facilitator will use this exact transaction, adding only its signature\n const serialized = signedTransaction.serialize();\n\n const payload: SolanaPaymentPayload = {\n transaction: uint8ArrayToBase64(serialized),\n };\n\n return JSON.stringify(payload);\n }\n\n /**\n * Encode SVM payment as X-PAYMENT header\n *\n * @param paymentPayload - JSON-encoded payment payload from signPayment()\n * @param chainConfig - Chain configuration (optional, defaults to 'solana')\n * @param version - x402 protocol version (1 or 2, defaults to 1)\n * @returns Base64-encoded X-PAYMENT header value\n */\n encodePaymentHeader(\n paymentPayload: string,\n chainConfig?: ChainConfig,\n version: X402Version = 1\n ): string {\n const payload = JSON.parse(paymentPayload) as SolanaPaymentPayload;\n\n // Use chain name from config, or default to 'solana' for backward compatibility\n const networkName = chainConfig?.name || 'solana';\n\n // Build the payload data - preserve token info for Token2022 (AUSD, etc.)\n const payloadData: { transaction: string; token?: TokenInfo } = {\n transaction: payload.transaction,\n };\n\n // CRITICAL: Preserve token info for non-USDC tokens (Token2022 like AUSD)\n // Without this, the facilitator cannot verify Token2022 transfers correctly\n if (payload.token) {\n payloadData.token = payload.token;\n }\n\n // Format in x402 standard format (v1 or v2)\n const x402Payload = version === 2\n ? {\n x402Version: 2 as const,\n scheme: 'exact' as const,\n network: chainToCAIP2(networkName), // CAIP-2 format for v2\n payload: payloadData,\n }\n : {\n x402Version: 1 as const,\n scheme: 'exact' as const,\n network: networkName, // Plain chain name for v1\n payload: payloadData,\n };\n\n return encodeBase64Json(x402Payload);\n }\n\n // Private helpers\n\n private async getPhantomProvider(): Promise<PhantomProvider | null> {\n if (typeof window === 'undefined') return null;\n\n // Try window.phantom.solana first\n const win = window as Window & {\n phantom?: { solana?: PhantomProvider };\n solana?: PhantomProvider;\n };\n\n if (win.phantom?.solana?.isPhantom) {\n return win.phantom.solana;\n }\n\n // Fallback to window.solana\n if (win.solana?.isPhantom) {\n return win.solana;\n }\n\n // Wait a bit for Phantom to inject itself\n for (let i = 0; i < 5; i++) {\n await new Promise(resolve => setTimeout(resolve, 100));\n if (win.phantom?.solana?.isPhantom) {\n return win.phantom.solana;\n }\n if (win.solana?.isPhantom) {\n return win.solana;\n }\n }\n\n return null;\n }\n\n /**\n * Get or create a connection for a specific chain\n *\n * IMPORTANT: Caches by RPC URL, not chain name. This allows consumers to\n * override the RPC URL (e.g., use Helius instead of public RPC) and get\n * a fresh connection with their custom RPC.\n */\n private async getConnection(chainConfig?: ChainConfig): Promise<InstanceType<typeof Connection>> {\n await loadSolanaDeps();\n\n const config = chainConfig || getChainByName('solana');\n if (!config) {\n throw new X402Error('Chain config not found', 'CHAIN_NOT_SUPPORTED');\n }\n\n // Cache by RPC URL, not chain name - allows custom RPC overrides\n const cacheKey = config.rpcUrl;\n\n // Check if we already have a connection for this RPC\n if (this.connections.has(cacheKey)) {\n return this.connections.get(cacheKey)!;\n }\n\n // Create new connection for this RPC\n const connection = new Connection(config.rpcUrl, 'confirmed');\n this.connections.set(cacheKey, connection);\n\n return connection;\n }\n\n /**\n * @deprecated Use getConnection instead\n */\n private async initConnection(chainConfig?: ChainConfig): Promise<void> {\n await this.getConnection(chainConfig);\n }\n}\n\n/**\n * @deprecated Use SVMProvider instead\n */\nexport class SolanaProvider extends SVMProvider {\n constructor() {\n super();\n console.warn('SolanaProvider is deprecated. Use SVMProvider instead.');\n }\n}\n\n// Default export\nexport default SVMProvider;\n","/**\n * DX402 `durable-evidence`: recover a paid response after the fact.\n *\n * x402 settles payment on-chain permanently but delivers the purchased resource\n * **exactly once**, in the body of a `200 OK`, and keeps nothing. A buyer who did\n * not capture it at that instant cannot recover it, and neither party can later\n * prove *what* was delivered — only *that* payment happened.\n *\n * DX402 closes that gap. The seller seals a copy of the response to the payer's\n * own public key — recovered from the payment signature itself — and anchors it.\n * The buyer gets an `X-Durable-Evidence` header pointing at it.\n *\n * **Paying is publishing your encryption key.** No registration, no key\n * exchange, no extra round trip.\n *\n * ```ts\n * const evidence = evidenceFromHeaders(response.headers);\n * const body = await recoverEvidence(evidence, myPrivateKey);\n * ```\n *\n * Specification: `docs/plans/dx402/02-SPEC-v0.1.md` in x402-rs.\n */\n\nimport { gcm } from '@noble/ciphers/aes';\nimport { ed25519, x25519 } from '@noble/curves/ed25519';\nimport { secp256k1 } from '@noble/curves/secp256k1';\nimport { hkdf } from '@noble/hashes/hkdf';\nimport {\n hexToBytes as nobleHexToBytes,\n bytesToHex,\n} from '@noble/hashes/utils';\nimport { keccak_256 } from '@noble/hashes/sha3';\n\nimport { getChainById, getChainByName } from './chains';\nimport { sha256, sha512 } from '@noble/hashes/sha2';\n\nexport const EVIDENCE_HEADER = 'X-Durable-Evidence';\n\nconst MAGIC = new Uint8Array([0x44, 0x58, 0x34, 0x30, 0x32]); // \"DX402\"\n/** One recipient (the payer). Still emitted for that case, so deployed readers keep working. */\nconst FORMAT_V1 = 1;\n/** Several recipients. A v2 blob positively signals that somebody besides the payer can open it. */\nconst FORMAT_V2 = 2;\n\n/** Why a party holds a key to this evidence. */\nexport type RecipientRole = 'payer' | 'seller' | 'auditor';\nconst ROLE_NAMES: RecipientRole[] = ['payer', 'seller', 'auditor'];\nconst NONCE_LEN = 12;\nconst CEK_LEN = 32;\nconst HKDF_INFO = new TextEncoder().encode('DX402-v1-wrap');\n\nexport class DX402Error extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'DX402Error';\n }\n}\n\n/**\n * No evidence was anchored for this payment.\n *\n * A normal outcome, not a fault: the body may have exceeded the seller's size\n * cap, the store may have been unreachable, or the payer may be a\n * smart-contract wallet with no recoverable key.\n */\nexport class EvidenceSkipped extends DX402Error {\n constructor(public readonly reason: string) {\n super(`no durable evidence was anchored: ${reason}`);\n this.name = 'EvidenceSkipped';\n }\n}\n\n/**\n * The anchored bytes are not the bytes that were delivered.\n *\n * This is the interesting failure: the seller anchored something other than\n * what it served, which is precisely the fraud `contentHash` exists to expose.\n * Treat it as evidence of misbehaviour, not a transport glitch.\n */\nexport class ContentHashMismatch extends DX402Error {\n constructor(\n public readonly anchored: string,\n public readonly actual: string,\n ) {\n super(`content hash mismatch: anchored ${anchored}, decrypted ${actual}`);\n this.name = 'ContentHashMismatch';\n }\n}\n\nexport type EvidenceMode = 'direct' | 'escrowed';\n\nexport interface AnchoredEvidence {\n v: number;\n paymentId: string;\n pointer: string;\n backend: string;\n contentHash: string;\n cipher: string;\n keyAlg: 'ECIES-secp256k1' | 'ECIES-X25519';\n mode: EvidenceMode;\n retention: string;\n receipt?: string;\n}\n\n/**\n * Whether the facilitator is cryptographically unable to read this payload.\n *\n * `direct` and `escrowed` make materially different claims about who can open\n * the payload, so a caller that cares about confidentiality must check rather\n * than assume.\n */\nexport function isEndToEnd(evidence: AnchoredEvidence): boolean {\n return evidence.mode === 'direct';\n}\n\nfunction b64urlDecode(value: string): Uint8Array {\n const normalized = value.trim().replace(/-/g, '+').replace(/_/g, '/');\n const padded = normalized + '='.repeat((4 - (normalized.length % 4)) % 4);\n return Uint8Array.from(atob(padded), (c) => c.charCodeAt(0));\n}\n\n/**\n * Hex decode, strictly.\n *\n * The hand-rolled loop this replaces used `parseInt`, which returns NaN for\n * non-hex input — and a Uint8Array stores NaN as 0. So `'zz'.repeat(32)`\n * decoded to 32 zero bytes and `parseInt('4z', 16)` to 4: malformed input\n * became a plausible-looking key instead of an error. This gates real key\n * material (the payer private key in `recoverEvidence`, the 65-byte signature\n * in `payerKeyFromEvmSignature`, the payee address in `anchorDigest`), and the\n * symptom was a misleading 'wrong key, or the blob belongs to another payment'\n * one layer later. Same failure class as the base58 `rjust(32)` bug in the\n * Python SDK. Python (`bytes.fromhex`) and Rust (`hex::decode`) already reject;\n * TypeScript was the permissive outlier.\n */\nfunction hexToBytes(hex: string): Uint8Array {\n const clean = hex.startsWith('0x') ? hex.slice(2) : hex;\n try {\n return nobleHexToBytes(clean);\n } catch (e) {\n throw new DX402Error(`invalid hex: ${(e as Error).message}`);\n }\n}\n\n/** keccak256 of a body, `0x`-prefixed — matching the facilitator's `contentHash`. */\nexport function contentHash(body: Uint8Array): string {\n return '0x' + bytesToHex(keccak_256(body));\n}\n\n/**\n * Derive the canonical payment identifier: `keccak256(caip2Network || txHash)`.\n *\n * This value is the AEAD associated data binding a ciphertext to its payment.\n * Buyer and seller must derive it identically or decryption fails with no\n * obvious cause, which is why it lives in the SDK rather than in each caller.\n */\nexport function paymentId(caip2Network: string, txHash: string): string {\n const enc = new TextEncoder();\n const clean = txHash.startsWith('0x') ? txHash.slice(2) : txHash;\n const preimage = new Uint8Array([...enc.encode(caip2Network), ...enc.encode(clean)]);\n return '0x' + bytesToHex(keccak_256(preimage));\n}\n\n/** Parse an `X-Durable-Evidence` header value. */\nexport function parseEvidenceHeader(value: string): AnchoredEvidence {\n let payload: Record<string, unknown>;\n try {\n payload = JSON.parse(new TextDecoder().decode(b64urlDecode(value)));\n } catch (err) {\n throw new DX402Error(`malformed ${EVIDENCE_HEADER} header: ${String(err)}`);\n }\n if ('skipped' in payload) {\n throw new EvidenceSkipped(String(payload.skipped));\n }\n if (!payload.paymentId || !payload.pointer || !payload.contentHash) {\n throw new DX402Error(`malformed ${EVIDENCE_HEADER} header: missing required fields`);\n }\n return payload as unknown as AnchoredEvidence;\n}\n\n/**\n * Pull the anchored evidence out of a response's headers.\n *\n * Accepts a `Headers` object or a plain record. Lookup is case-insensitive,\n * because HTTP does not care and different clients disagree about casing.\n */\nexport function evidenceFromHeaders(\n headers: Headers | Record<string, string>,\n): AnchoredEvidence {\n let raw: string | null | undefined;\n if (typeof (headers as Headers).get === 'function') {\n raw = (headers as Headers).get(EVIDENCE_HEADER);\n } else {\n const target = EVIDENCE_HEADER.toLowerCase();\n for (const [key, value] of Object.entries(headers as Record<string, string>)) {\n if (key.toLowerCase() === target) {\n raw = value;\n break;\n }\n }\n }\n if (!raw) throw new DX402Error(`no ${EVIDENCE_HEADER} header on this response`);\n return parseEvidenceHeader(raw);\n}\n\n/**\n * Turn a DX402 pointer into a fetchable URL.\n *\n * `s3+https://...` is a scheme tag over an ordinary HTTPS URL; `ipfs://` and\n * `ar://` go through public gateways. Anything else passes through untouched, so\n * a caller with their own resolver is not blocked by this function.\n */\nexport function dereferencePointer(pointer: string): string {\n if (pointer.startsWith('s3+')) return pointer.slice(3);\n if (pointer.startsWith('ipfs://')) return `https://ipfs.io/ipfs/${pointer.slice(7)}`;\n if (pointer.startsWith('ar://')) return `https://arweave.net/${pointer.slice(5)}`;\n return pointer;\n}\n\ninterface Recipient {\n role: RecipientRole;\n alg: 'secp256k1' | 'x25519';\n ephemeral: Uint8Array;\n cekNonce: Uint8Array;\n wrappedCek: Uint8Array;\n}\n\ninterface SealedEnvelope {\n recipients: Recipient[];\n bodyNonce: Uint8Array;\n ciphertext: Uint8Array;\n}\n\n/**\n * Who can open this blob, without decrypting anything.\n *\n * Worth surfacing: a buyer has to be able to see that the seller — or a\n * designated auditor — also holds a key to what they bought. Finding that out\n * afterwards would destroy the privacy property.\n */\nexport function sealedRoles(raw: Uint8Array): RecipientRole[] {\n return parseSealed(raw).recipients.map((r) => r.role);\n}\n\n/**\n * Parse the sealed-blob layout.\n *\n * `MAGIC | version | alg | ephLen | eph | cekNonce | wrappedLen | wrapped |\n * bodyNonce | ciphertext`\n *\n * Every read is bounds-checked, so a truncated blob is a clear parse failure\n * rather than an out-of-range surprise later.\n */\nexport function parseSealed(raw: Uint8Array): SealedEnvelope {\n let pos = 0;\n const take = (n: number, what: string): Uint8Array => {\n if (raw.length < pos + n) throw new DX402Error(`truncated DX402 sealed blob at ${what}`);\n const chunk = raw.subarray(pos, pos + n);\n pos += n;\n return chunk;\n };\n\n const magic = take(MAGIC.length, 'magic');\n for (let i = 0; i < MAGIC.length; i++) {\n if (magic[i] !== MAGIC[i]) throw new DX402Error('not a DX402 sealed blob');\n }\n\n const version = take(1, 'version')[0];\n let count: number;\n if (version === FORMAT_V1) count = 1;\n else if (version === FORMAT_V2) count = take(1, 'recipient count')[0];\n else throw new DX402Error(`unsupported sealed-blob version ${version}`);\n\n // An envelope nobody can open is not evidence.\n if (count === 0) throw new DX402Error('DX402 sealed blob has no recipients');\n\n const recipients: Recipient[] = [];\n for (let i = 0; i < count; i++) {\n let role: RecipientRole = 'payer';\n if (version === FORMAT_V2) {\n const b = take(1, 'role')[0];\n if (b >= ROLE_NAMES.length) throw new DX402Error(`unknown role ${b}`);\n role = ROLE_NAMES[b];\n }\n\n const algByte = take(1, 'algorithm')[0];\n if (algByte !== 1 && algByte !== 2) {\n throw new DX402Error(`unknown key algorithm ${algByte}`);\n }\n const ephLen = take(1, 'ephemeral key length')[0];\n const ephemeral = take(ephLen, 'ephemeral key');\n const cekNonce = take(NONCE_LEN, 'cek nonce');\n const lenBytes = take(2, 'wrapped key length');\n const wrappedCek = take((lenBytes[0] << 8) | lenBytes[1], 'wrapped cek');\n\n recipients.push({\n role,\n alg: algByte === 1 ? 'secp256k1' : 'x25519',\n ephemeral,\n cekNonce,\n wrappedCek,\n });\n }\n\n const bodyNonce = take(NONCE_LEN, 'body nonce');\n return { recipients, bodyNonce, ciphertext: raw.subarray(pos) };\n}\n\nfunction sharedSecret(sealed: Recipient, privateKey: Uint8Array): Uint8Array {\n if (sealed.alg === 'secp256k1') {\n // Compressed output is 33 bytes: a 0x02/0x03 tag plus the x-coordinate.\n // Only the x-coordinate is the ECDH result, matching what the Rust side\n // feeds into HKDF. Including the tag byte would derive a different key and\n // fail with no useful diagnostic.\n const full = secp256k1.getSharedSecret(privateKey, sealed.ephemeral, true);\n return full.subarray(1);\n }\n\n // ed25519 seed -> X25519 scalar: SHA-512 the seed, take the low half.\n // @noble/curves clamps internally.\n const scalar = sha512(privateKey).subarray(0, 32);\n const shared = x25519.getSharedSecret(scalar, sealed.ephemeral);\n\n // RFC 7748 section 6.1: an all-zero result means a small-order public key was\n // supplied, which would make the wrapping key reproducible by whoever\n // supplied it.\n if (shared.every((b) => b === 0)) {\n throw new DX402Error('degenerate ECDH result (small-order public key)');\n }\n return shared;\n}\n\n/**\n * Decrypt a sealed envelope with whichever recipient slot belongs to `privateKey`.\n *\n * Tries every slot: a holder does not necessarily know which one is theirs, and\n * in a multi-recipient envelope the payer is not always first. A slot that does\n * not open is skipped, not reported — \"that one was not for me\" is not an error.\n */\nexport function unseal(\n sealed: SealedEnvelope,\n privateKey: Uint8Array,\n aad: Uint8Array,\n): Uint8Array {\n for (const recipient of sealed.recipients) {\n let shared: Uint8Array;\n try {\n shared = sharedSecret(recipient, privateKey);\n } catch (err) {\n if (err instanceof DX402Error) throw err;\n continue;\n }\n\n const wrapKey = hkdf(sha256, shared, aad, HKDF_INFO, 32);\n let cek: Uint8Array;\n try {\n cek = gcm(wrapKey, recipient.cekNonce, aad).decrypt(recipient.wrappedCek);\n } catch {\n continue; // not our slot\n }\n if (cek.length !== CEK_LEN) {\n throw new DX402Error(`unwrapped CEK is ${cek.length} bytes, expected ${CEK_LEN}`);\n }\n return gcm(cek, sealed.bodyNonce, aad).decrypt(sealed.ciphertext);\n }\n\n throw new DX402Error(\n 'no recipient slot opened -- wrong key, or the blob belongs to another payment',\n );\n}\n\n/**\n * Fetch, decrypt and verify the body behind `evidence`.\n *\n * `privateKey` is the raw key of the wallet that paid: 32 bytes for both an EVM\n * secp256k1 key and an ed25519 seed. Hex accepted with or without `0x`.\n *\n * In `direct` mode this needs no permission from anyone — the ciphertext was\n * sealed to the public key of the wallet that paid, so retrieval is arithmetic\n * rather than an access-control decision that could be refused or misconfigured.\n *\n * The `contentHash` check is **not optional**: it is what catches a seller that\n * anchored something other than what it served.\n */\nexport async function recoverEvidence(\n evidence: AnchoredEvidence,\n privateKey: Uint8Array | string,\n options: { fetch?: typeof fetch } = {},\n): Promise<Uint8Array> {\n const key = typeof privateKey === 'string' ? hexToBytes(privateKey) : privateKey;\n if (key.length !== 32) {\n throw new DX402Error(`private key must be 32 bytes, got ${key.length}`);\n }\n\n const doFetch = options.fetch ?? fetch;\n const url = dereferencePointer(evidence.pointer);\n const res = await doFetch(url);\n if (!res.ok) {\n throw new DX402Error(`could not fetch sealed evidence: HTTP ${res.status}`);\n }\n const blob = new Uint8Array(await res.arrayBuffer());\n\n const sealed = parseSealed(blob);\n const aad = new TextEncoder().encode(evidence.paymentId);\n\n let plaintext: Uint8Array;\n try {\n plaintext = unseal(sealed, key, aad);\n } catch (err) {\n if (err instanceof DX402Error) throw err;\n throw new DX402Error(\n 'decryption failed -- wrong key, or the blob belongs to another payment',\n );\n }\n\n const actual = contentHash(plaintext);\n if (actual.toLowerCase() !== evidence.contentHash.toLowerCase()) {\n throw new ContentHashMismatch(evidence.contentHash, actual);\n }\n\n return plaintext;\n}\n\n// ============================================================================\n// Seller side -- sealing\n// ============================================================================\n//\n// The half above recovers evidence. This half PRODUCES it, and it belongs to\n// whoever holds the plaintext: the resource server, right after settlement.\n//\n// The facilitator is deliberately not involved. It only ever sees /verify and\n// /settle, never a response body, so sealing cannot happen there.\n\nimport { edwardsToMontgomeryPub } from '@noble/curves/ed25519';\nimport { randomBytes } from '@noble/hashes/utils';\n\n/**\n * Map an ed25519 public key to its X25519 form.\n *\n * On ed25519 chains (Solana, NEAR, Stellar, Algorand) the address **is** the\n * public key, so this is all that stands between an address and an encryption\n * target — no signature, no lookup.\n */\nexport function ed25519ToX25519(pubkey: Uint8Array): Uint8Array {\n if (pubkey.length !== 32) {\n throw new DX402Error(`ed25519 public key must be 32 bytes, got ${pubkey.length}`);\n }\n return edwardsToMontgomeryPub(pubkey);\n}\n\n/**\n * Recover an EVM payer's secp256k1 public key from their payment signature.\n *\n * `digest` is the EIP-712 digest the payer actually signed. Getting it wrong\n * does not throw: it recovers a *different, perfectly valid* key, and the body\n * would be sealed to a stranger while every log line said success. The token's\n * EIP-712 domain name varies per chain and even flips between a chain's mainnet\n * and testnet, so derive it from the same table the facilitator uses.\n *\n * Returns the SEC1-compressed key (33 bytes).\n */\nexport function payerKeyFromEvmSignature(\n signature: Uint8Array | string,\n digest: Uint8Array,\n): Uint8Array {\n const sig = typeof signature === 'string' ? hexToBytes(signature) : signature;\n if (sig.length !== 65) {\n throw new DX402Error(`signature must be 65 bytes, got ${sig.length}`);\n }\n\n let v = sig[65 - 1];\n if (v === 27 || v === 28) v -= 27;\n else if (v >= 35) v = (v - 35) % 2;\n if (v !== 0 && v !== 1) throw new DX402Error(`invalid recovery id ${sig[64]}`);\n\n const parsed = secp256k1.Signature.fromCompact(sig.subarray(0, 64)).addRecoveryBit(v);\n return parsed.recoverPublicKey(digest).toRawBytes(true);\n}\n\n/**\n * Seal `body` so that only the holder of the payer's private key can read it.\n *\n * `payerKey` is a 33-byte SEC1-compressed secp256k1 key (EVM, XRPL) or a 32-byte\n * X25519 key from {@link ed25519ToX25519}.\n *\n * `paymentIdValue` is bound in as AEAD associated data, which is what stops a\n * ciphertext from being replayed as the evidence for a different payment.\n * Derive it with {@link paymentId} on both sides — deriving it differently makes\n * decryption fail with no obvious cause.\n *\n * Returns the bytes to upload. Nothing here touches the network.\n */\nexport function sealEvidence(\n body: Uint8Array,\n payerKey: Uint8Array,\n paymentIdValue: string,\n): Uint8Array {\n const aad = new TextEncoder().encode(paymentIdValue);\n const cek = randomBytes(32);\n const bodyNonce = randomBytes(NONCE_LEN);\n const cekNonce = randomBytes(NONCE_LEN);\n\n const ciphertext = gcm(cek, bodyNonce, aad).encrypt(body);\n\n let algByte: number;\n let ephemeral: Uint8Array;\n let shared: Uint8Array;\n\n if (payerKey.length === 33) {\n algByte = 1;\n const ephPriv = secp256k1.utils.randomPrivateKey();\n ephemeral = secp256k1.getPublicKey(ephPriv, true);\n // Only the x-coordinate is the ECDH result; the leading tag byte is not\n // part of it. Including it would derive a different key and fail with no\n // useful diagnostic.\n shared = secp256k1.getSharedSecret(ephPriv, payerKey, true).subarray(1);\n } else if (payerKey.length === 32) {\n algByte = 2;\n const ephPriv = randomBytes(32);\n ephemeral = x25519.getPublicKey(ephPriv);\n shared = x25519.getSharedSecret(ephPriv, payerKey);\n\n // RFC 7748 section 6.1: a small-order payer key would drive the shared\n // secret to a constant that whoever supplied it could reproduce.\n if (shared.every((b) => b === 0)) {\n throw new DX402Error('degenerate ECDH result (small-order public key)');\n }\n } else {\n throw new DX402Error(\n `payer key must be 33 bytes (secp256k1) or 32 (X25519), got ${payerKey.length}`,\n );\n }\n\n const wrapKey = hkdf(sha256, shared, aad, HKDF_INFO, 32);\n const wrappedCek = gcm(wrapKey, cekNonce, aad).encrypt(cek);\n\n const out = new Uint8Array(\n MAGIC.length + 3 + ephemeral.length + NONCE_LEN + 2 + wrappedCek.length +\n NONCE_LEN + ciphertext.length,\n );\n let pos = 0;\n out.set(MAGIC, pos); pos += MAGIC.length;\n out[pos++] = FORMAT_V1;\n out[pos++] = algByte;\n out[pos++] = ephemeral.length;\n out.set(ephemeral, pos); pos += ephemeral.length;\n out.set(cekNonce, pos); pos += NONCE_LEN;\n out[pos++] = (wrappedCek.length >> 8) & 0xff;\n out[pos++] = wrappedCek.length & 0xff;\n out.set(wrappedCek, pos); pos += wrappedCek.length;\n out.set(bodyNonce, pos); pos += NONCE_LEN;\n out.set(ciphertext, pos);\n return out;\n}\n\n// ============================================================================\n// Anchor authorization -- proving the anchor is yours\n// ============================================================================\n//\n// An anchor carrying a valid payee signature is `verified` and final. One\n// without is provisional: it still blocks a duplicate, but a verified anchor\n// for the same payment supersedes it.\n//\n// That asymmetry exists because the paymentId claim is permanent. Without it,\n// whoever anchored first owned the evidence of a payment forever and the real\n// seller was locked out.\n\nconst ANCHOR_DOMAIN_NAME = 'DX402 Anchor';\nconst ANCHOR_DOMAIN_VERSION = '1';\nconst ANCHOR_TYPE =\n 'Dx402AnchorAuthorization(bytes32 paymentId,bytes32 contentHash,string pointer,address payee)';\nconst EIP712_DOMAIN_TYPE = 'EIP712Domain(string name,string version,uint256 chainId)';\n\n/** The zero address, for the ed25519 form of the digest. */\nexport const ZERO_ADDRESS = '0x' + '00'.repeat(20);\n\nfunction concatBytes(...parts: Uint8Array[]): Uint8Array {\n const total = parts.reduce((n, p) => n + p.length, 0);\n const out = new Uint8Array(total);\n let pos = 0;\n for (const p of parts) {\n out.set(p, pos);\n pos += p.length;\n }\n return out;\n}\n\nfunction uint256(n: number | bigint): Uint8Array {\n const out = new Uint8Array(32);\n let v = BigInt(n);\n for (let i = 31; i >= 0 && v > 0n; i--) {\n out[i] = Number(v & 0xffn);\n v >>= 8n;\n }\n return out;\n}\n\n/**\n * The 32-byte digest a seller signs to prove an anchor is theirs.\n *\n * One canonical message across every curve. `payee` is the EVM address for a\n * secp256k1 payee and the **zero address** for an ed25519 one — an ed25519\n * address does not fit the `address` field, and the binding is already\n * established by which key verifies the signature.\n *\n * `pointer` is whatever you send in the anchor, or the **empty string** when you\n * send `sealed` and the facilitator issues the pointer itself: you cannot sign a\n * value you have not seen.\n *\n * Getting this wrong throws nothing — it produces a signature that simply never\n * verifies, and the anchor stays provisional with no clue why. The tests pin it\n * against digests emitted by the facilitator's own Rust implementation.\n */\nexport function anchorDigest(\n paymentId: string,\n contentHash: string,\n pointer: string,\n payee: string,\n chainId: number,\n): Uint8Array {\n const b32 = (value: string, field: string): Uint8Array => {\n const raw = hexToBytes(value);\n if (raw.length !== 32) throw new DX402Error(`${field} must be 32 bytes, got ${raw.length}`);\n return raw;\n };\n\n const addr = hexToBytes(payee);\n if (addr.length !== 20) {\n throw new DX402Error(`payee must be a 20-byte address, got ${addr.length}`);\n }\n\n const enc = new TextEncoder();\n const domainSeparator = keccak_256(\n concatBytes(\n keccak_256(enc.encode(EIP712_DOMAIN_TYPE)),\n keccak_256(enc.encode(ANCHOR_DOMAIN_NAME)),\n keccak_256(enc.encode(ANCHOR_DOMAIN_VERSION)),\n uint256(chainId),\n ),\n );\n\n const structHash = keccak_256(\n concatBytes(\n keccak_256(enc.encode(ANCHOR_TYPE)),\n b32(paymentId, 'paymentId'),\n b32(contentHash, 'contentHash'),\n keccak_256(enc.encode(pointer)),\n new Uint8Array(12),\n addr,\n ),\n );\n\n return keccak_256(concatBytes(new Uint8Array([0x19, 0x01]), domainSeparator, structHash));\n}\n\n/**\n * Sign an anchor authorization with a Solana / Stellar ed25519 key.\n *\n * A Solana payee cannot produce an EIP-712 signature at all — its address is an\n * ed25519 key — so requiring one would leave that chain unable to prove\n * authorship even once the on-chain gate is enforced. This closes it today, with\n * no RPC.\n */\nexport function signAnchorEd25519(\n privateKey: Uint8Array,\n paymentId: string,\n contentHash: string,\n pointer = '',\n): string {\n if (privateKey.length !== 32) {\n throw new DX402Error(`ed25519 seed must be 32 bytes, got ${privateKey.length}`);\n }\n const digest = anchorDigest(paymentId, contentHash, pointer, ZERO_ADDRESS, 0);\n return '0x' + bytesToHex(ed25519.sign(digest, privateKey));\n}\n\n/**\n * Sign an anchor authorization with an EVM secp256k1 key.\n *\n * `payee` must be the address of `privateKey` — the facilitator recovers the\n * signer and compares, so declaring somebody else's address simply leaves the\n * anchor provisional.\n */\nexport function signAnchorEvm(\n privateKey: Uint8Array,\n paymentId: string,\n contentHash: string,\n pointer: string,\n payee: string,\n chainId: number,\n): string {\n const digest = anchorDigest(paymentId, contentHash, pointer, payee, chainId);\n const sig = secp256k1.sign(digest, privateKey);\n return '0x' + bytesToHex(sig.toCompactRawBytes()) + (sig.recovery === 1 ? '01' : '00');\n}\n\n/**\n * Derive the encryption target from a Solana (or Fogo) address.\n *\n * On ed25519 chains the address **is** the public key, so this needs no\n * signature and no lookup. Rejects anything that does not decode to exactly 32\n * bytes: a short decode silently padded up to 32 produces a small-order point,\n * which fails a layer later with a message that points nowhere near the cause.\n */\nexport function payerKeyFromSolanaAddress(address: string): Uint8Array {\n if (!address || !address.trim()) throw new DX402Error('empty Solana address');\n\n const alphabet = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';\n let num = 0n;\n for (const ch of address) {\n const idx = alphabet.indexOf(ch);\n if (idx < 0) throw new DX402Error(`invalid base58 character '${ch}' in address`);\n num = num * 58n + BigInt(idx);\n }\n\n let hex = num.toString(16);\n if (hex.length % 2) hex = '0' + hex;\n const body = hexToBytes(hex);\n const leading = address.length - address.replace(/^1+/, '').length;\n\n const decoded = new Uint8Array(leading + body.length);\n decoded.set(body, leading);\n if (decoded.length !== 32) {\n throw new DX402Error(`Solana address decodes to ${decoded.length} bytes, expected 32`);\n }\n return ed25519ToX25519(decoded);\n}\n\n/**\n * Seal `body` so every listed recipient can read it, and nobody else.\n *\n * The body is encrypted **once**; only the content key is wrapped per recipient,\n * so adding the seller costs about sixty bytes rather than a second copy of the\n * payload. That is what makes it practical for a seller to keep a readable copy\n * of what it delivered — and answer a false \"that is not what you sent\" —\n * instead of paying to anchor evidence it cannot open.\n *\n * A single payer recipient is emitted as format **v1, byte-for-byte**, so\n * nothing already anchored becomes unreadable and readers still on v1 keep\n * working.\n */\nexport function sealEvidenceTo(\n body: Uint8Array,\n recipients: Array<{ role: RecipientRole; key: Uint8Array }>,\n paymentIdValue: string,\n): Uint8Array {\n if (recipients.length === 0) {\n throw new DX402Error('an envelope with no recipients could never be opened');\n }\n\n const aad = new TextEncoder().encode(paymentIdValue);\n const cek = randomBytes(CEK_LEN);\n const bodyNonce = randomBytes(NONCE_LEN);\n const ciphertext = gcm(cek, bodyNonce, aad).encrypt(body);\n\n const wrapped = recipients.map(({ role, key }) => {\n let algByte: number;\n let ephemeral: Uint8Array;\n let shared: Uint8Array;\n\n if (key.length === 33) {\n algByte = 1;\n const priv = secp256k1.utils.randomPrivateKey();\n ephemeral = secp256k1.getPublicKey(priv, true);\n shared = secp256k1.getSharedSecret(priv, key, true).subarray(1);\n } else if (key.length === 32) {\n algByte = 2;\n const priv = randomBytes(32);\n ephemeral = x25519.getPublicKey(priv);\n shared = x25519.getSharedSecret(priv, key);\n if (shared.every((b) => b === 0)) {\n throw new DX402Error('degenerate ECDH result (small-order public key)');\n }\n } else {\n throw new DX402Error(\n `public key must be 33 bytes (secp256k1) or 32 (X25519), got ${key.length}`,\n );\n }\n\n const wrapKey = hkdf(sha256, shared, aad, HKDF_INFO, 32);\n const cekNonce = randomBytes(NONCE_LEN);\n return {\n role,\n algByte,\n ephemeral,\n cekNonce,\n wrappedCek: gcm(wrapKey, cekNonce, aad).encrypt(cek),\n };\n });\n\n const singlePayer = wrapped.length === 1 && wrapped[0].role === 'payer';\n const parts: Uint8Array[] = [MAGIC, new Uint8Array([singlePayer ? FORMAT_V1 : FORMAT_V2])];\n if (!singlePayer) parts.push(new Uint8Array([wrapped.length]));\n\n for (const r of wrapped) {\n if (!singlePayer) parts.push(new Uint8Array([ROLE_NAMES.indexOf(r.role)]));\n parts.push(new Uint8Array([r.algByte, r.ephemeral.length]));\n parts.push(r.ephemeral, r.cekNonce);\n parts.push(new Uint8Array([(r.wrappedCek.length >> 8) & 0xff, r.wrappedCek.length & 0xff]));\n parts.push(r.wrappedCek);\n }\n\n parts.push(bodyNonce, ciphertext);\n return concatBytes(...parts);\n}\n\n// ============================================================================\n// The whole seller side, in one call\n// ============================================================================\n\nexport interface AnchorOptions {\n paymentId: string;\n network: string;\n txHash: string;\n payer: string;\n payee: string;\n /** The buyer's encryption key, from `payerKeyFromSolanaAddress` or similar. */\n payerKey: Uint8Array;\n /**\n * Your **public** key, to keep a readable copy so you can answer a false\n * \"that is not what you sent\".\n *\n * It does not have to be your payment key, and should not be — a custodial\n * payment wallet works fine here, because this key only ever decrypts.\n */\n sellerEncryptionKey?: Uint8Array;\n /**\n * The settlement proof, in the facilitator's `ProofOfPayment` shape\n * (`transactionHash`, `blockNumber`, `network`, `payer`, `payee`, `amount`,\n * `token`, `timestamp`, `paymentHash`).\n *\n * **The only thing that reaches `verified: true`.** Without it the\n * facilitator has checked no chain, so it records the anchor as provisional\n * and answers `notVerifiedReason: \"dx402_proof_missing\"`: the signature is\n * accepted (`signed: true`) but authorship is not certified, and a claim that\n * proves more may supersede it.\n */\n proofOfPayment?: Record<string, unknown>;\n /**\n * Which backend to anchor to (`\"s3\"`, `\"ipfs-private\"`, `\"ipfs-public\"`).\n * Omit to take the facilitator's default.\n *\n * Ask {@link availableBackends} what a given facilitator offers rather than\n * assuming — it depends on the deployment, and you may be pointed at one that\n * is not ours. **`ipfs-public` is irreversible**: the bytes become permanently\n * resolvable by anyone, and nobody, the facilitator included, can take them\n * down.\n */\n storage?: string;\n /**\n * `(digest) => \"0x...\"`. A callable rather than a private key is what lets a\n * custodian sign: it receives the digest and returns the signature without the\n * seed ever leaving it.\n *\n * Without one the anchor is **provisional** — it holds the slot, but a signed\n * anchor for the same payment supersedes it.\n */\n sign?: (digest: Uint8Array) => string | Promise<string>;\n /**\n * `(sealedBytes) => pointer`. Bring your own storage.\n *\n * Without this the sealed envelope travels **inside** the anchor request and\n * the facilitator hosts it, which is the easy path and stays the default. With\n * it, the SDK still seals exactly as before -- the buyer has to be able to\n * decrypt, so the sealing is not optional -- then hands you the ciphertext,\n * you write it wherever you keep durable bytes, and you return the pointer\n * that addresses it. The request then carries only that pointer, so the\n * ciphertext never travels through the anchor call and\n * {@link ANCHOR_MAX_REQUEST_BYTES} does not apply to your body.\n *\n * A callable rather than a precomputed pointer, for the same reason\n * {@link AnchorOptions.sign} is one: the SDK must seal first, and only then\n * can anything be uploaded. Handing in a pointer computed in advance would\n * mean addressing bytes that do not exist yet.\n *\n * The returned pointer is what the buyer will dereference, so it must be\n * readable by them -- see {@link dereferencePointer} for the schemes the SDK\n * resolves out of the box. It is also bound into the seller signature.\n *\n * **It is never allowed to break the sale.** If it throws or returns\n * something unusable, the anchor degrades to a skip and the payment is\n * untouched.\n */\n upload?: (sealed: Uint8Array) => string | Promise<string>;\n /**\n * Which storage family the pointer belongs to: `s3`, `ipfs` or `arweave`.\n *\n * Defaults to `s3`, and in {@link AnchorOptions.upload} mode it is inferred\n * from the pointer's scheme when you do not say. Distinct from `storage`,\n * which names one of the FACILITATOR's own offers and is meaningless when you\n * supply the bytes yourself.\n */\n backend?: 's3' | 'ipfs' | 'arweave';\n retention?: string;\n facilitator?: string;\n fetch?: typeof fetch;\n}\n\n/**\n * Seal a response body, anchor it, and return the `X-Durable-Evidence` value.\n *\n * **It never throws.** Every failure resolves to a skip notice, because evidence\n * is an addition to the payment path and must never be a gate in front of it —\n * an unreachable facilitator has to cost the receipt, never the sale.\n *\n * # Two ways to store the ciphertext\n *\n * **Hosted (default).** The sealed envelope travels inside the anchor request\n * and the facilitator stores it and issues the pointer. Nothing to set up. The\n * request carries the ciphertext, so it is bounded by\n * {@link ANCHOR_MAX_REQUEST_BYTES}.\n *\n * **Your own storage.** Pass {@link AnchorOptions.upload}. The SDK seals\n * identically, hands you the ciphertext, and sends the pointer you return in\n * place of the blob — so the ciphertext never travels through the anchor call\n * and that request bound does not apply to your body. The facilitator has\n * accepted a caller-supplied pointer since v0.1; this is the SDK catching up.\n *\n * ```ts\n * await anchorEvidence(body, {\n * ...common,\n * // called with the SEALED bytes, never the plaintext\n * upload: async (sealed) => {\n * await myBucket.put(key, sealed);\n * return `s3+https://cdn.example.com/${key}`;\n * },\n * });\n * ```\n *\n * Either way the seller keeps custody of nothing it did not already have: the\n * facilitator cannot read a `direct`-mode envelope in the hosted case either.\n * What changes is durability and cost, which become yours.\n */\n\n/** `0x` + 40 hex. An ed25519 payee (Solana, Stellar) never matches. */\nfunction isEvmAddress(value: string): boolean {\n return /^0x[0-9a-fA-F]{40}$/.test((value ?? '').trim());\n}\n\n/** The chain id behind a network name or CAIP-2 id, or undefined if unknown. */\nfunction chainIdFor(network: string): number | undefined {\n // `eip155:8453` carries the chain id literally. Read it rather than going\n // through the chain table, which has no entry for EVM TESTNETS -- so without\n // this a seller on one cannot produce a verifiable anchor signature at all.\n const raw = network ?? '';\n if (raw.toLowerCase().startsWith('eip155:')) {\n const tail = raw.slice('eip155:'.length);\n if (/^\\d+$/.test(tail)) return Number(tail);\n }\n const name = raw.includes(':') ? (raw.split(':')[1] ?? '') : raw;\n const byId = Number(name);\n if (Number.isFinite(byId) && byId > 0) return getChainById(byId)?.chainId;\n return getChainByName(name)?.chainId;\n}\n\n/**\n * The digest the facilitator will ACTUALLY verify, chosen by the payee's curve.\n *\n * The gate dispatches on the payee and checks **one** form -- never both. A\n * secp256k1 payee is verified against the digest built with its REAL address and\n * chain id; an ed25519 payee, whose address does not fit the `address` field, is\n * verified against the zero address and chain id 0.\n *\n * Signing the wrong form throws nothing. It yields a signature that never\n * verifies, the anchor silently stays **provisional**, and a provisional anchor\n * can be superseded by anyone -- the very hijack a signed anchor exists to stop.\n * Reproduced against production by KarmaKadabra, 2026-08-19: with everything else\n * identical, the ed25519 form was refused (`409 dx402_already_anchored`) and the\n * EVM form superseded the provisional.\n *\n * `pointer` defaults to the empty string, which is right when you send `sealed`:\n * the facilitator issues the pointer and you cannot sign what you have not seen.\n * When you supply your OWN pointer it must be passed here **verbatim** -- the\n * facilitator verifies against `req.pointer` when one is present and against\n * `\"\"` when it is absent (x402-rs `dx402/service.rs`, `signed_pointer`), so\n * signing the empty string alongside a pointer produces a signature that never\n * verifies and an anchor that silently stays provisional.\n */\nexport function sellerDigestFor(\n paymentId: string,\n contentHash: string,\n payee: string,\n network: string,\n pointer = '',\n): Uint8Array | undefined {\n if (isEvmAddress(payee)) {\n const chainId = chainIdFor(network);\n // An EVM payee whose chain id we cannot resolve. Falling through to the\n // ed25519 form is how this shipped in 0.53.0: it throws nothing and yields\n // a signature that never verifies, so the anchor stays provisional forever\n // with no error anywhere. Refuse instead -- unsigned is honest and\n // recoverable, signed-but-worthless only looks done.\n if (!chainId) return undefined;\n return anchorDigest(paymentId, contentHash, pointer, payee, chainId);\n }\n return anchorDigest(paymentId, contentHash, pointer, ZERO_ADDRESS, 0);\n}\n\n\n/**\n * Largest `POST /dx402/anchor` request the facilitator accepts, mirroring its\n * `MAX_REQUEST_BODY_BYTES` (default 64 KiB, an anti-OOM bound on every route).\n */\nexport const ANCHOR_MAX_REQUEST_BYTES = 64 * 1024;\n\n\n/** base64 without spreading the array into arguments -- a large blob would\n * otherwise overflow the call stack and surface as a generic failure. */\nfunction toBase64(bytes: Uint8Array): string {\n let out = '';\n const CHUNK = 0x8000;\n for (let i = 0; i < bytes.length; i += CHUNK) {\n out += String.fromCharCode(...bytes.subarray(i, i + CHUNK));\n }\n return btoa(out);\n}\n\n/**\n * Which storage family a pointer names, for the anchor's `backend` field.\n *\n * The facilitator records this; it does not fetch through it. `s3` is the\n * fallback because `s3+https://` is the SDK's own scheme for \"an ordinary HTTPS\n * URL\", which is what most sellers' own sinks are.\n */\nfunction backendForPointer(pointer: string): 's3' | 'ipfs' | 'arweave' {\n if (pointer.startsWith('ipfs://')) return 'ipfs';\n if (pointer.startsWith('ar://')) return 'arweave';\n return 's3';\n}\n\nexport async function anchorEvidence(\n body: Uint8Array,\n opts: AnchorOptions,\n): Promise<Record<string, unknown>> {\n try {\n const recipients: Array<{ role: RecipientRole; key: Uint8Array }> = [\n { role: 'payer', key: opts.payerKey },\n ];\n if (opts.sellerEncryptionKey) {\n recipients.push({ role: 'seller', key: opts.sellerEncryptionKey });\n }\n const blob = sealEvidenceTo(body, recipients, opts.paymentId);\n const hash = contentHash(body);\n\n // Bring-your-own-storage. The sealing above is identical either way -- the\n // buyer must be able to decrypt -- so all that changes is who holds the\n // ciphertext and, therefore, whether it has to travel in this request.\n //\n // The upload is fenced off completely: a seller's bucket going down is not\n // a reason for a paid response to fail, so anything thrown here becomes a\n // skip, exactly like an unreachable facilitator.\n let pointer: string | undefined;\n if (opts.upload) {\n try {\n pointer = await opts.upload(blob);\n } catch {\n return { v: 1, skipped: 'anchor_failed', stage: 'upload' };\n }\n if (typeof pointer !== 'string' || pointer.trim() === '') {\n // An empty pointer addresses nothing, and the facilitator would record\n // an anchor that dereferences to a 404 forever. Worse than no anchor.\n return { v: 1, skipped: 'anchor_failed', stage: 'upload' };\n }\n pointer = pointer.trim();\n }\n\n const payload: Record<string, unknown> = {\n paymentId: opts.paymentId,\n network: opts.network,\n txHash: opts.txHash,\n payer: opts.payer,\n payee: opts.payee,\n // Exactly one of these. The facilitator dispatches on their presence:\n // `sealed` -> it hosts and derives the pointer; `pointer` alone -> it uses\n // yours; neither -> error (x402-rs `dx402/service.rs`).\n ...(pointer !== undefined ? { pointer } : { sealed: toBase64(blob) }),\n // Declared, not measured. Since x402-rs 2.3.0 the facilitator records\n // the store that ACTUALLY took the bytes and returns that, so a response\n // may name a different backend than the request did -- `ipfs` where you\n // said `s3`, because a deployment whose primary is Pinata wrote there.\n // That is the facilitator correcting the record, not a mismatch to\n // assert on.\n backend: opts.backend ?? (pointer !== undefined ? backendForPointer(pointer) : 's3'),\n contentHash: hash,\n keyAlg: opts.payerKey.length === 32 ? 'ECIES-X25519' : 'ECIES-secp256k1',\n mode: 'direct',\n retention: opts.retention ?? '90d',\n };\n\n let unsigned: string | undefined;\n if (opts.proofOfPayment) {\n payload.proofOfPayment = opts.proofOfPayment;\n }\n\n if (opts.storage) {\n payload.storage = opts.storage;\n }\n\n if (opts.sign) {\n // The signature covers the pointer the facilitator will verify against:\n // ours when we supply one, the empty string when the facilitator issues\n // it. Signing the wrong one throws nothing and leaves the anchor\n // provisional -- which is the state anyone can supersede.\n const digest = sellerDigestFor(opts.paymentId, hash, opts.payee, opts.network, pointer ?? '');\n if (digest === undefined) {\n unsigned = 'unknown_chain_id';\n } else {\n payload.sellerSignature = await opts.sign(digest);\n }\n }\n\n // Measure the SEALED, serialised request -- not the plaintext. The\n // envelope adds a nonce, the wrapped CEK and its JSON, and the ciphertext\n // travels base64 (4/3). Checking the plaintext lets through bodies the\n // facilitator then rejects, arriving as a generic failure long after the\n // sealing work was done. Measured by KarmaKadabra, 2026-08-19: 47 KB of\n // plaintext fits, 48 KB does not.\n //\n // In `upload` mode the ciphertext is not in the request at all, so this\n // bound says nothing about the body and is not applied. The request is a\n // pointer and some metadata; only a pathological pointer could approach it.\n const wire = JSON.stringify(payload);\n if (pointer === undefined && new TextEncoder().encode(wire).length > ANCHOR_MAX_REQUEST_BYTES) {\n return { v: 1, skipped: 'too_large' };\n }\n\n const base = (opts.facilitator ?? 'https://facilitator.ultravioletadao.xyz').replace(\n /\\/+$/,\n '',\n );\n const doFetch = opts.fetch ?? fetch;\n const res = await doFetch(`${base}/dx402/anchor`, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: wire,\n });\n // Carry the facilitator's own diagnosis out rather than flattening every\n // failure to `anchor_failed`. A rejected signature answers 422\n // `dx402_signature_not_verified`; erasing it here would reproduce, one\n // layer down, the exact problem that code exists to solve.\n if (!res.ok) {\n let error: unknown;\n try {\n error = ((await res.json()) as { error?: unknown }).error;\n } catch {\n /* a non-JSON error body is still a failure */\n }\n return { v: 1, skipped: 'anchor_failed', status: res.status, error };\n }\n const out = (await res.json()) as Record<string, unknown>;\n if (unsigned) out.unsigned = unsigned;\n return out;\n } catch {\n return { v: 1, skipped: 'anchor_failed' };\n }\n}\n\n/** One storage option a facilitator offers, from `GET /dx402/stats`. */\nexport interface BackendOffer {\n id: string;\n retention: string;\n /**\n * Whether the bytes can actually be removed when retention expires.\n *\n * `false` means the `retentionUntil` in the signed receipt **cannot be\n * honoured**: on public IPFS, unpinning removes the facilitator's copy, not\n * the network's.\n */\n revocable: boolean;\n /** Whether anyone resolves the bytes without going through the facilitator. */\n public: boolean;\n enabled: boolean;\n disabledReason?: string;\n}\n\n/**\n * Ask a facilitator which storage backends it actually offers.\n *\n * Ask instead of assuming. What exists depends on the deployment — one without\n * a Pinata credential offers only `s3` — and an integrator may be pointed at a\n * facilitator that is not ours. A hardcoded list in your code is a promise\n * somebody else has to keep.\n *\n * Resolves to `[]` rather than rejecting when the facilitator is unreachable or\n * does not run DX402 — same discipline as {@link anchorEvidence}.\n */\nexport async function availableBackends(\n facilitator = 'https://facilitator.ultravioletadao.xyz',\n opts: { fetch?: typeof fetch } = {},\n): Promise<BackendOffer[]> {\n try {\n const doFetch = opts.fetch ?? fetch;\n const res = await doFetch(`${facilitator.replace(/\\/+$/, '')}/dx402/stats`);\n if (!res.ok) return [];\n const body = (await res.json()) as { backends?: BackendOffer[] };\n return body.backends ?? [];\n } catch {\n return [];\n }\n}\n\n/** Encode an anchor result for the `X-Durable-Evidence` response header. */\nexport function evidenceHeader(evidence: unknown): string {\n // Encode to UTF-8 first. `btoa` takes a *binary* string: any code point above\n // U+00FF throws InvalidCharacterError, and one between U+0080 and U+00FF is\n // silently emitted as a single latin-1 byte, so the far side decodes mojibake.\n // Either is reachable from ordinary evidence -- a `notVerifiedReason` or a\n // pointer with a non-ASCII character is enough.\n const bytes = new TextEncoder().encode(JSON.stringify(evidence));\n return toBase64(bytes).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\n}\n","/** Portable payment receipts. They attest settlement, not merchant delivery. */\nimport { ed25519 } from '@noble/curves/ed25519';\nimport { sha256 } from '@noble/hashes/sha256';\nimport { bytesToHex, randomBytes } from '@noble/hashes/utils';\nimport type { X402FetchOptions } from './types';\n\nexport const RECEIPT_ISSUER = 'https://facilitator.ultravioletadao.xyz';\nexport type PaymentState = 'verified' | 'pending' | 'confirmed' | 'rejected' | 'unknown' | 'not_required';\nexport interface FacilitatorReceipt {\n schemaVersion: number; receiptId: string; revision: number; issuer: string; issuedAt: number;\n operation: string; purchaseId: string | null; network: string; scheme: string; x402Version: number;\n asset: string; amount: string; decimals: number | null; payTo: string; payer: string | null;\n requestHash: string; requestHashVersion: string; request: Record<string, unknown>;\n paymentRequestHash: string; authorizationId: string; status: string;\n settlement: { id: string; idType: string; paymentId?: string | null; [key: string]: unknown } | null;\n refusalReason: string | null; diagnosticCode: string | null;\n retry: { action: string; afterSeconds?: number; [key: string]: unknown };\n proof: { type: string; jws?: string; [key: string]: unknown } | null;\n [key: string]: unknown;\n}\nexport interface PurchaseContext {\n purchaseId: string;\n /** Secret lookup capability. Store privately alongside paymentHeaders. */\n accessToken: string;\n method?: string; url?: string; bodySha256?: string;\n paymentHeaders?: Record<string, string>;\n receipt?: FacilitatorReceipt;\n}\nexport interface ReceiptKeys { keys: Array<{ kid?: string; kty?: string; crv?: string; x?: string }> }\nexport interface FetchReceiptResult {\n response: Response | null; receipt: FacilitatorReceipt | null; paymentState: PaymentState;\n context: PurchaseContext; proofVerified: boolean; error?: unknown;\n}\nexport interface ReceiptFetchOptions extends X402FetchOptions {\n context: PurchaseContext;\n /** Must complete before the authorized request is sent. */\n persist: (context: PurchaseContext) => void | Promise<void>;\n trustedKeys?: ReceiptKeys;\n issuer?: string;\n}\n\nconst encoder = new TextEncoder();\nconst decoder = new TextDecoder('utf-8', { fatal: true });\nconst digest = (value: Uint8Array): string => bytesToHex(sha256(value));\n\nexport function canonicalReceiptJson(value: unknown): string {\n if (value === null || typeof value === 'string' || typeof value === 'boolean') return JSON.stringify(value);\n if (typeof value === 'number' && Number.isSafeInteger(value) && value >= 0) return String(value);\n if (Array.isArray(value)) return `[${value.map(canonicalReceiptJson).join(',')}]`;\n if (typeof value === 'object' && value) {\n const object = value as Record<string, unknown>;\n const keys = Object.keys(object).sort();\n if (keys.some(key => !/^[\\x00-\\x7f]*$/.test(key))) throw new Error('non-ASCII canonical key');\n return `{${keys.map(key => `${JSON.stringify(key)}:${canonicalReceiptJson(object[key])}`).join(',')}}`;\n }\n throw new Error('unsupported canonical value');\n}\nexport function receiptCommitment(domain: string, value: unknown): string {\n return digest(encoder.encode(`${domain}\\n${canonicalReceiptJson(value)}`));\n}\n\nfunction encode64(bytes: Uint8Array): string {\n if (typeof Buffer !== 'undefined') return Buffer.from(bytes).toString('base64');\n return btoa(Array.from(bytes, b => String.fromCharCode(b)).join(''));\n}\nfunction decode64(value: string): Uint8Array {\n if (!/^[A-Za-z0-9+/]*={0,2}$/.test(value) || value.length % 4 !== 0) throw new Error('invalid base64');\n if (typeof Buffer !== 'undefined') return new Uint8Array(Buffer.from(value, 'base64'));\n return Uint8Array.from(atob(value), c => c.charCodeAt(0));\n}\nfunction decodeUrl64(value: string): Uint8Array {\n const padded = value.replace(/-/g, '+').replace(/_/g, '/');\n return decode64(padded + '='.repeat((4 - padded.length % 4) % 4));\n}\n\nexport function parseFacilitatorReceipt(value: unknown): FacilitatorReceipt | null {\n if (value === null || value === undefined) return null;\n const r = value as FacilitatorReceipt;\n if (r.schemaVersion !== 1 || !['verified', 'pending', 'confirmed', 'rejected', 'unknown'].includes(r.status)) throw new Error('unsupported receipt version or state');\n for (const key of ['receiptId', 'issuer', 'operation', 'network', 'scheme', 'asset', 'amount', 'payTo', 'paymentRequestHash', 'authorizationId']) {\n if (typeof r[key] !== 'string' || !r[key]) throw new Error(`invalid receipt ${key}`);\n }\n if (!Number.isSafeInteger(r.revision) || r.revision < 1 || !r.request || !r.retry) throw new Error('incomplete receipt');\n if (r.requestHashVersion !== 'uvd-x402-request-v1' || r.requestHash !== receiptCommitment(r.requestHashVersion, r.request)) throw new Error('receipt request hash mismatch');\n for (const key of ['network', 'scheme', 'asset', 'amount', 'payTo', 'purchaseId']) {\n if (r[key] !== r.request[key]) throw new Error('receipt terms mismatch');\n }\n if (!/^[0-9]+$/.test(r.amount)) throw new Error('receipt amount must be an atomic integer string');\n if (r.status === 'confirmed' && (r.operation !== 'settle' || !r.settlement?.id)) throw new Error('confirmation has no settlement');\n return r;\n}\n\n/** Keys must be trusted independently of the receipt; no auto-fetch of issuer URLs. */\nexport function verifyFacilitatorReceipt(receipt: FacilitatorReceipt, jwks: ReceiptKeys, issuer = RECEIPT_ISSUER): boolean {\n try {\n parseFacilitatorReceipt(receipt);\n if (receipt.issuer !== issuer || receipt.proof?.type !== 'jws' || !receipt.proof.jws) return false;\n const parts = receipt.proof.jws.split('.');\n if (parts.length !== 3) return false;\n const [protectedHeader, payload, signature] = parts;\n const header = JSON.parse(decoder.decode(decodeUrl64(protectedHeader)));\n if (header.alg !== 'EdDSA' || header.typ !== 'uvd-facilitator-receipt+jws') return false;\n const keys = jwks.keys.filter(k => k.kid === header.kid && k.kty === 'OKP' && k.crv === 'Ed25519');\n if (keys.length !== 1 || !keys[0].x) return false;\n if (decoder.decode(decodeUrl64(payload)) !== canonicalReceiptJson({ ...receipt, proof: null })) return false;\n return ed25519.verify(decodeUrl64(signature), encoder.encode(`${protectedHeader}.${payload}`), decodeUrl64(keys[0].x));\n } catch { return false; }\n}\n\nexport function createPurchaseContext(): PurchaseContext {\n return { purchaseId: bytesToHex(randomBytes(16)), accessToken: bytesToHex(randomBytes(32)) };\n}\nexport function purchaseContextHeader(context: PurchaseContext): string {\n return encode64(encoder.encode(canonicalReceiptJson({ purchaseId: context.purchaseId, accessToken: context.accessToken,\n method: context.method, url: context.url, bodySha256: context.bodySha256 })));\n}\n/** Merchant-side binding to the actual request, before asking the facilitator. */\nexport function validatePurchaseContext(header: string | undefined, method: string, url: string, body: Uint8Array): string | undefined {\n if (!header) return undefined;\n if (header.length > 8192) throw new Error('invalid purchase context');\n const context = JSON.parse(decoder.decode(decode64(header)));\n if (typeof context.purchaseId !== 'string' || !context.purchaseId || context.purchaseId.length > 128\n || typeof context.accessToken !== 'string' || !/^[0-9a-f]{64}$/.test(context.accessToken)\n || context.method !== method.toUpperCase() || context.url !== new URL(url).toString()\n || context.bodySha256 !== digest(body)) throw new Error('purchase context does not match the HTTP request');\n return header;\n}\nexport function paymentResponseHeaders(result: Record<string, unknown>): Record<string, string> {\n const encoded = encode64(encoder.encode(JSON.stringify(result)));\n if (encoded.length > 32768) throw new Error('payment response too large');\n return { 'PAYMENT-RESPONSE': encoded, 'X-PAYMENT-RESPONSE': encoded,\n 'Access-Control-Expose-Headers': 'PAYMENT-RESPONSE, X-PAYMENT-RESPONSE', 'Cache-Control': 'no-store' };\n}\n/** Headers that hold a comma-separated list the application may already have set. */\nconst LIST_HEADERS = ['Access-Control-Expose-Headers', 'Cache-Control'];\n/**\n * Adds the comma-separated `additions` to `existing`, keeping every entry already\n * there and its spelling. Entries compare case-insensitively by name, so a\n * `Cache-Control` of `no-store, max-age=0` does not gain a second `no-store`.\n */\nexport function mergeHeaderList(existing: string | undefined, additions: string): string {\n const name = (entry: string) => entry.split('=')[0].trim().toLowerCase();\n const kept = (existing || '').split(',').map(entry => entry.trim()).filter(Boolean);\n const seen = new Set(kept.map(name));\n for (const entry of additions.split(',').map(value => value.trim()).filter(Boolean)) {\n if (!seen.has(name(entry))) { kept.push(entry); seen.add(name(entry)); }\n }\n return kept.join(', ');\n}\n/**\n * {@link paymentResponseHeaders} for a response that may already carry CORS or\n * cache headers: `Access-Control-Expose-Headers` and `Cache-Control` are merged\n * with the current value read through `current`, never replaced.\n */\nexport function mergePaymentResponseHeaders(\n result: Record<string, unknown>, current: (name: string) => string | undefined,\n): Record<string, string> {\n const headers = paymentResponseHeaders(result);\n for (const name of LIST_HEADERS) headers[name] = mergeHeaderList(current(name), headers[name]);\n return headers;\n}\nexport function receiptFromResponse(response: Response): FacilitatorReceipt | null {\n const values = [response.headers.get('PAYMENT-RESPONSE'), response.headers.get('X-PAYMENT-RESPONSE')].filter((v): v is string => v !== null);\n if (!values.length) return null;\n if (new Set(values).size !== 1 || values[0].includes(',') || values[0].length > 32768) throw new Error('ambiguous or oversized payment response header');\n return parseFacilitatorReceipt(JSON.parse(decoder.decode(decode64(values[0]))).receipt);\n}\n/** HTTP error bodies can be plain text. Preserve their original diagnosis. */\nexport function receiptFromErrorBody(body: string): FacilitatorReceipt | null {\n try { return parseFacilitatorReceipt(JSON.parse(body).receipt); } catch { return null; }\n}\n\nexport async function fetchWithReceipt(\n fetchClient: (url: string, options: X402FetchOptions) => Promise<Response>, url: string, options: ReceiptFetchOptions,\n): Promise<FetchReceiptResult> {\n const { context, persist, trustedKeys, issuer = RECEIPT_ISSUER } = options;\n const transport = options.fetchImpl || globalThis.fetch;\n const method = (options.method || 'GET').toUpperCase();\n const request = new Request(url, { ...options.init, method });\n const bytes = new Uint8Array(await request.arrayBuffer());\n const bodyHash = digest(bytes);\n if (context.method && (context.method !== method || context.url !== request.url || context.bodySha256 !== bodyHash)) throw new Error('purchase context cannot be reused for another HTTP request');\n context.method = method; context.url = request.url; context.bodySha256 = bodyHash;\n const init = { ...options.init, method, headers: new Headers(request.headers), body: ['GET', 'HEAD'].includes(method) ? undefined : bytes };\n let receipt = parseFacilitatorReceipt(context.receipt);\n let transportError: unknown;\n const persistCopy = async () => { await persist(JSON.parse(JSON.stringify(context))); };\n const send: typeof fetch = async (input, sendOptions) => {\n const headers = new Headers(sendOptions?.headers);\n const paid = headers.get('X-PAYMENT') || headers.get('PAYMENT-SIGNATURE');\n if (paid) {\n const paymentHeaders: Record<string, string> = {};\n for (const name of ['X-PAYMENT', 'PAYMENT-SIGNATURE']) {\n const value = headers.get(name); if (value) paymentHeaders[name] = value;\n }\n if (context.paymentHeaders && JSON.stringify(context.paymentHeaders) !== JSON.stringify(paymentHeaders)) throw new Error('refusing a new authorization for an existing purchase');\n context.paymentHeaders = paymentHeaders;\n headers.set('X-UVD-Purchase', purchaseContextHeader(context));\n await persistCopy();\n }\n try { return await transport(input, { ...sendOptions, headers }); }\n catch (error) { transportError = error; throw error; }\n };\n try {\n let response: Response;\n if (context.paymentHeaders) {\n const headers = new Headers(init.headers);\n for (const [name, value] of Object.entries(context.paymentHeaders)) headers.set(name, value);\n response = await send(request.url, { ...init, headers });\n } else {\n response = await fetchClient(request.url, { ...options, method, init, fetchImpl: send });\n }\n const incoming = receiptFromResponse(response);\n if (incoming) {\n if (incoming.issuer !== issuer || Object.entries({ purchaseId: context.purchaseId, method, url: context.url, bodySha256: bodyHash }).some(([key, value]) => incoming.request[key] !== value)) throw new Error('receipt does not bind this purchase');\n if (receipt?.operation === 'settle' && (incoming.receiptId !== receipt.receiptId || incoming.revision < receipt.revision)) throw new Error('receipt revision conflict');\n if (trustedKeys && !verifyFacilitatorReceipt(incoming, trustedKeys, issuer)) throw new Error('receipt signature verification failed');\n receipt = incoming; context.receipt = incoming; await persistCopy();\n }\n const proofVerified = !!(receipt && trustedKeys && verifyFacilitatorReceipt(receipt, trustedKeys, issuer));\n if (receipt && trustedKeys && !proofVerified) throw new Error('receipt signature verification failed');\n return { response, receipt, paymentState: receipt ? receipt.status as PaymentState : context.paymentHeaders ? 'unknown' : 'not_required', context, proofVerified };\n } catch (error) {\n if (!transportError) throw error;\n return { response: null, receipt, paymentState: 'unknown', context, proofVerified: false, error };\n }\n}\n\nexport async function getFacilitatorReceipt(receiptId: string, context: PurchaseContext, options: { issuer?: string; fetchImpl?: typeof fetch } = {}): Promise<FacilitatorReceipt> {\n if (!/^[0-9a-f-]{36}$/.test(receiptId)) throw new Error('invalid receipt ID');\n const issuer = options.issuer || RECEIPT_ISSUER;\n const response = await (options.fetchImpl || globalThis.fetch)(`${issuer}/receipts/${receiptId}`, { headers: { Authorization: `Bearer ${context.accessToken}` } });\n if (!response.ok) throw new Error(`receipt lookup failed: ${response.status}`);\n const receipt = parseFacilitatorReceipt((await response.json()).receipt);\n if (!receipt || receipt.issuer !== issuer || receipt.purchaseId !== context.purchaseId) throw new Error('receipt lookup mismatch');\n return receipt;\n}\n","/**\n * uvd-x402-sdk - Main Client\n *\n * The X402Client is the primary entry point for the SDK.\n * It manages wallet connections, chain switching, and payment creation.\n */\n\nimport { ethers } from 'ethers';\nimport { fetchWithReceipt, type ReceiptFetchOptions, type FetchReceiptResult } from '../receipts';\nimport type {\n ChainConfig,\n NetworkType,\n PaymentInfo,\n PaymentResult,\n WalletState,\n X402ClientConfig,\n X402Event,\n X402EventData,\n X402EventHandler,\n EVMPaymentPayload,\n TokenType,\n X402EVMPayload,\n X402Version,\n X402PaymentOffer,\n X402FetchOptions,\n WalletAdapter,\n} from '../types';\nimport { X402Error, DEFAULT_CONFIG } from '../types';\nimport {\n PurchasePolicy,\n PolicyRefusedError,\n decideOnChallenge,\n noReadableOffer,\n canonicalRecipient,\n} from '../policy';\nimport type { PolicyApproval, ReadChallenge } from '../policy';\nimport {\n SUPPORTED_CHAINS,\n getChainByName,\n getChainById,\n getEnabledChains,\n getTokenConfig,\n} from '../chains';\nimport {\n validateRecipient,\n chainToCAIP2,\n caip2ToChain,\n encodeBase64Json,\n buildTokenMetadata,\n resolveValiditySeconds,\n clampValiditySeconds,\n} from '../utils';\n\n/**\n * The x402 scheme vocabulary, shared by all three implementations.\n *\n * The same five the Rust facilitator's closed `Scheme` enum holds and the same\n * five the Python SDK keys `KNOWN_SCHEMES` on. A scheme outside this set is one\n * no implementation in the stack can name, so an entry carrying one is unreadable\n * and is counted by the name the seller used.\n *\n * Kept as a set of known NAMES rather than of payable ones because the two are\n * different questions, and conflating them is what rule 7 is about: naming what a\n * seller offered is how a caller learns to go find a facilitator that implements\n * it. See {@link CLIENT_PAYABLE_SCHEMES} for the other question.\n */\nexport const KNOWN_SCHEMES: ReadonlySet<string> = new Set([\n 'exact',\n 'upto',\n 'escrow',\n 'commerce',\n 'fhe-transfer',\n]);\n\n/**\n * Of those, the ones the BUYER path in this client can actually sign.\n *\n * One entry, and that is the point: the payload builder stamps\n * `scheme: 'exact'` into everything it produces, so `exact` is the only thing\n * this client can honestly present. `escrow` and `commerce` are implemented on\n * the SELLER side (`src/backend`) and in the pre-auth builder, and `upto` and\n * `fhe-transfer` are not implemented here at all.\n *\n * # Why this is a SECOND set and not a narrower first one\n *\n * `parse402` used to accept any entry carrying an amount, a payee and a network,\n * so a well-formed offer asking for a scheme this build cannot present was read\n * as payable and then **signed as `exact`** -- a payment offered to the seller\n * under a scheme it never asked for. Recognising a scheme is not being able to\n * pay it. Collapsing these two sets into one re-opens exactly that hole: widen\n * this one to the five known names and a well-formed `escrow` offer gets signed\n * as `exact` again.\n *\n * Both cases end the same way for the caller -- the entry is excluded and counted\n * by its scheme name -- and `no-readable-offer` says \"no offer in this challenge\n * is one this build **can pay**\", which is the frame both of them sit in.\n */\nexport const CLIENT_PAYABLE_SCHEMES: ReadonlySet<string> = new Set(['exact']);\n\n/**\n * X402Client - Main SDK client for x402 payments\n *\n * @example\n * ```ts\n * import { X402Client } from 'uvd-x402-sdk';\n *\n * const client = new X402Client({ defaultChain: 'base' });\n *\n * // Connect wallet\n * await client.connect('base');\n *\n * // Create payment\n * const result = await client.createPayment({\n * recipient: '0x...',\n * amount: '10.00',\n * });\n *\n * // Use result.paymentHeader in your API request\n * ```\n */\nexport class X402Client {\n // Configuration\n private readonly config: Required<Pick<X402ClientConfig, 'facilitatorUrl' | 'defaultChain' | 'autoConnect' | 'debug'>> & X402ClientConfig;\n\n // Wallet state\n private provider: ethers.BrowserProvider | ethers.JsonRpcProvider | null = null;\n private signer: ethers.Signer | null = null;\n private connectedAddress: string | null = null;\n private currentChainId: number | null = null;\n private currentNetwork: NetworkType | null = null;\n private currentChainName: string | null = null;\n /**\n * Non-EVM wallet, when one is connected. EVM keeps using `provider`/`signer`\n * because those are ethers-typed; every other network type talks through the\n * {@link WalletAdapter} contract instead.\n */\n private walletAdapter: WalletAdapter | null = null;\n\n // Event emitter\n private eventHandlers: Map<X402Event, Set<X402EventHandler<X402Event>>> = new Map();\n\n /**\n * What this buyer is allowed to sign, evaluated against the offer in hand\n * before anything is signed.\n *\n * `permissive()` when the caller supplied none, and that asymmetry is\n * deliberate: this SDK had no budget before 2.89.0, so switching one on\n * silently would refuse payments consumers are making today, while whoever\n * sits down to WRITE a policy gets the deny-by-default one.\n */\n private readonly purchasePolicy: PurchasePolicy;\n\n constructor(config: X402ClientConfig = {}) {\n // A window that cannot be signed is refused while the client is built, not\n // on its first payment with a user waiting -- and before the RPC and chain\n // overrides below touch the shared registry.\n resolveValiditySeconds(undefined, config.validitySeconds);\n\n this.config = {\n ...DEFAULT_CONFIG,\n ...config,\n };\n\n // Apply custom RPC overrides\n if (config.rpcOverrides) {\n for (const [chainName, rpcUrl] of Object.entries(config.rpcOverrides)) {\n if (SUPPORTED_CHAINS[chainName]) {\n SUPPORTED_CHAINS[chainName].rpcUrl = rpcUrl;\n }\n }\n }\n\n // Apply custom chain configurations\n if (config.customChains) {\n for (const [chainName, chainConfig] of Object.entries(config.customChains)) {\n if (SUPPORTED_CHAINS[chainName]) {\n Object.assign(SUPPORTED_CHAINS[chainName], chainConfig);\n }\n }\n }\n\n this.purchasePolicy = config.policy ?? PurchasePolicy.permissive();\n\n this.log('X402Client initialized', { config: this.config });\n }\n\n /**\n * The policy in force, for a caller that wants to record a settled payment\n * against it with {@link PurchasePolicy.recordSpend}.\n *\n * Nothing on the payment path ever widens it.\n */\n get policy(): PurchasePolicy {\n return this.purchasePolicy;\n }\n\n // ============================================================================\n // PUBLIC API - Wallet Connection\n // ============================================================================\n\n /**\n * Connect to a wallet on the specified chain\n */\n async connect(chainName?: string): Promise<string> {\n const targetChain = chainName || this.config.defaultChain;\n const chain = getChainByName(targetChain);\n\n if (!chain) {\n throw new X402Error(`Unsupported chain: ${targetChain}`, 'CHAIN_NOT_SUPPORTED');\n }\n\n if (!chain.x402.enabled) {\n throw new X402Error(`Chain ${targetChain} is not enabled for x402 payments`, 'CHAIN_NOT_SUPPORTED');\n }\n\n this.log(`Connecting wallet on ${chain.displayName}...`);\n\n // Route to appropriate connection method based on network type\n switch (chain.networkType) {\n case 'evm':\n return this.connectEVMWallet(chain);\n case 'svm':\n // The registry says 'svm' for Solana and Fogo; this used to read\n // `case 'solana'`, which no chain has ever carried, so every SVM\n // caller fell through to `default:`. `NetworkType` allows both\n // spellings, so the compiler never caught it.\n return this.connectSVMWallet(chain);\n case 'stellar':\n throw new X402Error(\n 'Stellar support requires importing from \"uvd-x402-sdk/stellar\"',\n 'CHAIN_NOT_SUPPORTED'\n );\n case 'near':\n throw new X402Error(\n 'NEAR support requires importing from \"uvd-x402-sdk/near\"',\n 'CHAIN_NOT_SUPPORTED'\n );\n case 'hedera':\n throw new X402Error('Use HederaProvider from \"uvd-x402-sdk/hedera\" with connectWithAdapter()', 'CHAIN_NOT_SUPPORTED');\n case 'xrpl':\n throw new X402Error(\n 'XRPL support requires importing from \"uvd-x402-sdk/xrpl\"',\n 'CHAIN_NOT_SUPPORTED'\n );\n default:\n throw new X402Error(`Unknown network type for chain ${targetChain}`, 'CHAIN_NOT_SUPPORTED');\n }\n }\n\n /** Connect a native-chain adapter, e.g. HederaProvider, without an EVM wallet. */\n async connectWithAdapter(adapter: WalletAdapter, chainName: string): Promise<string> {\n const chain = getChainByName(chainName);\n if (!chain?.x402.enabled || chain.networkType !== adapter.networkType) {\n throw new X402Error('Adapter does not support the selected chain', 'CHAIN_NOT_SUPPORTED');\n }\n await this.disconnect();\n const address = await adapter.connect(chain.name);\n this.walletAdapter = adapter;\n this.connectedAddress = address;\n this.currentChainName = chain.name;\n this.currentChainId = chain.chainId;\n this.currentNetwork = chain.networkType;\n this.emit('connect', this.getState());\n return address;\n }\n\n /** Connect using a private key (Node.js / server-side, no browser wallet needed). */\n async connectWithPrivateKey(privateKey: string, chainName?: string): Promise<string> {\n const targetChain = chainName || this.config.defaultChain;\n const chain = getChainByName(targetChain);\n\n if (!chain) {\n throw new X402Error(`Unsupported chain: ${targetChain}`, 'CHAIN_NOT_SUPPORTED');\n }\n\n if (!chain.x402.enabled) {\n throw new X402Error(`Chain ${targetChain} is not enabled for x402 payments`, 'CHAIN_NOT_SUPPORTED');\n }\n\n if (chain.networkType !== 'evm') {\n throw new X402Error('connectWithPrivateKey is only supported for EVM chains', 'CHAIN_NOT_SUPPORTED');\n }\n\n this.log(`Connecting with private key on ${chain.displayName}...`);\n\n const rpcProvider = new ethers.JsonRpcProvider(chain.rpcUrl);\n const wallet = new ethers.Wallet(privateKey, rpcProvider);\n\n this.provider = rpcProvider;\n this.signer = wallet;\n this.connectedAddress = wallet.address;\n this.currentChainId = chain.chainId;\n this.currentNetwork = 'evm';\n this.currentChainName = chain.name;\n\n const state = this.getState();\n this.emit('connect', state);\n this.log('Private key wallet connected', { address: this.connectedAddress, chain: chain.name });\n\n return this.connectedAddress;\n }\n\n /**\n * Disconnect the current wallet\n */\n async disconnect(): Promise<void> {\n if (this.walletAdapter) {\n try {\n await this.walletAdapter.disconnect();\n } catch {\n // A wallet that is already gone must not block local teardown.\n }\n this.walletAdapter = null;\n }\n this.provider = null;\n this.signer = null;\n this.connectedAddress = null;\n this.currentChainId = null;\n this.currentNetwork = null;\n this.currentChainName = null;\n\n this.emit('disconnect', undefined);\n this.log('Wallet disconnected');\n }\n\n /**\n * Switch to a different chain (EVM only)\n */\n async switchChain(chainName: string): Promise<void> {\n const chain = getChainByName(chainName);\n\n if (!chain) {\n throw new X402Error(`Unsupported chain: ${chainName}`, 'CHAIN_NOT_SUPPORTED');\n }\n\n if (chain.networkType !== 'evm') {\n throw new X402Error(\n 'switchChain is only supported for EVM networks. Reconnect with connect() for other networks.',\n 'CHAIN_NOT_SUPPORTED'\n );\n }\n\n if (!this.provider) {\n throw new X402Error('Wallet not connected', 'WALLET_NOT_CONNECTED');\n }\n\n // Private key connections cannot use wallet_switchEthereumChain — re-create provider\n if (this.provider instanceof ethers.JsonRpcProvider && this.signer instanceof ethers.Wallet) {\n const rpcProvider = new ethers.JsonRpcProvider(chain.rpcUrl);\n const wallet = new ethers.Wallet(this.signer.privateKey, rpcProvider);\n this.provider = rpcProvider;\n this.signer = wallet;\n this.currentChainId = chain.chainId;\n this.currentChainName = chain.name;\n this.emit('chainChanged', { chainId: chain.chainId, chainName: chain.name });\n this.log('Switched chain (private key mode)', { chain: chain.name });\n return;\n }\n\n await this.switchEVMChain(chain);\n }\n\n // ============================================================================\n // PUBLIC API - Payment Creation\n // ============================================================================\n\n /**\n * Create a payment authorization\n *\n * @param paymentInfo - Payment information from 402 response\n * @returns Payment result with encoded X-PAYMENT header\n */\n async createPayment(paymentInfo: PaymentInfo): Promise<PaymentResult> {\n if (!this.connectedAddress) {\n throw new X402Error('Wallet not connected', 'WALLET_NOT_CONNECTED');\n }\n\n if (!this.currentChainName) {\n throw new X402Error('Chain not set', 'CHAIN_NOT_SUPPORTED');\n }\n\n const chain = getChainByName(this.currentChainName);\n if (!chain) {\n throw new X402Error(`Chain ${this.currentChainName} not found`, 'CHAIN_NOT_SUPPORTED');\n }\n\n this.emit('paymentStarted', { amount: paymentInfo.amount, network: chain.name });\n this.log('Creating payment...', { paymentInfo, chain: chain.name });\n\n try {\n // Route to appropriate payment method\n switch (chain.networkType) {\n case 'evm':\n return await this.createEVMPayment(paymentInfo, chain);\n default:\n if (this.walletAdapter?.networkType === chain.networkType) {\n return await this.createAdapterPayment(paymentInfo, chain);\n }\n throw new X402Error(\n `Payment creation for ${chain.networkType} requires the appropriate provider`,\n 'CHAIN_NOT_SUPPORTED'\n );\n }\n } catch (error) {\n const x402Error = error instanceof X402Error\n ? error\n : new X402Error(\n error instanceof Error ? error.message : 'Unknown error',\n 'PAYMENT_FAILED',\n error\n );\n\n this.emit('paymentFailed', { error: x402Error.message, code: x402Error.code });\n throw x402Error;\n }\n }\n\n\n // ============================================================================\n // PUBLIC API - Buyer loop\n // ============================================================================\n\n /**\n * Fetch a resource, paying its `402 Payment Required` challenge if it has one.\n *\n * The BUYER side of x402, and the half this client was missing: it could sign\n * a payment ({@link createPayment}) but never ask for one, so every consumer\n * hand-rolled the same loop -- probe, read `accepts`, pick, sign, retry --\n * and each one picked its own answer to \"how much is too much\".\n *\n * Safe by default: `maxAmount` is a hard ceiling. A 402 that asks for more\n * throws `PAYMENT_EXCEEDS_MAX` instead of quietly signing it. A response that\n * is not a 402 -- a first-try 200 included -- comes back untouched; this pays\n * only when payment is what was asked for.\n *\n * @param url - Resource URL.\n * @param options - See {@link X402FetchOptions}.\n * @returns The paid response after a 402, or the original response.\n *\n * @example\n * ```ts\n * await client.connectWithPrivateKey(key, 'base');\n * const res = await client.fetch('https://api.example.com/data', {\n * maxAmount: '0.05',\n * });\n * const data = await res.json();\n * ```\n */\n async fetchWithReceipt(url: string, options: ReceiptFetchOptions): Promise<FetchReceiptResult> {\n return fetchWithReceipt((target, init) => this.fetch(target, init), url, options);\n }\n\n async fetch(url: string, options: X402FetchOptions = {}): Promise<Response> {\n if (!this.connectedAddress) {\n throw new X402Error('Wallet not connected', 'WALLET_NOT_CONNECTED');\n }\n\n const method = options.method || 'GET';\n const doFetch = options.fetchImpl || globalThis.fetch;\n if (typeof doFetch !== 'function') {\n throw new X402Error(\n 'No fetch implementation available; pass options.fetchImpl',\n 'NETWORK_ERROR'\n );\n }\n\n const probe = await doFetch(url, { ...options.init, method });\n if (probe.status !== 402) {\n return probe;\n }\n\n let body: unknown;\n try {\n body = await probe.json();\n } catch (error) {\n throw new X402Error(\n `402 response body is not JSON: ${error instanceof Error ? error.message : 'unknown'}`,\n 'PAYMENT_FAILED',\n error\n );\n }\n\n const tokenType: TokenType = options.tokenType || 'usdc';\n const challenge = this.parse402(body, tokenType);\n const { version, offers } = challenge;\n if (offers.length === 0) {\n // Step 1 of the policy contract, and two different facts that used to be\n // one error. A seller that sent offers none of which this build can read is\n // asking for a scheme we do not implement; saying so names what it wanted,\n // where \"no usable payment options\" sends the caller hunting a bug in its\n // own code. A seller that sent none at all is the other fact, and keeps the\n // error it always had.\n const unreadableCount = challenge.unreadableCount ?? challenge.unreadable.length;\n if (unreadableCount > 0) {\n throw new PolicyRefusedError(noReadableOffer(challenge.unreadable));\n }\n throw new X402Error(\n '402 response offered no usable payment options',\n 'NO_ACCEPTABLE_PAYMENT'\n );\n }\n\n // The ceiling is deliberately NOT applied while selecting: if even the\n // cheapest offer is over budget the caller wants to be told the price, not\n // handed a vague \"nothing acceptable\".\n const chosen = options.select\n ? options.select(offers)\n : X402Client.cheapestOffer(offers);\n if (!chosen) {\n throw new X402Error(\n 'No payment option selected for the 402 challenge',\n 'NO_ACCEPTABLE_PAYMENT'\n );\n }\n\n if (options.maxAmount !== undefined) {\n const ceiling = ethers.parseUnits(options.maxAmount, chosen.decimals);\n if (BigInt(chosen.amount) > ceiling) {\n throw new X402Error(\n `Payment of ${ethers.formatUnits(chosen.amount, chosen.decimals)} exceeds ` +\n `maxAmount ${options.maxAmount} for ${url}`,\n 'PAYMENT_EXCEEDS_MAX',\n {\n amount: chosen.amount,\n decimals: chosen.decimals,\n maxAmount: options.maxAmount,\n }\n );\n }\n }\n\n // The policy, evaluated against THIS offer, before anything is signed. An\n // offer that diverges from a listing but sits inside an authorised policy\n // proceeds -- stopping to ask would turn every ordinary reprice into a halt --\n // and one that does not is refused with a concrete cause. The policy is never\n // widened to fit the offer, and there is no confirmation hook in this path.\n //\n // The whole challenge goes in, never just the offer: `validUntil` lives in\n // the challenge's `extensions`, and a call that takes the parts is how it gets\n // dropped.\n const decision = decideOnChallenge(this.purchasePolicy, challenge, chosen, {\n now: Math.floor(Date.now() / 1000),\n quote: options.advertised,\n });\n if (!decision.ok) {\n this.log('policy refused this offer', { cause: decision.refusal.code });\n this.emit('paymentFailed', {\n error: decision.refusal.message,\n code: 'POLICY_REFUSED',\n });\n throw new PolicyRefusedError(decision.refusal);\n }\n const approval: PolicyApproval = decision.approval;\n this.log('policy approved this offer', {\n versusQuote: approval.versusQuote.code,\n amount: String(approval.amount),\n });\n\n if (!chosen.chainName) {\n throw new X402Error(\n `402 asked for payment on unknown network '${chosen.network}'`,\n 'CHAIN_NOT_SUPPORTED'\n );\n }\n\n // The policy just approved the offer's OWN asset, but `createPayment` signs\n // for whatever token `tokenType` resolves to on this chain -- and reads the\n // price at that token's decimals. With USDC on both sides they coincide,\n // which is why this never showed. They do not have to: a seller pricing in a\n // token that is not the configured one would get an approval for asset A and\n // a signature for asset B, at B's decimals, and the caller would believe a\n // budget it never actually enforced.\n //\n // Refused rather than silently re-pointed: which token to pay with is the\n // caller's decision, and guessing it from the seller's 402 is how a wallet\n // ends up signing for a token nobody chose.\n const configuredToken = getTokenConfig(chosen.chainName, tokenType);\n if (\n chosen.asset &&\n configuredToken &&\n canonicalRecipient(configuredToken.address) !== canonicalRecipient(chosen.asset)\n ) {\n throw new X402Error(\n `402 wants ${chosen.asset} on ${chosen.chainName}, but this client signs ` +\n `${configuredToken.address} (tokenType '${tokenType}'). Pass the tokenType ` +\n 'that matches the offer; signing the configured token would pay a ' +\n 'different asset than the one that was approved.',\n 'NO_ACCEPTABLE_PAYMENT',\n {\n offered: chosen.asset,\n wouldSign: configuredToken.address,\n tokenType,\n network: chosen.chainName,\n }\n );\n }\n\n if (chosen.chainName !== this.currentChainName) {\n await this.switchChain(chosen.chainName);\n }\n\n // The window: the seller's declared `maxTimeoutSeconds` when its 402 carried\n // one, clamped to the payer's ceiling; otherwise this client's own. The\n // facilitator never rejects a long window, so signing LESS than the seller\n // declared is the failure that bites -- an authorization that dies before the\n // seller's own settle and revokes a payment that was made.\n const payment = await this.createPayment({\n accepted: chosen.raw,\n resource: { url },\n extensions: challenge.extensions as Record<string, unknown> | undefined,\n recipient: chosen.payTo,\n amount: ethers.formatUnits(chosen.amount, chosen.decimals),\n tokenType,\n network: chosen.chainName,\n x402Version: version,\n validitySeconds:\n chosen.maxTimeoutSeconds !== undefined\n ? clampValiditySeconds(chosen.maxTimeoutSeconds)\n : undefined,\n });\n\n // v1 servers read `X-PAYMENT`; v2 ones read `PAYMENT-SIGNATURE`. Both carry\n // the identical base64 payload, so sending both on a v2 retry costs nothing\n // and spares the caller from guessing which name the resource implemented.\n const paidHeaders: Record<string, string> = {\n ...X402Client.headersToRecord(options.init?.headers),\n 'X-PAYMENT': payment.paymentHeader,\n };\n if (version === 2) {\n paidHeaders['PAYMENT-SIGNATURE'] = payment.paymentHeader;\n }\n\n const paid = await doFetch(url, { ...options.init, method, headers: paidHeaders });\n\n // Approving did not spend: signing can fail and a settlement can be refused,\n // and a cumulative limit that counted attempts would lock a caller out of\n // money it never spent. A retry that came back as anything but another 402 is\n // the seller accepting the payment, which is the moment a caller records it --\n // by its own hand, in `onPaid`, never automatically here.\n if (paid.status !== 402) {\n options.onPaid?.(approval);\n }\n return paid;\n }\n\n /**\n * Normalise a 402 body into its envelope version, its payment offers, the ones\n * it could not read, and the challenge's `extensions`.\n *\n * Reads both spec shapes -- `{x402Version, accepts: [...]}` and the non-spec\n * one where a lone requirement sits at the top level -- and both dialects of\n * the price field (`maxAmountRequired` in v1, `amount` in v2).\n *\n * **`accepts` is a list, so one unreadable entry does not sink the list.** A\n * seller offering `exact` alongside a scheme this build does not implement used\n * to be unpayable in the Rust crate, and the buyer never learned there was a\n * perfectly payable offer right there. The readable ones are kept and the\n * others are counted by scheme name, so a refusal can say what the seller\n * offered instead of \"could not parse\". Discovering the service keeps working\n * even when buying it automatically does not.\n *\n * Returns the WHOLE challenge on purpose: handing `offers` alone downstream is\n * what dropped the seller's `validUntil` on the floor in Rust for a full commit\n * with every unit test green.\n */\n private parse402(\n body: unknown,\n tokenType: TokenType\n ): ReadChallenge & { version: X402Version } {\n const doc = (body ?? {}) as Record<string, unknown>;\n const version: X402Version = Number(doc.x402Version) === 2 ? 2 : 1;\n\n const rawAccepts = Array.isArray(doc.accepts)\n ? doc.accepts\n : doc.payTo\n ? [doc]\n : [];\n\n const offers: X402PaymentOffer[] = [];\n const unreadable: string[] = [];\n let unreadableCount = 0;\n\n /** Count an entry this build cannot pay, by scheme name when it has one. */\n const cannotRead = (accept: Record<string, unknown> | null) => {\n unreadableCount += 1;\n const scheme = accept?.scheme;\n if (typeof scheme === 'string' && scheme) unreadable.push(scheme);\n };\n\n for (const entry of rawAccepts) {\n if (!entry || typeof entry !== 'object') {\n cannotRead(null);\n continue;\n }\n const accept = entry as Record<string, unknown>;\n\n // The scheme first, so a well-formed offer in a scheme we cannot pay is\n // counted by the NAME the seller used -- the informative half of rule 7 --\n // instead of being reported for whichever field it also happened to omit.\n //\n // An ABSENT scheme is unreadable, not `exact`. Rust requires the field, so a\n // challenge without it fails to deserialise there, and a buyer that guessed\n // `exact` would sign under a scheme the seller never actually named -- which\n // is the same hole as signing a named one we cannot present, minus the\n // evidence. It is counted (`unreadableCount`) without a name, because it has\n // none to report.\n //\n // Note this is deliberately ASYMMETRIC with the seller side of this SDK,\n // where a missing scheme reads as `exact` (\"the default, not an override\",\n // `src/backend/index.ts`). A seller is lenient about what it accepts; a\n // buyer is strict about what it signs.\n const declaredScheme = accept.scheme;\n if (\n typeof declaredScheme !== 'string' ||\n !declaredScheme ||\n !KNOWN_SCHEMES.has(declaredScheme) ||\n !CLIENT_PAYABLE_SCHEMES.has(declaredScheme)\n ) {\n cannotRead(accept);\n continue;\n }\n\n const amount = accept.amount ?? accept.maxAmountRequired;\n const payTo = accept.payTo;\n const network = accept.network;\n if (amount === undefined || amount === null) {\n cannotRead(accept);\n continue;\n }\n if (typeof payTo !== 'string' || !payTo) {\n cannotRead(accept);\n continue;\n }\n if (typeof network !== 'string' || !network) {\n cannotRead(accept);\n continue;\n }\n\n const chainName = getChainByName(network) ? network : caip2ToChain(network);\n\n // The seller's settlement window, when it declared a usable one. Anything\n // that is not a finite number counts as NOT declared instead of making the\n // offer unreadable: price, payee and network are intact, and the client's\n // own window still applies.\n const declaredTimeout =\n typeof accept.maxTimeoutSeconds === 'number' && Number.isFinite(accept.maxTimeoutSeconds)\n ? accept.maxTimeoutSeconds\n : undefined;\n\n offers.push({\n network,\n chainName,\n asset: typeof accept.asset === 'string' ? accept.asset : undefined,\n amount: String(amount),\n decimals: X402Client.offerDecimals(chainName, tokenType),\n payTo,\n ...(declaredTimeout !== undefined ? { maxTimeoutSeconds: declaredTimeout } : {}),\n raw: accept,\n });\n }\n\n const extensions =\n doc.extensions && typeof doc.extensions === 'object' && !Array.isArray(doc.extensions)\n ? (doc.extensions as Record<string, unknown>)\n : undefined;\n\n return { version, offers, unreadable, unreadableCount, extensions };\n }\n\n /**\n * Decimals to read an offer's atomic `amount` with.\n *\n * Not cosmetic: BSC USDC has 18 and everyone else's has 6, so reading every\n * price at 6 makes one chain look 10^12 times cheaper than it is and the\n * cheapest offer gets chosen wrong. Falls back to 6 only when the chain is\n * unknown -- and an unknown chain cannot be paid anyway.\n */\n private static offerDecimals(chainName: string | null, tokenType: TokenType): number {\n if (!chainName) return 6;\n const token = getTokenConfig(chainName, tokenType);\n if (token) return token.decimals;\n return getChainByName(chainName)?.usdc.decimals ?? 6;\n }\n\n /** Cheapest offer, compared across chains at a common scale. */\n private static cheapestOffer(offers: X402PaymentOffer[]): X402PaymentOffer {\n return offers.reduce((best, offer) =>\n X402Client.scaled(offer) < X402Client.scaled(best) ? offer : best\n );\n }\n\n /** An offer's price scaled to 18 decimals, so BigInt comparison is exact. */\n private static scaled(offer: X402PaymentOffer): bigint {\n const exponent = 18 - offer.decimals;\n const value = BigInt(offer.amount);\n return exponent >= 0\n ? value * 10n ** BigInt(exponent)\n : value / 10n ** BigInt(-exponent);\n }\n\n /** Flatten whatever `HeadersInit` shape the caller passed into a record. */\n private static headersToRecord(init?: HeadersInit): Record<string, string> {\n if (!init) return {};\n if (Array.isArray(init)) return Object.fromEntries(init);\n const maybeHeaders = init as Headers;\n if (typeof maybeHeaders.forEach === 'function') {\n const out: Record<string, string> = {};\n maybeHeaders.forEach((value, key) => {\n out[key] = value;\n });\n return out;\n }\n return { ...(init as Record<string, string>) };\n }\n\n /**\n * Check USDC balance on current chain\n */\n async getBalance(): Promise<string> {\n if (!this.connectedAddress || !this.currentChainName) {\n throw new X402Error('Wallet not connected', 'WALLET_NOT_CONNECTED');\n }\n\n const chain = getChainByName(this.currentChainName);\n if (!chain) {\n throw new X402Error(`Chain ${this.currentChainName} not found`, 'CHAIN_NOT_SUPPORTED');\n }\n\n switch (chain.networkType) {\n case 'evm':\n return this.getEVMBalance(chain);\n default:\n if (this.walletAdapter?.networkType === chain.networkType) {\n return this.walletAdapter.getBalance(chain);\n }\n throw new X402Error(\n `Balance check for ${chain.networkType} requires the appropriate provider`,\n 'CHAIN_NOT_SUPPORTED'\n );\n }\n }\n\n // ============================================================================\n // PUBLIC API - Getters\n // ============================================================================\n\n /**\n * Get current wallet state\n */\n getState(): WalletState {\n return {\n connected: this.connectedAddress !== null,\n address: this.connectedAddress,\n chainId: this.currentChainId,\n network: this.currentChainName,\n networkType: this.currentNetwork,\n balance: null, // Call getBalance() separately\n };\n }\n\n /**\n * Get connected wallet address\n */\n getAddress(): string | null {\n return this.connectedAddress;\n }\n\n /**\n * Get current chain ID\n */\n getChainId(): number | null {\n return this.currentChainId;\n }\n\n /**\n * Get current chain name\n */\n getChainName(): string | null {\n return this.currentChainName;\n }\n\n /**\n * Get current chain display name\n */\n getChainDisplayName(): string | null {\n if (!this.currentChainName) return null;\n const chain = getChainByName(this.currentChainName);\n return chain?.displayName ?? null;\n }\n\n /**\n * Check if wallet is connected\n */\n isConnected(): boolean {\n return this.connectedAddress !== null;\n }\n\n /**\n * Get list of enabled chains\n */\n getEnabledChains(): ChainConfig[] {\n return getEnabledChains();\n }\n\n /**\n * Get chain config by name\n */\n getChain(name: string): ChainConfig | undefined {\n return getChainByName(name);\n }\n\n // ============================================================================\n // PUBLIC API - Events\n // ============================================================================\n\n /**\n * Subscribe to an event\n */\n on<E extends X402Event>(event: E, handler: X402EventHandler<E>): () => void {\n if (!this.eventHandlers.has(event)) {\n this.eventHandlers.set(event, new Set());\n }\n this.eventHandlers.get(event)!.add(handler as X402EventHandler<X402Event>);\n\n // Return unsubscribe function\n return () => this.off(event, handler);\n }\n\n /**\n * Unsubscribe from an event\n */\n off<E extends X402Event>(event: E, handler: X402EventHandler<E>): void {\n this.eventHandlers.get(event)?.delete(handler as X402EventHandler<X402Event>);\n }\n\n // ============================================================================\n // PRIVATE - EVM Wallet Connection\n // ============================================================================\n\n /**\n * Connect an SVM chain (Solana, Fogo) through the Phantom-backed provider.\n *\n * The provider is imported lazily: `@solana/web3.js` and `@solana/spl-token`\n * are OPTIONAL peer dependencies, so an EVM-only consumer must never pay for\n * them at module load. They are resolved only once someone actually asks for\n * an SVM chain.\n */\n private async connectSVMWallet(chain: ChainConfig): Promise<string> {\n const { SVMProvider } = await import('../providers/solana');\n const adapter = new SVMProvider();\n\n // SVMProvider.connect() takes no chain: one Phantom session serves every\n // SVM chain, and the chain is passed per call via chainConfig.\n const address = await adapter.connect();\n\n this.walletAdapter = adapter;\n this.provider = null;\n this.signer = null;\n this.connectedAddress = address;\n this.currentChainId = chain.chainId;\n this.currentNetwork = chain.networkType;\n this.currentChainName = chain.name;\n\n const state = this.getState();\n this.emit('connect', state);\n this.log('SVM wallet connected', { address, chain: chain.name });\n\n return address;\n }\n\n private async connectEVMWallet(chain: ChainConfig): Promise<string> {\n // Check for injected provider\n if (typeof window === 'undefined' || !window.ethereum) {\n throw new X402Error(\n 'No Ethereum wallet found. Please install MetaMask or another EVM wallet.',\n 'WALLET_NOT_FOUND'\n );\n }\n\n try {\n this.provider = new ethers.BrowserProvider(window.ethereum);\n\n // Request account access\n await this.provider.send('eth_requestAccounts', []);\n\n // Switch to target chain\n await this.switchEVMChain(chain);\n\n // Get signer and address\n this.signer = await this.provider.getSigner();\n this.connectedAddress = await this.signer.getAddress();\n this.currentChainId = chain.chainId;\n this.currentNetwork = 'evm';\n this.currentChainName = chain.name;\n\n // Setup event listeners\n this.setupEVMEventListeners();\n\n const state = this.getState();\n this.emit('connect', state);\n this.log('EVM wallet connected', { address: this.connectedAddress, chain: chain.name });\n\n return this.connectedAddress;\n } catch (error: unknown) {\n if (error instanceof Error) {\n if (error.message.includes('User rejected') || (error as { code?: number }).code === 4001) {\n throw new X402Error('Connection rejected by user', 'WALLET_CONNECTION_REJECTED');\n }\n }\n throw new X402Error(\n `Failed to connect wallet: ${error instanceof Error ? error.message : 'Unknown error'}`,\n 'UNKNOWN_ERROR',\n error\n );\n }\n }\n\n private async switchEVMChain(chain: ChainConfig): Promise<void> {\n if (!this.provider) {\n throw new X402Error('Wallet not connected', 'WALLET_NOT_CONNECTED');\n }\n\n try {\n await this.provider.send('wallet_switchEthereumChain', [{ chainId: chain.chainIdHex }]);\n } catch (switchError: unknown) {\n // Chain not added - try to add it\n if ((switchError as { code?: number }).code === 4902) {\n try {\n await this.provider.send('wallet_addEthereumChain', [\n {\n chainId: chain.chainIdHex,\n chainName: chain.displayName,\n nativeCurrency: chain.nativeCurrency,\n rpcUrls: [chain.rpcUrl],\n blockExplorerUrls: [chain.explorerUrl],\n },\n ]);\n } catch (addError) {\n throw new X402Error(\n `Failed to add ${chain.displayName} network`,\n 'CHAIN_SWITCH_REJECTED',\n addError\n );\n }\n } else if ((switchError as { code?: number }).code === 4001) {\n throw new X402Error('Network switch rejected by user', 'CHAIN_SWITCH_REJECTED');\n } else {\n throw new X402Error(\n `Failed to switch to ${chain.displayName}`,\n 'CHAIN_SWITCH_REJECTED',\n switchError\n );\n }\n }\n\n this.currentChainId = chain.chainId;\n this.currentChainName = chain.name;\n this.emit('chainChanged', { chainId: chain.chainId, chainName: chain.name });\n }\n\n private setupEVMEventListeners(): void {\n if (typeof window === 'undefined' || !window.ethereum) return;\n\n window.ethereum.on?.('accountsChanged', ((...args: unknown[]) => {\n const accounts = args[0] as string[];\n if (accounts.length === 0) {\n this.disconnect();\n } else if (accounts[0] !== this.connectedAddress) {\n this.connectedAddress = accounts[0];\n this.emit('accountChanged', { address: accounts[0] });\n }\n }) as (...args: unknown[]) => void);\n\n window.ethereum.on?.('chainChanged', ((...args: unknown[]) => {\n const chainIdHex = args[0] as string;\n const chainId = parseInt(chainIdHex, 16);\n const chain = getChainById(chainId);\n if (chain) {\n this.currentChainId = chainId;\n this.currentChainName = chain.name;\n this.emit('chainChanged', { chainId, chainName: chain.name });\n }\n }) as (...args: unknown[]) => void);\n }\n\n // ============================================================================\n // PRIVATE - EVM Payment Creation\n // ============================================================================\n\n private async createEVMPayment(paymentInfo: PaymentInfo, chain: ChainConfig): Promise<PaymentResult> {\n if (!this.signer) {\n throw new X402Error('Wallet not connected', 'WALLET_NOT_CONNECTED');\n }\n\n // Get recipient address for EVM\n const recipient = this.getRecipientForNetwork(paymentInfo, 'evm');\n\n // Validate recipient address - prevents empty/invalid addresses\n validateRecipient(recipient, 'evm');\n\n // Which stablecoin to charge. Defaults to USDC so existing callers are\n // unaffected; anything else is resolved from the chain's token registry.\n const tokenType: TokenType = paymentInfo.tokenType || 'usdc';\n const token = getTokenConfig(chain.name, tokenType);\n if (!token) {\n throw new X402Error(\n `Token ${tokenType} not supported on ${chain.name}`,\n 'CHAIN_NOT_SUPPORTED'\n );\n }\n\n // Generate random nonce\n const nonceBytes = new Uint8Array(32);\n if (typeof window !== 'undefined' && window.crypto) {\n window.crypto.getRandomValues(nonceBytes);\n } else {\n for (let i = 0; i < 32; i++) {\n nonceBytes[i] = Math.floor(Math.random() * 256);\n }\n }\n const nonce = ethers.hexlify(nonceBytes);\n\n // How long this authorization stays settleable. Per payment first, then the\n // client's default, then 300 s -- see `resolveValiditySeconds`.\n const validAfter = 0;\n const validityWindowSeconds = resolveValiditySeconds(\n paymentInfo.validitySeconds,\n this.config.validitySeconds\n );\n const validBefore = Math.floor(Date.now() / 1000) + validityWindowSeconds;\n\n // EIP-712 domain of the token being charged\n const domain = {\n name: token.name,\n version: token.version,\n chainId: chain.chainId,\n verifyingContract: token.address,\n };\n\n // EIP-712 types for TransferWithAuthorization (ERC-3009)\n const types = {\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 };\n\n // Parse amount in the token's own decimals\n const value = ethers.parseUnits(paymentInfo.amount, token.decimals);\n const from = await this.signer.getAddress();\n const to = ethers.getAddress(recipient);\n\n // Message to sign\n const message = {\n from,\n to,\n value,\n validAfter,\n validBefore,\n nonce,\n };\n\n this.log('Signing EIP-712 message...', { domain, message });\n\n // Sign the EIP-712 message\n let signature: string;\n try {\n signature = await this.signer.signTypedData(domain, types, message);\n } catch (error: unknown) {\n if (error instanceof Error && (error.message.includes('User rejected') || (error as { code?: number }).code === 4001)) {\n throw new X402Error('Signature rejected by user', 'SIGNATURE_REJECTED');\n }\n throw new X402Error(\n `Failed to sign payment: ${error instanceof Error ? error.message : 'Unknown error'}`,\n 'PAYMENT_FAILED',\n error\n );\n }\n\n const sig = ethers.Signature.from(signature);\n\n // Construct payload\n const payload: EVMPaymentPayload = {\n from,\n to,\n value: value.toString(),\n validAfter,\n validBefore,\n nonce,\n v: sig.v,\n r: sig.r,\n s: sig.s,\n chainId: chain.chainId,\n token: token.address,\n };\n\n // Encode as X-PAYMENT header. The 402 wins over the config when it spoke:\n // `x402Version: 'auto'` means \"whatever the resource asked for\".\n const paymentHeader = this.encodeEVMPaymentHeader(\n payload,\n chain,\n paymentInfo.x402Version\n );\n\n this.emit('paymentSigned', { paymentHeader });\n\n const result: PaymentResult = {\n success: true,\n paymentHeader,\n headers: {\n 'X-PAYMENT': paymentHeader,\n 'PAYMENT-SIGNATURE': paymentHeader,\n },\n network: chain.name,\n payer: from,\n };\n\n this.emit('paymentCompleted', result);\n this.log('Payment created successfully', { network: chain.name, from });\n\n return result;\n }\n\n /**\n * Build a payment through a non-EVM {@link WalletAdapter}.\n *\n * The adapter signs and returns its own payload; encoding that payload into\n * the X-PAYMENT header is network-specific, so it stays with the provider\n * that produced it. Version resolution matches the EVM path exactly: a hint\n * read off the resource's own 402 wins over the client config.\n */\n private async createAdapterPayment(\n paymentInfo: PaymentInfo,\n chain: ChainConfig\n ): Promise<PaymentResult> {\n const adapter = this.walletAdapter;\n if (!adapter) {\n throw new X402Error('Wallet not connected', 'WALLET_NOT_CONNECTED');\n }\n\n const encode = (adapter as { encodePaymentHeader?: (p: string, c: ChainConfig, v: X402Version) => string })\n .encodePaymentHeader;\n if (typeof encode !== 'function') {\n throw new X402Error(\n `The ${adapter.name} adapter cannot encode an X-PAYMENT header`,\n 'CHAIN_NOT_SUPPORTED'\n );\n }\n\n const version = paymentInfo.x402Version ?? (chain.networkType === 'hedera' ? 2 : this.config.x402Version === 2 ? 2 : 1);\n const signed = await adapter.signPayment({ ...paymentInfo, x402Version: version }, chain);\n const paymentHeader = encode.call(adapter, signed, chain, version);\n\n this.emit('paymentSigned', { paymentHeader });\n\n const result: PaymentResult = {\n success: true,\n paymentHeader,\n headers: {\n 'X-PAYMENT': paymentHeader,\n 'PAYMENT-SIGNATURE': paymentHeader,\n },\n network: chain.name,\n payer: adapter.getAddress() ?? undefined,\n };\n\n this.emit('paymentCompleted', result);\n this.log('Payment created successfully', { network: chain.name, adapter: adapter.name });\n\n return result;\n }\n\n private encodeEVMPaymentHeader(\n payload: EVMPaymentPayload,\n chain: ChainConfig,\n versionHint?: X402Version\n ): string {\n // Reconstruct full signature from v, r, s\n const fullSignature = payload.r + payload.s.slice(2) + payload.v.toString(16).padStart(2, '0');\n\n // Determine version to use. A hint read off the resource's own 402 wins;\n // with no hint we fall back to the config (default v1 for compatibility).\n const version = versionHint ?? (this.config.x402Version === 2 ? 2 : 1);\n\n // Build the payload data\n const payloadData: X402EVMPayload = {\n signature: fullSignature,\n authorization: {\n from: payload.from,\n to: payload.to,\n value: payload.value,\n validAfter: payload.validAfter.toString(),\n validBefore: payload.validBefore.toString(),\n nonce: payload.nonce,\n },\n };\n\n if (this.config.includeTokenMetadata) {\n const token = buildTokenMetadata(chain.name, payload.token);\n if (!token) {\n throw new X402Error(\n `Token ${payload.token} is not in the registry for ${chain.name}; cannot build token metadata`,\n 'CHAIN_NOT_SUPPORTED'\n );\n }\n payloadData.token = token;\n }\n\n // Format in x402 standard format (v1 or v2)\n const x402Payload = version === 2\n ? {\n x402Version: 2 as const,\n scheme: 'exact' as const,\n network: chainToCAIP2(chain.name), // CAIP-2 format for v2\n payload: payloadData,\n }\n : {\n x402Version: 1 as const,\n scheme: 'exact' as const,\n network: chain.name, // Plain chain name for v1\n payload: payloadData,\n };\n\n // Base64 encode (UTF-8 safe: token domain names like `USD₮0` are not ASCII)\n return encodeBase64Json(x402Payload);\n }\n\n // ============================================================================\n // PRIVATE - EVM Balance Check\n // ============================================================================\n\n private async getEVMBalance(chain: ChainConfig): Promise<string> {\n // Use public RPC for balance check (more reliable than wallet provider)\n const publicProvider = new ethers.JsonRpcProvider(chain.rpcUrl);\n\n const usdcAbi = ['function balanceOf(address owner) view returns (uint256)'];\n const usdcContract = new ethers.Contract(chain.usdc.address, usdcAbi, publicProvider);\n\n try {\n const balance = await usdcContract.balanceOf(this.connectedAddress);\n const formatted = ethers.formatUnits(balance, chain.usdc.decimals);\n return parseFloat(formatted).toFixed(2);\n } catch {\n return '0.00';\n }\n }\n\n // ============================================================================\n // PRIVATE - Utilities\n // ============================================================================\n\n private getRecipientForNetwork(paymentInfo: PaymentInfo, network: NetworkType): string {\n // Map SVM to solana for recipient lookup\n const lookupNetwork = network === 'svm' ? 'solana' : network;\n const recipients = paymentInfo.recipients as Record<string, string> | undefined;\n if (recipients?.[lookupNetwork]) {\n return recipients[lookupNetwork];\n }\n return paymentInfo.recipient;\n }\n\n private emit<E extends X402Event>(event: E, data: X402EventData[E]): void {\n this.eventHandlers.get(event)?.forEach(handler => {\n try {\n handler(data);\n } catch (error) {\n console.error(`Error in ${event} handler:`, error);\n }\n });\n }\n\n private log(message: string, data?: unknown): void {\n if (this.config.debug) {\n console.log(`[X402Client] ${message}`, data ?? '');\n }\n }\n}\n\n// Type augmentation for window.ethereum\ndeclare global {\n interface Window {\n ethereum?: {\n request: (args: { method: string; params?: unknown[] }) => Promise<unknown>;\n on?: (event: string, handler: (...args: unknown[]) => void) => void;\n removeListener?: (event: string, handler: (...args: unknown[]) => void) => void;\n };\n }\n}\n","/**\n * uvd-x402-sdk - What this buyer is allowed to sign, decided before it signs.\n *\n * # The rule this module exists to enforce\n *\n * A catalog listing is a claim somebody else made about their own price. The\n * `402` that comes back from the actual request is the offer. They can differ,\n * legitimately: a seller may have repriced, and the listing may be a copy of a\n * copy. So the buying decision cannot be made against the listing. It has to be\n * made against **the offer in hand**, every time, before anything is signed.\n *\n * Two things follow, and both are load-bearing:\n *\n * - **A divergence from the listing is not, by itself, a refusal.** If the offer\n * costs more than the catalog said but still sits inside a policy the operator\n * already authorised, the payment proceeds. Stopping to ask would turn every\n * ordinary reprice into a halt, and an agent that halts on ordinary commerce\n * is an agent nobody can leave running. There is no human-confirmation hook in\n * this path.\n * - **A policy is never widened to fit an offer.** Not by a byte, not once, not\n * \"because the seller says so\". There is deliberately no method on this type\n * that raises a limit from inside an evaluation. If the offer exceeds what was\n * authorised the answer is a refusal with a concrete cause, and the caller\n * decides whether to authorise more.\n *\n * # Order of evaluation\n *\n * Fixed, and part of the contract, because the FIRST failing check is the one\n * reported and a caller branches on it:\n *\n * 1. Was any offer readable at all? -> `no-readable-offer`\n * 2. Has it expired? -> `offer-expired`\n * 3. Is the recipient one we are willing to pay? -> `recipient-not-permitted`\n * 4. Was its asset budgeted at all? -> `asset-not-budgeted`\n * 5. Does it exceed the per-payment limit for that asset? -> `per-payment-limit`\n * 6. Does it exceed what remains of the cumulative limit? -> `cumulative-limit`\n *\n * The comparison against the listing is made LAST and refuses nothing: it is\n * evidence for the caller, never a gate.\n *\n * This is the same contract the Rust facilitator's `x402-reqwest` crate\n * implements (`PurchasePolicy`, release 2.25.0), written down once so a buyer in\n * either language refuses the same payments for the same stated reasons.\n *\n * @module\n */\n\nimport { X402Error } from './types';\nimport type { X402PaymentOffer } from './types';\n\n// ============================================================================\n// The offer-validity extension\n// ============================================================================\n\n/**\n * Extension key under which a seller declares how long its offer stands.\n *\n * Defined once, here, and read by nobody else's constant: a seller and a buyer\n * naming different keys have nothing to say to each other. The version is IN\n * the key because the offer-and-receipt transport can still change, and a value\n * read from an unversioned key could never be compared with anything later. A\n * key we do not recognise is ignored, which means \"no declared expiry\" -- a\n * different thing from \"expired\".\n */\nexport const OFFER_VALIDITY_EXTENSION = 'offer-receipt/1';\n\n/**\n * Read `validUntil` (Unix seconds) out of a 402 challenge's `extensions`.\n *\n * Shape: `extensions[\"offer-receipt/1\"].info.validUntil`. The `{info, schema}`\n * envelope is the one every merged x402 extension uses; reading the number from\n * anywhere else would be reading a field nobody agreed to publish.\n *\n * Anything unreadable is `undefined`, **never zero**: \"the seller said\n * something we could not read\" must not become \"this offer expired in 1970\".\n * A string, a float, a negative, a number past `Number.MAX_SAFE_INTEGER` -- all\n * unreadable, all absent.\n */\nexport function offerValidUntil(\n extensions: Record<string, unknown> | undefined | null\n): number | undefined {\n if (!extensions || typeof extensions !== 'object') return undefined;\n const entry = (extensions as Record<string, unknown>)[OFFER_VALIDITY_EXTENSION];\n if (!entry || typeof entry !== 'object') return undefined;\n const info = (entry as Record<string, unknown>).info;\n if (!info || typeof info !== 'object') return undefined;\n const value = (info as Record<string, unknown>).validUntil;\n if (typeof value !== 'number') return undefined;\n if (!Number.isSafeInteger(value) || value < 0) return undefined;\n return value;\n}\n\n// ============================================================================\n// Addresses\n// ============================================================================\n\n/**\n * Canonical form of a recipient or token address, for comparison.\n *\n * # Why this is not `toLowerCase()`\n *\n * It was, in the Rust crate, and that is only correct for one family. EVM\n * addresses are hex and arrive both checksummed and lowercase, so folding case\n * is right and necessary. **Base58 is case-sensitive** -- Solana and XRPL\n * addresses use both cases as distinct symbols -- so lowercasing one does not\n * produce the same address spelled differently, it produces a string that is not\n * an address.\n *\n * An allowlist written in the seller's own spelling would then never match, and\n * every payment to a legitimate Solana payee would be refused with\n * `recipient-not-permitted`. Worse in the other direction: two distinct base58\n * addresses can fold to the same lowercase string, so an allowlist could admit\n * an address nobody put on it.\n *\n * So: hex is folded, everything else is compared exactly.\n */\nexport function canonicalRecipient(address: string): string {\n const trimmed = address.trim();\n const rest =\n trimmed.startsWith('0x') || trimmed.startsWith('0X') ? trimmed.slice(2) : null;\n const isHex = rest !== null && rest.length > 0 && /^[0-9a-fA-F]+$/.test(rest);\n return isHex ? trimmed.toLowerCase() : trimmed;\n}\n\n// ============================================================================\n// Assets\n// ============================================================================\n\n/**\n * A token on a network -- the unit a budget is denominated in.\n *\n * Both halves are required. The same USDC contract address on two networks is\n * two different assets, and a budget for one is not a budget for the other: the\n * EVM signer takes its EIP-712 domain from the seller's own `extra`, so it will\n * sign for whatever token and network the seller names.\n */\nexport interface PolicyAsset {\n /**\n * SDK chain name (`'base'`) when the 402's network resolved to one, otherwise\n * the network string exactly as the 402 wrote it.\n *\n * Resolving first is what lets one written policy cover both 402 dialects:\n * a v1 challenge says `base` and a v2 one says `eip155:8453`, and a budget\n * keyed on the raw string would silently miss half of a seller's offers.\n */\n network: string;\n /** Token contract address. Compared canonicalised, never raw. */\n address: string;\n}\n\n/**\n * Stable map key for an asset. Not part of the wire format; comparison only.\n *\n * The network is folded to lowercase because SDK chain names and CAIP-2 strings\n * are lowercase by convention, so `'Base'` and `'base'` are the same network\n * written two ways -- never two networks. Leaving the case in fails closed\n * (`asset-not-budgeted`, so no wrong payment), but it trips the operator over a\n * capital letter and the refusal would point at the budget instead of the typo.\n * The address keeps its by-family treatment: see {@link canonicalRecipient}.\n */\nexport function assetKey(asset: PolicyAsset): string {\n return `${asset.network.trim().toLowerCase()}|${canonicalRecipient(asset.address)}`;\n}\n\n/** Human form, for a refusal message. */\nfunction assetLabel(asset: PolicyAsset): string {\n return asset.address ? `${asset.address} on ${asset.network}` : `(no asset declared) on ${asset.network}`;\n}\n\n/**\n * The asset an offer is priced in.\n *\n * An offer that declares no `asset` yields an empty address, which no budget can\n * ever hold -- {@link PurchasePolicy.perPayment} rejects an empty address -- so\n * such an offer is refused with `asset-not-budgeted` unless unlisted assets were\n * explicitly permitted. That is the safe direction: an unnamed token is a token\n * nobody budgeted for.\n */\nexport function offerAsset(offer: X402PaymentOffer): PolicyAsset {\n return {\n network: offer.chainName ?? offer.network,\n address: typeof offer.asset === 'string' ? offer.asset : '',\n };\n}\n\n// ============================================================================\n// Refusals\n// ============================================================================\n\n/**\n * Closed vocabulary of reasons a payment was not signed, in kebab-case, so an\n * SDK in another language branches on it without parsing English.\n *\n * There is no `other`: a refusal a caller cannot interpret is a refusal it will\n * paper over.\n */\nexport type PolicyRefusalCode =\n | 'no-readable-offer'\n | 'offer-expired'\n | 'recipient-not-permitted'\n | 'asset-not-budgeted'\n | 'per-payment-limit'\n | 'cumulative-limit';\n\n/**\n * Why a payment was not signed. Every variant carries the numbers that caused\n * it, so a caller can log the decision without re-deriving it.\n */\nexport type PolicyRefusal =\n | {\n code: 'no-readable-offer';\n /** Scheme names the seller offered, for the ones this build cannot read. */\n offered: string[];\n message: string;\n }\n | { code: 'offer-expired'; validUntil: number; now: number; message: string }\n | { code: 'recipient-not-permitted'; payTo: string; message: string }\n | { code: 'asset-not-budgeted'; asset: PolicyAsset; message: string }\n | {\n code: 'per-payment-limit';\n requested: bigint;\n allowed: bigint;\n asset: PolicyAsset;\n message: string;\n }\n | {\n code: 'cumulative-limit';\n requested: bigint;\n spent: bigint;\n wouldTotal: bigint;\n allowed: bigint;\n asset: PolicyAsset;\n message: string;\n };\n\n/**\n * A 402 whose offers this build could not read, turned into a refusal that says\n * so.\n *\n * The point is the message. A caller that learns the seller offered\n * `batch-settlement` knows to look for a facilitator that implements it, where\n * \"could not parse the response\" would have sent it looking for a bug in its own\n * code. Discovering the service keeps working even though buying it\n * automatically does not.\n */\nexport function noReadableOffer(offered: string[]): PolicyRefusal {\n return {\n code: 'no-readable-offer',\n offered,\n message:\n 'no offer in this challenge is one this build can pay; offered: ' +\n JSON.stringify(offered),\n };\n}\n\n/**\n * Error thrown on the real payment path when the policy refuses.\n *\n * Extends {@link X402Error}, so a consumer already catching `X402Error` keeps\n * catching this; the typed cause is on {@link PolicyRefusedError.refusal} and\n * its stable code on `refusal.code`.\n */\nexport class PolicyRefusedError extends X402Error {\n public readonly refusal: PolicyRefusal;\n\n constructor(refusal: PolicyRefusal) {\n super(`payment refused by policy: ${refusal.message}`, 'POLICY_REFUSED', refusal);\n this.name = 'PolicyRefusedError';\n this.refusal = refusal;\n }\n\n /** Stable kebab code of the refusal, for branching. */\n get policyCode(): PolicyRefusalCode {\n return this.refusal.code;\n }\n}\n\n// ============================================================================\n// The listing, and how the offer compares to it\n// ============================================================================\n\n/**\n * What a catalog listing advertised, for comparison against the real offer.\n *\n * Optional throughout. A buyer that never read a listing simply evaluates the\n * offer against its policy, which is the same decision with one fewer input.\n */\nexport interface AdvertisedQuote {\n asset: PolicyAsset;\n /** Price in the token's own atomic units. */\n amount: bigint;\n}\n\n/** How the offer in hand compares to what the catalog advertised. */\nexport type QuoteComparison =\n | { code: 'not-compared' }\n | { code: 'matches' }\n | { code: 'amount-differs'; advertised: bigint; offered: bigint }\n /**\n * A different asset entirely. The same number in another currency is not the\n * same price, so there is nothing to compare -- and no number is compared.\n */\n | { code: 'different-asset'; advertised: PolicyAsset; offered: PolicyAsset };\n\n/** A payment this policy permits, and what it noticed on the way. */\nexport interface PolicyApproval {\n asset: PolicyAsset;\n /** Price in the token's own atomic units. */\n amount: bigint;\n /**\n * How the offer compared to the listing, when there was one. Carried so a\n * caller can log or surface it; it never changed the decision.\n */\n versusQuote: QuoteComparison;\n}\n\n/** The outcome of an evaluation. Explicit, so no caller needs a `try`. */\nexport type PolicyDecision =\n | { ok: true; approval: PolicyApproval }\n | { ok: false; refusal: PolicyRefusal };\n\n/** Inputs to {@link PurchasePolicy.evaluate} besides the offer itself. */\nexport interface EvaluateOptions {\n /**\n * Unix seconds. Passed rather than read so the decision is testable at an\n * exact instant: money decisions that depend on a hidden clock cannot be\n * pinned.\n */\n now: number;\n /** `validUntil` the seller declared, if any. See {@link offerValidUntil}. */\n validUntil?: number;\n /** What the catalog advertised, if the caller read a listing. */\n quote?: AdvertisedQuote;\n}\n\n// ============================================================================\n// The policy\n// ============================================================================\n\n/**\n * The spending rules a caller authorised in advance.\n *\n * Every builder returns a new policy that **shares the running total**: two\n * copies of one policy spend from the same purse, which is what makes a\n * cumulative limit mean anything when a client is copied per request.\n *\n * @example\n * ```ts\n * const USDC_BASE = { network: 'base', address: '0x8335...2913' };\n * const policy = PurchasePolicy.create()\n * .perPayment(USDC_BASE, 50_000n) // 0.05 USDC, atomic units\n * .cumulative(USDC_BASE, 1_000_000n) // 1 USDC total, for this policy's life\n * .onlyPay(['0xe4dc...e545']);\n *\n * const client = new X402Client({ defaultChain: 'base', policy });\n * ```\n */\nexport class PurchasePolicy {\n private readonly perPaymentLimits: Map<string, bigint>;\n private readonly cumulativeLimits: Map<string, bigint>;\n /** Shared by reference across every copy: one purse, many holders. */\n private readonly spentTotals: Map<string, bigint>;\n private readonly recipients: Set<string> | null;\n private readonly assetsByKey: Map<string, PolicyAsset>;\n private readonly unlistedAssetsAllowed: boolean;\n\n private constructor(\n perPaymentLimits: Map<string, bigint>,\n cumulativeLimits: Map<string, bigint>,\n spentTotals: Map<string, bigint>,\n recipients: Set<string> | null,\n assetsByKey: Map<string, PolicyAsset>,\n unlistedAssetsAllowed: boolean\n ) {\n this.perPaymentLimits = perPaymentLimits;\n this.cumulativeLimits = cumulativeLimits;\n this.spentTotals = spentTotals;\n this.recipients = recipients;\n this.assetsByKey = assetsByKey;\n this.unlistedAssetsAllowed = unlistedAssetsAllowed;\n }\n\n /**\n * A policy that pays nothing until it is told what it may pay.\n *\n * # Why the default is deny\n *\n * The limits are a map keyed by asset, and a map answers \"no entry\" for every\n * asset nobody thought of. Permitting on a missing entry means a budget in\n * USDC is **no budget at all** for any other token: a seller offering the same\n * resource priced in something unlisted walks straight past the ceiling, and\n * the wallet will sign it, because the EVM signer takes the EIP-712 domain\n * from the seller's own `extra` and will happily sign for a token and a\n * network it has never heard of.\n *\n * So an asset with no stated ceiling is refused. A caller that genuinely wants\n * to pay anything says so once, by name, with\n * {@link PurchasePolicy.allowUnlistedAssets}, and that sentence is then in\n * their code where a reader can find it.\n */\n static create(): PurchasePolicy {\n return new PurchasePolicy(new Map(), new Map(), new Map(), null, new Map(), false);\n }\n\n /**\n * A policy that permits an asset it was never told about.\n *\n * This is what {@link X402Client} holds when the caller supplied no policy,\n * and it exists for exactly one reason: this SDK had no budget before 2.89.0,\n * and turning one on silently would refuse payments that callers are making\n * today. Named rather than defaulted, so choosing it is visible. The asymmetry\n * is deliberate -- whoever sits down to WRITE a policy deserves the safe\n * default.\n */\n static permissive(): PurchasePolicy {\n return new PurchasePolicy(new Map(), new Map(), new Map(), null, new Map(), true);\n }\n\n /** Permit assets with no configured ceiling. */\n allowUnlistedAssets(): PurchasePolicy {\n return this.with({ unlistedAssetsAllowed: true });\n }\n\n /**\n * Refuse assets with no configured ceiling. The default; here so the intent\n * can be written down at a call site that wants it explicit.\n */\n denyUnlistedAssets(): PurchasePolicy {\n return this.with({ unlistedAssetsAllowed: false });\n }\n\n /** Most this policy will pay in ONE payment of `asset`, in atomic units. */\n perPayment(asset: PolicyAsset, amount: bigint): PurchasePolicy {\n const key = this.register(asset);\n const perPaymentLimits = new Map(this.perPaymentLimits);\n perPaymentLimits.set(key, requireCeiling(amount, 'perPayment'));\n return this.with({ perPaymentLimits });\n }\n\n /**\n * Most this policy will pay in `asset` in TOTAL, across every payment it\n * approves for as long as it lives.\n */\n cumulative(asset: PolicyAsset, amount: bigint): PurchasePolicy {\n const key = this.register(asset);\n const cumulativeLimits = new Map(this.cumulativeLimits);\n cumulativeLimits.set(key, requireCeiling(amount, 'cumulative'));\n return this.with({ cumulativeLimits });\n }\n\n /**\n * Restrict payment to a set of recipients.\n *\n * Addresses are canonicalised **by family**, not by lowercasing the string:\n * see {@link canonicalRecipient}.\n */\n onlyPay(recipients: Iterable<string>): PurchasePolicy {\n const set = new Set<string>();\n for (const r of recipients) set.add(canonicalRecipient(r));\n return this.with({ recipients: set });\n }\n\n /**\n * Total recorded so far for `asset`, in atomic units.\n *\n * A total that is not a sane bigint means something corrupted the purse.\n * Reporting zero would silently restore the caller's whole budget, so this\n * reports the CEILING instead: for money, the safe direction is to refuse,\n * never to permit.\n */\n spent(asset: PolicyAsset): bigint {\n const key = assetKey(asset);\n const value = this.spentTotals.get(key);\n if (value === undefined) return 0n;\n if (typeof value !== 'bigint' || value < 0n) {\n return this.cumulativeLimits.get(key) ?? 0n;\n }\n return value;\n }\n\n /**\n * Record that a payment actually happened.\n *\n * Separate from {@link PurchasePolicy.evaluate} on purpose. Signing can still\n * fail and a settlement can still be refused; a cumulative limit that counted\n * attempts rather than payments would lock a caller out of money it never\n * spent. Call this when a payment settled.\n *\n * A negative amount is ignored: handing budget back is not something a\n * settlement can do, and treating it as one would be a way to widen a policy\n * from outside.\n */\n recordSpend(asset: PolicyAsset, amount: bigint): void {\n if (typeof amount !== 'bigint' || amount <= 0n) return;\n const key = assetKey(asset);\n if (!this.assetsByKey.has(key)) this.assetsByKey.set(key, asset);\n const current = this.spent(asset);\n this.spentTotals.set(key, current + amount);\n }\n\n /**\n * Whether this policy pays an asset it holds no ceiling for. Read-only: there\n * is no setter that flips it from inside an evaluation.\n */\n get permitsUnlistedAssets(): boolean {\n return this.unlistedAssetsAllowed;\n }\n\n /**\n * Decide whether this offer may be signed. Steps 2 through 6 of the contract;\n * step 1 (`no-readable-offer`) is decided on the challenge, before an offer\n * exists to evaluate -- see {@link decideOnChallenge}.\n *\n * **Approving does not record the spend.** See\n * {@link PurchasePolicy.recordSpend}.\n */\n evaluate(offer: X402PaymentOffer, options: EvaluateOptions): PolicyDecision {\n const { now, validUntil, quote } = options;\n\n // 2. Expiry. Before anything about money: terms that have lapsed are not\n // terms, whatever they say. `validUntil === now` still stands -- it is the\n // last instant the offer is up.\n if (validUntil !== undefined && now > validUntil) {\n return {\n ok: false,\n refusal: {\n code: 'offer-expired',\n validUntil,\n now,\n message:\n `this offer expired at ${validUntil} (now ${now}); ` +\n 'ask the seller for new terms',\n },\n };\n }\n\n // 3. Recipient.\n if (this.recipients !== null) {\n const payTo = canonicalRecipient(offer.payTo);\n if (!this.recipients.has(payTo)) {\n return {\n ok: false,\n refusal: {\n code: 'recipient-not-permitted',\n payTo: offer.payTo,\n message: `this policy does not pay ${offer.payTo}`,\n },\n };\n }\n }\n\n const asset = offerAsset(offer);\n const key = assetKey(asset);\n const requested = readAmount(offer.amount);\n\n // 4. An asset nobody budgeted for. Checked BEFORE the ceilings, because the\n // ceilings are a map and a map has no opinion about a key it does not\n // hold -- which is precisely how an unlisted token would sail past a\n // budget that looks complete. And the caller has to be told \"budget that\n // asset\", not \"raise a ceiling that does not exist\".\n if (\n !this.unlistedAssetsAllowed &&\n !this.perPaymentLimits.has(key) &&\n !this.cumulativeLimits.has(key)\n ) {\n return {\n ok: false,\n refusal: {\n code: 'asset-not-budgeted',\n asset,\n message:\n `this policy has no budget for ${assetLabel(asset)}; ` +\n 'it pays only what it was told it may pay',\n },\n };\n }\n\n // 5. Per-payment ceiling.\n const perPaymentAllowed = this.perPaymentLimits.get(key);\n if (perPaymentAllowed !== undefined && requested > perPaymentAllowed) {\n return {\n ok: false,\n refusal: {\n code: 'per-payment-limit',\n requested,\n allowed: perPaymentAllowed,\n asset,\n message:\n `offer of ${requested} exceeds the per-payment limit of ` +\n `${perPaymentAllowed} for ${assetLabel(asset)}`,\n },\n };\n }\n\n // 6. Cumulative ceiling.\n const cumulativeAllowed = this.cumulativeLimits.get(key);\n if (cumulativeAllowed !== undefined) {\n const spent = this.spent(asset);\n const wouldTotal = spent + requested;\n if (wouldTotal > cumulativeAllowed) {\n return {\n ok: false,\n refusal: {\n code: 'cumulative-limit',\n requested,\n spent,\n wouldTotal,\n allowed: cumulativeAllowed,\n asset,\n message:\n `offer of ${requested} would take spend to ${wouldTotal}, past the ` +\n `cumulative limit of ${cumulativeAllowed} for ${assetLabel(asset)} ` +\n `(already spent ${spent})`,\n },\n };\n }\n }\n\n // The comparison against the listing is made LAST and refuses nothing. It is\n // evidence for the caller, not a gate: a seller repricing inside a policy the\n // operator already authorised is ordinary commerce.\n return {\n ok: true,\n approval: { asset, amount: requested, versusQuote: compareToQuote(asset, requested, quote) },\n };\n }\n\n /** Copy sharing the same purse. Cloning is what a per-request client does. */\n clone(): PurchasePolicy {\n return this.with({});\n }\n\n /**\n * Rebuild with some fields replaced, **always sharing `spentTotals`**. This is\n * the one place that decides copies share a purse, so it is the one place to\n * read when asking whether they do.\n */\n private with(changes: {\n perPaymentLimits?: Map<string, bigint>;\n cumulativeLimits?: Map<string, bigint>;\n recipients?: Set<string> | null;\n unlistedAssetsAllowed?: boolean;\n }): PurchasePolicy {\n return new PurchasePolicy(\n changes.perPaymentLimits ?? this.perPaymentLimits,\n changes.cumulativeLimits ?? this.cumulativeLimits,\n this.spentTotals,\n changes.recipients !== undefined ? changes.recipients : this.recipients,\n this.assetsByKey,\n changes.unlistedAssetsAllowed ?? this.unlistedAssetsAllowed\n );\n }\n\n /** Remember an asset's written form and reject one no budget could match. */\n private register(asset: PolicyAsset): string {\n if (!asset || typeof asset.address !== 'string' || asset.address.trim() === '') {\n throw new X402Error(\n 'A budget needs a token address; an asset with none can never match an offer',\n 'INVALID_CONFIG',\n { asset }\n );\n }\n if (typeof asset.network !== 'string' || asset.network.trim() === '') {\n throw new X402Error(\n 'A budget needs a network; the same address on two networks is two assets',\n 'INVALID_CONFIG',\n { asset }\n );\n }\n const key = assetKey(asset);\n this.assetsByKey.set(key, asset);\n return key;\n }\n}\n\n/** A ceiling has to be a non-negative bigint; anything else is a config bug. */\nfunction requireCeiling(amount: bigint, field: string): bigint {\n if (typeof amount !== 'bigint' || amount < 0n) {\n throw new X402Error(\n `${field} must be a non-negative bigint in atomic units`,\n 'INVALID_AMOUNT',\n { amount: String(amount) }\n );\n }\n return amount;\n}\n\n/**\n * An offer's price as a bigint.\n *\n * Arithmetic is bigint throughout, never `number`: atomic units of an 18-decimal\n * token pass `Number.MAX_SAFE_INTEGER` at 0.01 of a token, and a ceiling\n * compared as a float is a ceiling that rounds.\n *\n * An amount that is not a non-negative integer is read as the largest value we\n * can represent for the comparison, so it fails every ceiling rather than\n * passing as zero: a price we cannot read is not a price we may pay.\n */\nfunction readAmount(amount: string): bigint {\n const text = String(amount).trim();\n if (!/^\\d+$/.test(text)) return UNREADABLE_AMOUNT;\n return BigInt(text);\n}\n\n/**\n * Stand-in for a price we could not read. Absurdly large on purpose: it exceeds\n * every ceiling a caller would write, so an unreadable amount is refused by the\n * limit checks instead of sliding through as zero.\n */\nconst UNREADABLE_AMOUNT = (1n << 256n) - 1n;\n\nfunction compareToQuote(\n asset: PolicyAsset,\n requested: bigint,\n quote: AdvertisedQuote | undefined\n): QuoteComparison {\n if (!quote) return { code: 'not-compared' };\n if (assetKey(quote.asset) !== assetKey(asset)) {\n // Rule 4: a different asset is not the same price. No numbers are compared.\n return { code: 'different-asset', advertised: quote.asset, offered: asset };\n }\n if (quote.amount !== requested) {\n return { code: 'amount-differs', advertised: quote.amount, offered: requested };\n }\n return { code: 'matches' };\n}\n\n// ============================================================================\n// The whole decision, in one place\n// ============================================================================\n\n/** A 402 challenge as the buyer read it, whole. */\nexport interface ReadChallenge {\n /** Offers this build could read. */\n offers: X402PaymentOffer[];\n /**\n * Scheme names of the entries it could not. Rule 7: an `accepts` with one\n * unreadable entry KEEPS the readable ones and counts the others by scheme\n * name, so a refusal can say what the seller offered.\n */\n unreadable: string[];\n /**\n * How many entries were unreadable, which is not the same as how many could be\n * NAMED: an entry too broken to even carry a `scheme` still proves the seller\n * sent offers. Without it, a challenge whose only entry was nameless garbage\n * would read as \"the seller sent nothing\" -- a different fact, and the wrong\n * one to report. Defaults to `unreadable.length`.\n */\n unreadableCount?: number;\n /** The challenge's top-level `extensions`, where `validUntil` lives. */\n extensions?: Record<string, unknown>;\n}\n\n/** Inputs to {@link decideOnChallenge} besides the challenge. */\nexport interface DecideOptions {\n /** Unix seconds. Passed, never read, so the decision can be pinned in a test. */\n now: number;\n /** What the catalog advertised, if the caller read a listing. */\n quote?: AdvertisedQuote;\n}\n\n/**\n * The whole buying decision: all six steps, in the fixed order, against the\n * offer in hand.\n *\n * Takes the challenge WHOLE, deliberately. Passing `offers` alone is what\n * dropped the seller's `validUntil` on the floor in the Rust crate for a full\n * commit with every unit test green, and a signature that takes the parts\n * invites doing it again.\n *\n * Callable without a network stack on purpose: a decision that can only be\n * exercised by driving a real HTTP client is a decision nobody tests.\n *\n * @param offer - The offer already selected out of `challenge.offers`. Selection\n * is the caller's (cheapest, or its own `select`); this decides whether the\n * selected one may be paid.\n */\nexport function decideOnChallenge(\n policy: PurchasePolicy,\n challenge: ReadChallenge,\n offer: X402PaymentOffer | null,\n options: DecideOptions\n): PolicyDecision {\n // 1. Was any offer readable at all? A challenge that carried offers, none of\n // which this build can read, is not \"no matching payment method\": it is a\n // seller asking for a scheme we do not implement, and saying so names what\n // they wanted.\n const unreadableCount = challenge.unreadableCount ?? challenge.unreadable.length;\n if (challenge.offers.length === 0 && unreadableCount > 0) {\n return { ok: false, refusal: noReadableOffer(challenge.unreadable) };\n }\n if (!offer) {\n // Nothing selected out of a challenge that had readable offers, or a seller\n // that sent no offers at all. Either way there is no offer in hand to judge,\n // and the refusal names what the seller offered -- an empty list when it\n // offered nothing.\n return { ok: false, refusal: noReadableOffer(challenge.unreadable) };\n }\n return policy.evaluate(offer, {\n now: options.now,\n validUntil: offerValidUntil(challenge.extensions),\n quote: options.quote,\n });\n}\n","/**\n * uvd-x402-sdk\n *\n * x402 Payment SDK - Gasless crypto payments using the Ultravioleta facilitator.\n *\n * Supports 29 blockchain networks:\n * - EVM (17): Base, Ethereum, Polygon, Arbitrum, Optimism, Avalanche, Celo, HyperEVM, Unichain, Monad, Scroll, SKALE Base (mainnet + Sepolia), Robinhood Chain (mainnet + testnet), Arc mainnet + testnet\n * - SVM (2): Solana, Fogo\n * - Stellar (1): Stellar\n * - NEAR (1): NEAR Protocol\n * - Algorand (2): Algorand mainnet and testnet\n * - Sui (2): Sui mainnet and testnet\n * - XRPL (2): XRP Ledger mainnet and testnet\n *\n * Supports both x402 v1 and v2 protocols.\n *\n * @example Basic usage (EVM)\n * ```ts\n * import { X402Client } from 'uvd-x402-sdk';\n *\n * const client = new X402Client({ defaultChain: 'base' });\n *\n * // Connect wallet\n * await client.connect('base');\n *\n * // Create payment\n * const result = await client.createPayment({\n * recipient: '0x...',\n * amount: '10.00',\n * });\n *\n * // Use result.paymentHeader in X-PAYMENT HTTP header\n * ```\n *\n * @example With SVM (Solana/Fogo)\n * ```ts\n * import { SVMProvider } from 'uvd-x402-sdk/solana';\n * import { getChainByName } from 'uvd-x402-sdk';\n *\n * const svm = new SVMProvider();\n * const address = await svm.connect();\n *\n * // Solana payment\n * const solanaConfig = getChainByName('solana')!;\n * const payload = await svm.signPayment(paymentInfo, solanaConfig);\n * const header = svm.encodePaymentHeader(payload, solanaConfig);\n *\n * // Fogo payment (same provider, different config)\n * const fogoConfig = getChainByName('fogo')!;\n * const fogoPayload = await svm.signPayment(paymentInfo, fogoConfig);\n * const fogoHeader = svm.encodePaymentHeader(fogoPayload, fogoConfig);\n * ```\n *\n * @example With NEAR\n * ```ts\n * import { NEARProvider } from 'uvd-x402-sdk/near';\n * import { getChainByName } from 'uvd-x402-sdk';\n *\n * const near = new NEARProvider();\n * const accountId = await near.connect();\n * const nearConfig = getChainByName('near')!;\n * const payload = await near.signPayment(paymentInfo, nearConfig);\n * const header = near.encodePaymentHeader(payload);\n * ```\n *\n * @example With Algorand\n * ```ts\n * import { AlgorandProvider } from 'uvd-x402-sdk/algorand';\n * import { getChainByName } from 'uvd-x402-sdk';\n *\n * const algorand = new AlgorandProvider();\n * const address = await algorand.connect();\n * const algorandConfig = getChainByName('algorand')!;\n * const payload = await algorand.signPayment(paymentInfo, algorandConfig);\n * const header = algorand.encodePaymentHeader(payload, algorandConfig);\n * ```\n *\n * @example With Sui (Sponsored Transactions)\n * ```ts\n * import { SuiProvider } from 'uvd-x402-sdk/sui';\n * import { getChainByName } from 'uvd-x402-sdk';\n *\n * const sui = new SuiProvider();\n * const address = await sui.connect();\n * const suiConfig = getChainByName('sui')!;\n * const payload = await sui.signPayment(paymentInfo, suiConfig);\n * const header = sui.encodePaymentHeader(payload, suiConfig);\n * // User pays ZERO gas - facilitator sponsors the transaction\n * ```\n *\n * @example With XRPL (t54 pre-signed Payment blob)\n * ```ts\n * import { XRPLProvider } from 'uvd-x402-sdk/xrpl';\n * import { getChainByName } from 'uvd-x402-sdk';\n *\n * const xrpl = new XRPLProvider({ seed: process.env.XRPL_SEED });\n * const address = await xrpl.connect();\n * const xrplConfig = getChainByName('xrpl')!;\n * const payload = await xrpl.signPayment(paymentInfo, xrplConfig); // { signedTxBlob }\n * const header = xrpl.encodePaymentHeader(payload);\n * ```\n *\n * @example With React\n * ```tsx\n * import { X402Provider, useX402, usePayment } from 'uvd-x402-sdk/react';\n *\n * function App() {\n * return (\n * <X402Provider>\n * <PaymentButton />\n * </X402Provider>\n * );\n * }\n * ```\n *\n * @packageDocumentation\n */\n\n// Main client\n// DX402 durable-evidence: recover a paid response after the fact.\nexport {\n EVIDENCE_HEADER,\n DX402Error,\n EvidenceSkipped,\n ContentHashMismatch,\n isEndToEnd,\n contentHash,\n paymentId as dx402PaymentId,\n parseEvidenceHeader,\n evidenceFromHeaders,\n dereferencePointer,\n parseSealed,\n unseal,\n recoverEvidence,\n // seller side\n sealEvidence,\n ed25519ToX25519,\n payerKeyFromEvmSignature,\n sealedRoles,\n anchorDigest,\n signAnchorEd25519,\n signAnchorEvm,\n ZERO_ADDRESS,\n sealEvidenceTo,\n payerKeyFromSolanaAddress,\n anchorEvidence,\n availableBackends,\n type BackendOffer,\n // Reachable only via a deep import before this: the helper that exists so\n // nobody hand-builds a digest was the one you had to already know about.\n sellerDigestFor,\n ANCHOR_MAX_REQUEST_BYTES,\n evidenceHeader,\n} from './dx402';\nexport type { AnchoredEvidence, EvidenceMode, RecipientRole, AnchorOptions } from './dx402';\n\nexport { X402Client } from './client';\n\n// ============================================================================\n// Buyer policy - what this buyer is allowed to sign, decided before it signs\n// ============================================================================\n\nexport {\n PurchasePolicy,\n PolicyRefusedError,\n decideOnChallenge,\n noReadableOffer,\n offerValidUntil,\n offerAsset,\n canonicalRecipient,\n assetKey,\n OFFER_VALIDITY_EXTENSION,\n} from './policy';\nexport type {\n PolicyAsset,\n PolicyRefusal,\n PolicyRefusalCode,\n PolicyApproval,\n PolicyDecision,\n QuoteComparison,\n AdvertisedQuote,\n EvaluateOptions,\n DecideOptions,\n ReadChallenge,\n} from './policy';\n\n// Chain configuration\nexport {\n SUPPORTED_CHAINS,\n DEFAULT_CHAIN,\n DEFAULT_FACILITATOR_URL,\n getChainById,\n getChainByName,\n isChainSupported,\n getEnabledChains,\n getChainsByNetworkType,\n getEVMChainIds,\n getSVMChains,\n isSVMChain,\n getNetworkType,\n getExplorerTxUrl,\n getExplorerAddressUrl,\n // Multi-token support functions\n getTokenConfig,\n getTokenByAddress,\n getSupportedTokens,\n isTokenSupported,\n getChainsByToken,\n // Algorand helper functions\n getAlgorandChains,\n isAlgorandChain,\n // Sui helper functions\n getSuiChains,\n isSuiChain,\n // XRPL helper functions\n getXRPLChains,\n isXRPLChain,\n} from './chains';\n\n// x402 utilities\nexport {\n detectX402Version,\n paymentChallengeFrom,\n chainToCAIP2,\n caip2ToChain,\n parseNetworkIdentifier,\n encodeX402Header,\n decodeX402Header,\n createX402V1Header,\n createX402V2Header,\n createX402Header,\n generatePaymentOptions,\n isCAIP2Format,\n convertX402Header,\n // Validation utilities\n validateRecipient,\n validateAmount,\n // Payment header utilities\n createPaymentHeaders,\n getPaymentHeader,\n DEFAULT_PAYMENT_HEADER,\n PAYMENT_HEADER_NAMES,\n // UTF-8 safe base64 (token domain names like `USD₮0` are not ASCII)\n encodeBase64Utf8,\n decodeBase64Utf8,\n encodeBase64Json,\n // Multi-token payloads\n buildTokenMetadata,\n // EIP-3009 validity window (`validBefore = now + validitySeconds`)\n DEFAULT_VALIDITY_SECONDS,\n MAX_VALIDITY_SECONDS,\n resolveValiditySeconds,\n clampValiditySeconds,\n} from './utils';\n\n// Types\nexport type {\n // Chain types\n ChainConfig,\n USDCConfig,\n NativeCurrency,\n NetworkType,\n\n // Token types (multi-token support)\n TokenType,\n TokenConfig,\n PaymentTokenMetadata,\n\n // Wallet types\n WalletState,\n WalletAdapter,\n EIP712Domain,\n EIP712Types,\n\n // Payment types\n PaymentInfo,\n PaymentRequest,\n PaymentResult,\n X402PaymentOffer,\n X402FetchOptions,\n PaymentHeaders,\n PaymentPayload,\n EVMPaymentPayload,\n SolanaPaymentPayload,\n StellarPaymentPayload,\n NEARPaymentPayload,\n AlgorandPaymentPayload,\n SuiPaymentPayload,\n XRPLPaymentPayload,\n X402HeaderName,\n\n // x402 header types (v1 and v2)\n X402Scheme,\n X402Version,\n X402Header,\n X402HeaderV1,\n X402HeaderV2,\n X402PaymentOption,\n X402PayloadData,\n X402EVMPayload,\n X402SolanaPayload,\n X402SettlementAccountPayload,\n X402StellarPayload,\n X402NEARPayload,\n X402AlgorandPayload,\n X402SuiPayload,\n X402XRPLPayload,\n\n // Config types\n X402ClientConfig,\n MultiPaymentConfig,\n NetworkBalance,\n\n // Event types\n X402Event,\n X402EventData,\n X402EventHandler,\n\n // Error types\n X402ErrorCode,\n} from './types';\n\nexport { X402Error, DEFAULT_CONFIG, CAIP2_IDENTIFIERS, CAIP2_TO_CHAIN } from './types';\n\n// Signing wallet adapters\nexport type { SigningWalletAdapter, EIP3009Params, EIP3009Authorization } from './wallet';\nexport { EnvKeyAdapter } from './adapters/env-key';\nexport { OWSWalletAdapter } from './adapters/ows';\nexport type { OWSWallet } from './adapters/ows';\n\n// Facilitator configuration\nexport { FACILITATOR_ADDRESSES, getFacilitatorAddress } from './facilitator';\nexport type { FacilitatorAddresses } from './facilitator';\n\n// Live traffic stream (GET /events, Server-Sent Events)\nexport {\n streamTrafficEvents,\n parseTrafficEvent,\n matchesFilters,\n SSEParser,\n TrafficStreamError,\n EVENT_KINDS,\n KEEPALIVE_INTERVAL_MS,\n} from './events';\nexport type {\n TrafficEvent,\n TrafficEventKind,\n StreamTrafficEventsOptions,\n SSEFrame,\n} from './events';\n\n// ERC-8128 signed HTTP requests (RFC 9421 signature base + EIP-191)\nexport {\n signRequest,\n signRequestWithWallet,\n signRequestWithSigner,\n fetchNonce,\n createSignedFetch,\n buildSignatureBase,\n buildSignatureParams,\n} from './erc8128';\nexport type {\n ERC8128RequestOptions,\n SignRequestOptions,\n SignRequestWithSignerOptions,\n SignatureHeaders,\n CreateSignedFetchConfig,\n SignatureBaseParams,\n SignatureParamsInput,\n} from './erc8128';\n\n// Escrow pre-auth (sign-on-assignment X-Payment-Auth for the x402r escrow)\nexport {\n buildEscrowPreAuth,\n computeEscrowNonce,\n ESCROW_TIER_WINDOWS,\n ESCROW_DEPOSIT_LIMIT_USD,\n OPERATOR_FEE_BPS,\n MAX_PROTOCOL_FEE_BPS,\n DEFAULT_MIN_FEE_BPS,\n DEFAULT_MAX_FEE_BPS,\n} from './escrow-preauth';\nexport type {\n EscrowNetworkConfig,\n EscrowPaymentInfo,\n EscrowPreAuthParams,\n EscrowPreAuthSigner,\n EscrowTierWindows,\n} from './escrow-preauth';\n\n// Signed escrow lifecycle orders (who may release / refund money already held)\nexport {\n buildLifecycleAuth,\n buildLifecycleTypedData,\n lifecycleAuthFromSignature,\n wagmiLifecycleSigner,\n LIFECYCLE_ACTIONS,\n LIFECYCLE_DOMAIN_NAME,\n LIFECYCLE_DOMAIN_VERSION,\n LIFECYCLE_MAX_DEADLINE_SECS,\n LIFECYCLE_DEFAULT_DEADLINE_SECS,\n LIFECYCLE_ORDER_TYPES,\n} from './lifecycle-auth';\nexport type {\n LifecycleAction,\n LifecycleAuth,\n LifecyclePaymentInfo,\n LifecycleSigner,\n LifecycleTypedData,\n LifecycleTypedDataParams,\n BuildLifecycleAuthParams,\n WagmiLifecycleWalletClient,\n} from './lifecycle-auth';\n\n// EIP-7702 delegated accounts (which dialect a delegated payer must sign in)\nexport {\n DELEGATE_PREFIX,\n SMA_WRAP_TARGETS,\n delegateTarget,\n isDelegated,\n needsAccountWrap,\n replaySafeTypedData,\n resolveDelegation,\n rpcDelegationResolver,\n wrapSignature,\n} from './erc7702.js';\nexport type { DelegationResolver, DelegationVerdict } from './erc7702.js';\n\n// Server-side middleware and facilitator client\nexport {\n FacilitatorClient,\n createPaymentMiddleware,\n createHonoMiddleware,\n create402Response,\n extractPaymentFromHeaders,\n buildPaymentRequirements,\n buildVerifyRequest,\n buildSettleRequest,\n buildVerifyRequestV2,\n buildSettleRequestV2,\n // Choosing the envelope instead of assuming v1. `FacilitatorClient` now does\n // this on its own; these are for callers that build the body themselves.\n resolveEnvelopeVersion,\n buildVerifyRequestForVersion,\n buildSettleRequestForVersion,\n toResourceInfoV2,\n toPaymentRequirementsV2,\n getCorsHeaders,\n X402_CORS_HEADERS,\n X402_HEADER_NAMES,\n // Reading a facilitator refusal as data. A 503 is \"no verdict\", not a\n // rejected payment: re-signing on one charges the buyer twice.\n MAX_RETRY_AFTER_SECONDS,\n DEFAULT_RETRY_AFTER_SECONDS,\n DEFAULT_FACILITATOR_RETRIES,\n WRITER_LEASE_REASONS,\n REPLAYABLE_LEASE_REASONS,\n AMBIGUOUS_LEASE_REASONS,\n isReplayableLeaseReason,\n isAmbiguousLeaseReason,\n parseRetryAfterSeconds,\n readFacilitatorError,\n facilitatorFetch,\n // The 502 that must NOT be retried: the transfer was broadcast and may be\n // mined, so the hash is the answer and a retry is a second payment.\n SETTLEMENT_UNCONFIRMED,\n isSettlementUnconfirmed,\n parseFacilitatorErrorBody,\n // One purchase binding per payment. An authorization the facilitator already\n // admitted is answered 409 to a resend without it: the X-PAYMENT was used.\n IDEMPOTENCY_KEY_HEADER,\n IDEMPOTENT_REPLAYED_HEADER,\n createIdempotencyKey,\n AUTHORIZATION_ALREADY_SETTLED,\n AUTHORIZATION_IN_FLIGHT,\n RECEIPT_REQUEST_CONFLICT,\n isAuthorizationAlreadyUsed,\n isAuthorizationInFlight,\n buildPaymentConflictResponse,\n} from './backend';\nexport type {\n ResourceInfoV2,\n PaymentRequirementsV2,\n PaymentPayloadV2,\n VerifyRequestV2,\n SettleRequestV2,\n FacilitatorClientOptions,\n HonoMiddlewareOptions,\n PaymentAcceptance,\n PaymentMiddlewareOptions,\n VerifiedPaymentState,\n FacilitatorErrorInfo,\n FacilitatorFailureFields,\n FacilitatorFetchOptions,\n ParsedFacilitatorErrorBody,\n WriterLeaseReason,\n VerifyResponse,\n SettleResponse,\n FacilitatorCallOptions,\n AdmittedAuthorizationCode,\n PaymentConflictResponse,\n} from './backend';\n\n// Native Hedera; the optional signing peer remains lazily loaded.\nexport { HederaProvider, buildHederaRequirements, buildHederaRequest, validateHederaRequirements, HEDERA_NETWORKS } from './providers/hedera';\nexport type { HederaNetwork, HederaRequirements, HederaPaymentPayload } from './providers/hedera';\n\nexport * from \"./receipts\";\n","/**\n * uvd-x402-sdk - EnvKeyAdapter\n *\n * SigningWalletAdapter implementation using a raw private key.\n * Reads the key from a constructor parameter or the WALLET_PRIVATE_KEY\n * environment variable.\n *\n * Intended for server-side / CLI / agent use cases where the\n * signing key is available in the environment. NEVER use this\n * in browser contexts -- use OWSWalletAdapter instead.\n *\n * @example Using environment variable\n * ```ts\n * // Reads process.env.WALLET_PRIVATE_KEY\n * const wallet = new EnvKeyAdapter();\n * console.log(wallet.getAddress()); // 0x...\n * ```\n *\n * @example Using explicit key\n * ```ts\n * const wallet = new EnvKeyAdapter(process.env.MY_AGENT_KEY!);\n * const auth = await wallet.signEIP3009({\n * to: '0xRecipient',\n * amountUsdc: 0.10,\n * network: 'base',\n * });\n * ```\n */\n\nimport { ethers } from 'ethers';\nimport { getChainByName } from '../chains';\nimport { X402Error } from '../types';\nimport type {\n SigningWalletAdapter,\n EIP3009Params,\n EIP3009Authorization,\n} from '../wallet';\n\n/**\n * EnvKeyAdapter -- SigningWalletAdapter backed by a raw private key.\n */\nexport class EnvKeyAdapter implements SigningWalletAdapter {\n private readonly wallet: ethers.Wallet;\n\n /**\n * Create an EnvKeyAdapter.\n *\n * @param privateKey - Hex-encoded private key (with or without 0x prefix).\n * If omitted, reads from `process.env.WALLET_PRIVATE_KEY`.\n * @throws {X402Error} if no private key is available\n */\n constructor(privateKey?: string) {\n const key = privateKey || (typeof process !== 'undefined' ? process.env.WALLET_PRIVATE_KEY : undefined);\n\n if (!key) {\n throw new X402Error(\n 'No private key provided. Pass it to the constructor or set WALLET_PRIVATE_KEY env var.',\n 'WALLET_NOT_CONNECTED',\n );\n }\n\n this.wallet = new ethers.Wallet(key);\n }\n\n /**\n * Get the checksummed EVM wallet address.\n */\n getAddress(): string {\n return this.wallet.address;\n }\n\n /**\n * Sign a message using EIP-191 personal_sign.\n *\n * @param message - The message string to sign\n * @returns Hex-encoded signature\n */\n async signMessage(message: string): Promise<string> {\n return this.wallet.signMessage(message);\n }\n\n /**\n * Sign EIP-712 typed structured data.\n *\n * @param typedData - JSON string with `domain`, `types`, `primaryType`, and `message` fields\n * @returns Object with signature and v/r/s components\n */\n async signTypedData(typedData: string): Promise<{\n signature: string;\n v: number;\n r: string;\n s: string;\n }> {\n const parsed = JSON.parse(typedData) as {\n domain: ethers.TypedDataDomain;\n types: Record<string, Array<{ name: string; type: string }>>;\n primaryType: string;\n message: Record<string, unknown>;\n };\n\n // ethers v6 signTypedData does not take primaryType -- it infers it\n // from the types object (the type not listed as a field of another type).\n // We pass domain, types (without EIP712Domain), and the message value.\n const { domain, types, message } = parsed;\n\n // Remove EIP712Domain from types if present (ethers handles it via domain)\n const cleanTypes = { ...types };\n delete cleanTypes['EIP712Domain'];\n\n const signature = await this.wallet.signTypedData(domain, cleanTypes, message);\n const sig = ethers.Signature.from(signature);\n\n return {\n signature,\n v: sig.v,\n r: sig.r,\n s: sig.s,\n };\n }\n\n /**\n * Sign a serialized EVM transaction.\n *\n * Uses the raw private key via ethers.Wallet.signTransaction().\n * Used by AdvancedEscrowClient for on-chain operations (release,\n * refund, charge) when constructed with a SigningWalletAdapter.\n *\n * @param unsignedTx - Hex-encoded unsigned transaction (ethers serialized)\n * @returns Hex-encoded signed raw transaction, ready for broadcast\n */\n async signTransaction(unsignedTx: string): Promise<string> {\n const tx = ethers.Transaction.from(unsignedTx);\n return this.wallet.signTransaction(tx);\n }\n\n /**\n * Sign an EIP-3009 ReceiveWithAuthorization for USDC.\n *\n * @param params - EIP-3009 parameters\n * @returns Signed authorization ready for facilitator relay\n */\n async signEIP3009(params: EIP3009Params): Promise<EIP3009Authorization> {\n const chain = getChainByName(params.network);\n if (!chain) {\n throw new X402Error(`Unsupported network: ${params.network}`, 'CHAIN_NOT_SUPPORTED');\n }\n\n if (chain.networkType !== 'evm') {\n throw new X402Error(\n `EIP-3009 is only supported on EVM chains. ${params.network} is ${chain.networkType}.`,\n 'CHAIN_NOT_SUPPORTED',\n );\n }\n\n const chainId = params.chainId ?? chain.chainId;\n const usdcAddress = params.usdcContract ?? chain.usdc.address;\n const from = this.wallet.address;\n const to = ethers.getAddress(params.to);\n const value = ethers.parseUnits(params.amountUsdc.toString(), chain.usdc.decimals);\n const validAfter = params.validAfter ?? 0;\n const validBefore = params.validBefore ?? Math.floor(Date.now() / 1000) + 300;\n\n // Generate random 32-byte nonce\n const nonce = ethers.hexlify(ethers.randomBytes(32));\n\n // EIP-712 domain (matches USDC contract's domain separator)\n const domain: ethers.TypedDataDomain = {\n name: chain.usdc.name,\n version: chain.usdc.version,\n chainId,\n verifyingContract: usdcAddress,\n };\n\n // EIP-712 types for TransferWithAuthorization (ERC-3009)\n const types = {\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 };\n\n // Message to sign\n const message = {\n from,\n to,\n value,\n validAfter,\n validBefore,\n nonce,\n };\n\n // Sign the EIP-712 typed data\n let signature: string;\n try {\n signature = await this.wallet.signTypedData(domain, types, message);\n } catch (error: unknown) {\n throw new X402Error(\n `Failed to sign EIP-3009 authorization: ${error instanceof Error ? error.message : 'Unknown error'}`,\n 'PAYMENT_FAILED',\n error,\n );\n }\n\n const sig = ethers.Signature.from(signature);\n\n return {\n from,\n to,\n value: value.toString(),\n validAfter: validAfter.toString(),\n validBefore: validBefore.toString(),\n nonce,\n v: sig.v,\n r: sig.r,\n s: sig.s,\n signature,\n };\n }\n}\n","/**\n * uvd-x402-sdk - OWSWalletAdapter\n *\n * SigningWalletAdapter implementation using the Open Wallet Standard (OWS).\n * Delegates all signing to an OWS wallet instance, which manages key\n * security (encrypted vault, hardware isolation, etc.).\n *\n * Requires `@open-wallet-standard/core` as an optional peer dependency.\n * If the package is not installed, the adapter throws a helpful error\n * at construction time.\n *\n * @example\n * ```ts\n * import { OWSWalletAdapter } from 'uvd-x402-sdk';\n *\n * // The OWS wallet object must implement signMessage and signTypedData\n * const wallet = new OWSWalletAdapter(owsWallet);\n * const auth = await wallet.signEIP3009({\n * to: '0xRecipient',\n * amountUsdc: 0.50,\n * network: 'base',\n * });\n * ```\n */\n\nimport { ethers } from 'ethers';\nimport { getChainByName } from '../chains';\nimport { X402Error } from '../types';\nimport type {\n SigningWalletAdapter,\n EIP3009Params,\n EIP3009Authorization,\n} from '../wallet';\n\n// ============================================================================\n// OWS WALLET INTERFACE (minimal subset we need)\n// ============================================================================\n\n/**\n * Minimal OWS wallet interface for signing operations.\n *\n * This mirrors the subset of the Open Wallet Standard that we use,\n * avoiding a hard compile-time dependency on @open-wallet-standard/core.\n * Any object that satisfies this shape can be passed to OWSWalletAdapter.\n */\nexport interface OWSWallet {\n /** Get wallet accounts (at least one EVM account expected) */\n accounts: ReadonlyArray<{\n /** EVM address (0x...) */\n address: string;\n /** Chain identifiers this account supports */\n chains?: ReadonlyArray<string>;\n }>;\n\n /** Sign a personal message (EIP-191) */\n signMessage(params: {\n account: { address: string };\n message: string | Uint8Array;\n }): Promise<{ signature: string }>;\n\n /** Sign EIP-712 typed data */\n signTypedData(params: {\n account: { address: string };\n domain: Record<string, unknown>;\n types: Record<string, Array<{ name: string; type: string }>>;\n primaryType: string;\n message: Record<string, unknown>;\n }): Promise<{ signature: string }>;\n\n /** Sign a serialized EVM transaction (hex-encoded) */\n signTransaction(params: {\n account: { address: string };\n transaction: string;\n chainId: string;\n }): Promise<{ signedTransaction: string }>;\n}\n\n// ============================================================================\n// OWS WALLET ADAPTER\n// ============================================================================\n\n/**\n * OWSWalletAdapter -- SigningWalletAdapter backed by an Open Wallet Standard wallet.\n */\nexport class OWSWalletAdapter implements SigningWalletAdapter {\n private readonly owsWallet: OWSWallet;\n private readonly address: string;\n\n /**\n * Create an OWSWalletAdapter.\n *\n * @param owsWallet - An object implementing the OWSWallet interface\n * (typically from @open-wallet-standard/core or a compatible provider)\n * @param accountIndex - Which account to use if the wallet has multiple (default: 0)\n * @throws {X402Error} if the wallet has no accounts\n */\n constructor(owsWallet: OWSWallet, accountIndex = 0) {\n if (!owsWallet || !owsWallet.accounts || owsWallet.accounts.length === 0) {\n throw new X402Error(\n 'OWS wallet has no accounts. Create or import a wallet first.',\n 'WALLET_NOT_CONNECTED',\n );\n }\n\n const account = owsWallet.accounts[accountIndex];\n if (!account) {\n throw new X402Error(\n `OWS wallet account index ${accountIndex} does not exist. Wallet has ${owsWallet.accounts.length} account(s).`,\n 'WALLET_NOT_CONNECTED',\n );\n }\n\n this.owsWallet = owsWallet;\n this.address = ethers.getAddress(account.address);\n }\n\n /**\n * Get the checksummed EVM wallet address.\n */\n getAddress(): string {\n return this.address;\n }\n\n /**\n * Sign a message using EIP-191 personal_sign.\n *\n * @param message - The message string to sign\n * @returns Hex-encoded signature\n */\n async signMessage(message: string): Promise<string> {\n try {\n const result = await this.owsWallet.signMessage({\n account: { address: this.address },\n message,\n });\n return result.signature;\n } catch (error: unknown) {\n throw new X402Error(\n `OWS signMessage failed: ${error instanceof Error ? error.message : 'Unknown error'}`,\n 'PAYMENT_FAILED',\n error,\n );\n }\n }\n\n /**\n * Sign EIP-712 typed structured data.\n *\n * @param typedData - JSON string with `domain`, `types`, `primaryType`, and `message` fields\n * @returns Object with signature and v/r/s components\n */\n async signTypedData(typedData: string): Promise<{\n signature: string;\n v: number;\n r: string;\n s: string;\n }> {\n const parsed = JSON.parse(typedData) as {\n domain: Record<string, unknown>;\n types: Record<string, Array<{ name: string; type: string }>>;\n primaryType: string;\n message: Record<string, unknown>;\n };\n\n try {\n const result = await this.owsWallet.signTypedData({\n account: { address: this.address },\n domain: parsed.domain,\n types: parsed.types,\n primaryType: parsed.primaryType,\n message: parsed.message,\n });\n\n const sig = ethers.Signature.from(result.signature);\n\n return {\n signature: result.signature,\n v: sig.v,\n r: sig.r,\n s: sig.s,\n };\n } catch (error: unknown) {\n throw new X402Error(\n `OWS signTypedData failed: ${error instanceof Error ? error.message : 'Unknown error'}`,\n 'PAYMENT_FAILED',\n error,\n );\n }\n }\n\n /**\n * Sign a serialized EVM transaction.\n *\n * Delegates to the OWS wallet's signTransaction method.\n * Used by AdvancedEscrowClient for on-chain operations (release,\n * refund, charge) where the wallet signs instead of a raw private key.\n *\n * @param unsignedTx - Hex-encoded unsigned transaction\n * @returns Hex-encoded signed raw transaction\n */\n async signTransaction(unsignedTx: string): Promise<string> {\n try {\n const result = await this.owsWallet.signTransaction({\n account: { address: this.address },\n transaction: unsignedTx,\n chainId: '1', // chainId is embedded in the serialized TX; this is a hint\n });\n return result.signedTransaction;\n } catch (error: unknown) {\n throw new X402Error(\n `OWS signTransaction failed: ${error instanceof Error ? error.message : 'Unknown error'}`,\n 'PAYMENT_FAILED',\n error,\n );\n }\n }\n\n /**\n * Sign an EIP-3009 ReceiveWithAuthorization for USDC.\n *\n * @param params - EIP-3009 parameters\n * @returns Signed authorization ready for facilitator relay\n */\n async signEIP3009(params: EIP3009Params): Promise<EIP3009Authorization> {\n const chain = getChainByName(params.network);\n if (!chain) {\n throw new X402Error(`Unsupported network: ${params.network}`, 'CHAIN_NOT_SUPPORTED');\n }\n\n if (chain.networkType !== 'evm') {\n throw new X402Error(\n `EIP-3009 is only supported on EVM chains. ${params.network} is ${chain.networkType}.`,\n 'CHAIN_NOT_SUPPORTED',\n );\n }\n\n const chainId = params.chainId ?? chain.chainId;\n const usdcAddress = params.usdcContract ?? chain.usdc.address;\n const from = this.address;\n const to = ethers.getAddress(params.to);\n const value = ethers.parseUnits(params.amountUsdc.toString(), chain.usdc.decimals);\n const validAfter = params.validAfter ?? 0;\n const validBefore = params.validBefore ?? Math.floor(Date.now() / 1000) + 300;\n\n // Generate random 32-byte nonce\n const nonce = ethers.hexlify(ethers.randomBytes(32));\n\n // EIP-712 domain\n const domain: Record<string, unknown> = {\n name: chain.usdc.name,\n version: chain.usdc.version,\n chainId,\n verifyingContract: usdcAddress,\n };\n\n // EIP-712 types for TransferWithAuthorization (ERC-3009)\n const types = {\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 };\n\n // Message to sign\n const message: Record<string, unknown> = {\n from,\n to,\n value: value.toString(),\n validAfter: validAfter.toString(),\n validBefore: validBefore.toString(),\n nonce,\n };\n\n let signatureResult: { signature: string };\n try {\n signatureResult = await this.owsWallet.signTypedData({\n account: { address: this.address },\n domain,\n types,\n primaryType: 'TransferWithAuthorization',\n message,\n });\n } catch (error: unknown) {\n throw new X402Error(\n `OWS signEIP3009 failed: ${error instanceof Error ? error.message : 'Unknown error'}`,\n 'PAYMENT_FAILED',\n error,\n );\n }\n\n const sig = ethers.Signature.from(signatureResult.signature);\n\n return {\n from,\n to,\n value: value.toString(),\n validAfter: validAfter.toString(),\n validBefore: validBefore.toString(),\n nonce,\n v: sig.v,\n r: sig.r,\n s: sig.s,\n signature: signatureResult.signature,\n };\n }\n}\n","/**\n * Facilitator Configuration\n *\n * This module contains the known facilitator addresses for each chain.\n * The SDK uses these automatically so users don't need to configure them.\n *\n * The facilitator (https://facilitator.ultravioletadao.xyz) has wallets\n * on each supported blockchain for:\n * - EVM: Signing EIP-3009 transferWithAuthorization transactions\n * - Solana: Paying transaction fees (fee payer)\n * - Algorand: Signing fee transactions in atomic groups\n * - Stellar: Signing authorization entries\n * - NEAR: Acting as relayer for meta-transactions\n * - Sui: Sponsoring transactions (paying gas via sponsored txs)\n * - XRPL: Submitting pre-signed Payment blobs (paying the network fee)\n */\n\n/**\n * Default facilitator URL\n */\nexport const DEFAULT_FACILITATOR_URL = 'https://facilitator.ultravioletadao.xyz';\n\n/**\n * Facilitator wallet addresses by chain type\n *\n * These are the public addresses of the facilitator's wallets.\n * The facilitator uses these to pay fees and sign transactions.\n */\nexport const FACILITATOR_ADDRESSES = {\n // ============================================\n // EVM Chains\n // ============================================\n /**\n * EVM facilitator address (mainnet)\n * Used for: Submitting EIP-3009 transferWithAuthorization transactions\n * Note: Same address across all EVM mainnet chains\n */\n evm: '0x103040545AC5031A11E8C03dd11324C7333a13C7',\n\n /**\n * EVM facilitator address (testnet)\n * Used for: All EVM testnet chains\n */\n 'evm-testnet': '0x34033041a5944B8F10f8E4D8496Bfb84f1A293A8',\n\n // ============================================\n // Solana\n // ============================================\n /**\n * Solana facilitator address (mainnet)\n * Used for: Paying transaction fees on Solana\n */\n solana: 'F742C4VfFLQ9zRQyithoj5229ZgtX2WqKCSFKgH2EThq',\n\n /**\n * Solana facilitator address (devnet)\n */\n 'solana-devnet': '6xNPewUdKRbEZDReQdpyfNUdgNg8QRc8Mt263T5GZSRv',\n\n // ============================================\n // Fogo (uses same addresses as Solana)\n // ============================================\n /**\n * Fogo facilitator address (mainnet)\n */\n fogo: 'F742C4VfFLQ9zRQyithoj5229ZgtX2WqKCSFKgH2EThq',\n\n /**\n * Fogo facilitator address (testnet)\n */\n 'fogo-testnet': '6xNPewUdKRbEZDReQdpyfNUdgNg8QRc8Mt263T5GZSRv',\n\n // ============================================\n // NEAR\n // ============================================\n /**\n * NEAR facilitator address (mainnet)\n * Used for: Relaying meta-transactions\n */\n near: 'uvd-facilitator.near',\n\n /**\n * NEAR facilitator address (testnet)\n */\n 'near-testnet': 'uvd-facilitator.testnet',\n\n // ============================================\n // Stellar\n // ============================================\n /**\n * Stellar facilitator address (mainnet)\n * Used for: Signing soroban authorization entries\n */\n stellar: 'GCHPGXJT2WFFRFCA5TV4G4E3PMMXLNIDUH27PKDYA4QJ2XGYZWGFZNHB',\n\n /**\n * Stellar facilitator address (testnet)\n */\n 'stellar-testnet': 'GBBFZMLUJEZVI32EN4XA2KPP445XIBTMTRBLYWFIL556RDTHS2OWFQ2Z',\n\n // ============================================\n // Algorand\n // ============================================\n /**\n * Algorand facilitator address (mainnet)\n * Used for: Signing Transaction 0 (fee tx) in atomic groups\n */\n algorand: 'KIMS5H6QLCUDL65L5UBTOXDPWLMTS7N3AAC3I6B2NCONEI5QIVK7LH2C2I',\n\n /**\n * Algorand facilitator address (testnet)\n */\n 'algorand-testnet': '5DPPDQNYUPCTXRZWRYSF3WPYU6RKAUR25F3YG4EKXQRHV5AUAI62H5GXL4',\n\n // ============================================\n // Sui\n // ============================================\n /**\n * Sui facilitator address (mainnet)\n * Used for: Sponsoring transactions (paying gas)\n */\n sui: '0xe7bbf2b13f7d72714760aa16e024fa1b35a978793f9893d0568a4fbf356a764a',\n\n /**\n * Sui facilitator address (testnet)\n */\n 'sui-testnet': '0xabbd16a2fab2a502c9cfe835195a6fc7d70bfc27cffb40b8b286b52a97006e67',\n\n // ============================================\n // XRPL (XRP Ledger)\n // ============================================\n /**\n * XRPL facilitator address (mainnet)\n * Used for: Submitting pre-signed Payment blobs and paying the network fee\n */\n xrpl: 'rfADKkVXBNqK3z72tVSS3LVzAR3psYkonp',\n\n // Native Hedera sponsors (canonical ledger IDs and input aliases).\n 'hedera:mainnet': '0.0.10868300',\n 'hedera:testnet': '0.0.10576385',\n hedera: '0.0.10868300',\n 'hedera-testnet': '0.0.10576385',\n\n /**\n * XRPL facilitator address (testnet)\n */\n 'xrpl-testnet': 'rGhTioKAFHe75KgVnQtacRiKFuPv28Wbwk',\n} as const;\n\n/**\n * Get the facilitator address for a specific chain\n *\n * @param chainName - The chain name (e.g., 'algorand', 'solana', 'base')\n * @param networkType - The network type (e.g., 'evm', 'svm', 'algorand')\n * @returns The facilitator address for that chain, or undefined if not supported\n */\nexport function getFacilitatorAddress(\n chainName: string,\n networkType?: string\n): string | undefined {\n // Check for exact chain match first\n const exactMatch = FACILITATOR_ADDRESSES[chainName as keyof typeof FACILITATOR_ADDRESSES];\n if (exactMatch) {\n return exactMatch;\n }\n\n // Fall back to network type\n if (networkType === 'evm') {\n return FACILITATOR_ADDRESSES.evm;\n }\n if (networkType === 'svm' || networkType === 'solana') {\n return FACILITATOR_ADDRESSES.solana;\n }\n if (networkType === 'algorand') {\n return FACILITATOR_ADDRESSES.algorand;\n }\n if (networkType === 'stellar') {\n return FACILITATOR_ADDRESSES.stellar;\n }\n if (networkType === 'near') {\n return FACILITATOR_ADDRESSES.near;\n }\n if (networkType === 'sui') {\n return FACILITATOR_ADDRESSES.sui;\n }\n if (networkType === 'xrpl') {\n return FACILITATOR_ADDRESSES.xrpl;\n }\n\n return undefined;\n}\n\n/**\n * Type for facilitator addresses\n */\nexport type FacilitatorAddresses = typeof FACILITATOR_ADDRESSES;\n","/**\n * Live traffic stream client (`GET /events`, Server-Sent Events).\n *\n * The facilitator emits one event per operation it handles, so you can render or\n * react to live traffic without polling and without scraping logs.\n *\n * @example\n * ```ts\n * import { streamTrafficEvents } from '@ultravioletadao/x402-sdk';\n *\n * for await (const event of streamTrafficEvents()) {\n * console.log(event.kind, event.network, event.ok, event.tx);\n * }\n * ```\n *\n * @example Only settlements on the chains you care about. The facilitator has NO\n * server-side filter by network, so this is applied client-side.\n * ```ts\n * const stream = streamTrafficEvents({\n * networks: ['base', 'polygon'],\n * kinds: ['settle'],\n * });\n * for await (const event of stream) console.log(event.tx);\n * ```\n *\n * Three properties of this stream decide how you should use it:\n *\n * **It is lossy by design.** The facilitator will never slow down or fail a\n * payment to keep an observer in sync, so an event you were not connected for is\n * simply gone. Treat it as a live hint and use the chain as the source of truth.\n * Absence of events is NOT evidence that nothing happened.\n *\n * **Failed operations are not published.** Only operations that resolved emit an\n * event, so `ok: false` means \"resolved and came back negative\", never \"blew up\".\n * A stream that looks healthy is not proof that the rail is.\n *\n * **Admission is bounded.** The endpoint is public and unauthenticated, so it\n * sheds with HTTP 503 + `Retry-After` once too many subscribers are connected,\n * and returns 404 when the operator disabled it.\n */\n\nimport { DEFAULT_FACILITATOR_URL } from './facilitator';\n\n/** Operations the facilitator publishes. */\nexport type TrafficEventKind = 'verify' | 'settle';\n\n/** Operations the facilitator publishes, as a value. */\nexport const EVENT_KINDS: readonly TrafficEventKind[] = ['verify', 'settle'] as const;\n\n/**\n * The stream sends a `:keepalive` comment on this cadence, so any read timeout\n * you add must comfortably exceed it or you will kill healthy connections on an\n * idle rail.\n */\nexport const KEEPALIVE_INTERVAL_MS = 15_000;\n\n/**\n * One facilitator operation, as seen by an observer.\n *\n * Optional fields are *omitted* by the facilitator rather than sent as null, and\n * they are all absent when the operator runs the stream in `minimal` detail\n * mode. Never assume `payer` or `amount` is present.\n */\nexport interface TrafficEvent {\n /** Unix epoch **milliseconds**, UTC. Note: milliseconds, not seconds. */\n ts: number;\n kind: TrafficEventKind | string;\n /**\n * The facilitator's canonical network slug, the same one `/supported` uses.\n *\n * Beware: this is the *canonical* name, which is not always the alias you are\n * allowed to send. `skale` is accepted on the way in, but this field always\n * says `skale-base`. Match on the canonical form or you will silently drop\n * every event for that chain.\n */\n network: string;\n /** Resolved successfully? False means resolved-negative, not errored. */\n ok: boolean;\n payer?: string;\n /** Present on `settle`, absent on `verify` — nothing settled yet. */\n tx?: string;\n amount?: string;\n asset?: string;\n /**\n * The protected endpoint being bought.\n *\n * Answers \"what was paid for\", which the amount alone never does — two\n * 1-USDC settles are indistinguishable without it.\n */\n resource?: string;\n /** The seller receiving the payment. */\n payTo?: string;\n /** Human-readable description the seller advertised. */\n description?: string;\n /** Payment scheme: `exact`, `escrow`, `commerce`, `upto`. */\n scheme?: string;\n /**\n * Why the operation failed, as a BOUNDED CATEGORY — never the error text.\n *\n * Present only on operations that errored, and only where the operator set\n * `X402_EVENTS_PUBLISH_FAILURES=true`. A closed set (`contract_revert`,\n * `invalid_signature`, `insufficient_funds`, `invalid_timing`,\n * `blocked_address`, …, `other`) precisely so it can never carry an address\n * or an RPC URL.\n *\n * Note the distinction it makes visible: `ok: false` with no `error` means the\n * operation RESOLVED and came back negative; `error` set means it blew up.\n * Before this existed the second case produced no event at all.\n */\n error?: string;\n}\n\n/** Raised when the stream cannot be opened. Carries the HTTP status. */\nexport class TrafficStreamError extends Error {\n readonly status: number;\n /** Seconds to wait before retrying, when the server said so (503). */\n readonly retryAfter?: number;\n\n constructor(message: string, status: number, retryAfter?: number) {\n super(message);\n this.name = 'TrafficStreamError';\n this.status = status;\n this.retryAfter = retryAfter;\n }\n}\n\nexport interface StreamTrafficEventsOptions {\n /** Facilitator to subscribe to. Defaults to the Ultravioleta DAO facilitator. */\n facilitatorUrl?: string;\n /**\n * Only yield events for these networks. Applied client-side — the facilitator\n * has no per-network filter, so every event still crosses the wire. Match the\n * canonical slug (`skale-base`, not `skale`).\n */\n networks?: string[];\n /** Only yield these operations. */\n kinds?: TrafficEventKind[];\n /** Abort the stream. Without one, iteration ends only when the server closes. */\n signal?: AbortSignal;\n /** Extra headers, for a deployment that gates the stream behind authorization. */\n headers?: Record<string, string>;\n}\n\n/** One decoded SSE frame: the event name and its raw data payload. */\nexport interface SSEFrame {\n event: string;\n data: string;\n}\n\n/**\n * Incremental Server-Sent Events parser.\n *\n * Kept separate from the network layer so the framing can be tested without a\n * socket — which matters, because the case that breaks in production is an idle\n * rail sending nothing but keepalive comments for minutes.\n */\nexport class SSEParser {\n private buffer = '';\n private eventName = '';\n private dataLines: string[] = [];\n\n /** Feed a chunk of the response body; get back whatever frames completed. */\n push(chunk: string): SSEFrame[] {\n this.buffer += chunk;\n const frames: SSEFrame[] = [];\n\n let newlineIndex: number;\n while ((newlineIndex = this.buffer.indexOf('\\n')) !== -1) {\n const line = this.buffer.slice(0, newlineIndex).replace(/\\r$/, '');\n this.buffer = this.buffer.slice(newlineIndex + 1);\n\n if (line === '') {\n // Blank line dispatches. A dispatch with no data is a no-op per spec.\n if (this.dataLines.length > 0) {\n frames.push({\n event: this.eventName || 'message',\n data: this.dataLines.join('\\n'),\n });\n }\n this.eventName = '';\n this.dataLines = [];\n continue;\n }\n\n if (line.startsWith(':')) {\n // Comment. This is what a keepalive looks like — deliberately silent.\n continue;\n }\n\n const colon = line.indexOf(':');\n const field = colon === -1 ? line : line.slice(0, colon);\n let value = colon === -1 ? '' : line.slice(colon + 1);\n // A single leading space after the colon is framing, not value.\n if (value.startsWith(' ')) value = value.slice(1);\n\n if (field === 'event') this.eventName = value;\n else if (field === 'data') this.dataLines.push(value);\n // id / retry: accepted and ignored, so a future facilitator that starts\n // sending them does not break this parser.\n }\n\n return frames;\n }\n}\n\n/**\n * Decode one SSE frame into a {@link TrafficEvent}.\n *\n * Returns null for anything malformed: a single bad message must never tear down\n * a long-lived stream — the connection is worth more than the message.\n */\nexport function parseTrafficEvent(frame: SSEFrame): TrafficEvent | null {\n let payload: unknown;\n try {\n payload = JSON.parse(frame.data);\n } catch {\n return null;\n }\n if (typeof payload !== 'object' || payload === null || Array.isArray(payload)) {\n return null;\n }\n\n const raw = payload as Record<string, unknown>;\n // The SSE event name is authoritative for `kind`; the body carries it too and\n // they agree, but the framing is the contract.\n const kind = (raw.kind as string) || frame.event;\n\n if (typeof raw.ts !== 'number' || typeof raw.network !== 'string' || typeof raw.ok !== 'boolean') {\n return null;\n }\n\n const event: TrafficEvent = {\n ts: raw.ts,\n kind,\n network: raw.network,\n ok: raw.ok,\n };\n if (typeof raw.payer === 'string') event.payer = raw.payer;\n if (typeof raw.tx === 'string') event.tx = raw.tx;\n if (typeof raw.amount === 'string') event.amount = raw.amount;\n if (typeof raw.asset === 'string') event.asset = raw.asset;\n if (typeof raw.resource === 'string') event.resource = raw.resource;\n if (typeof raw.payTo === 'string') event.payTo = raw.payTo;\n if (typeof raw.description === 'string') event.description = raw.description;\n if (typeof raw.scheme === 'string') event.scheme = raw.scheme;\n if (typeof raw.error === 'string') event.error = raw.error;\n return event;\n}\n\n/** Does this event pass the caller's client-side filters? */\nexport function matchesFilters(\n event: TrafficEvent,\n options: Pick<StreamTrafficEventsOptions, 'networks' | 'kinds'>\n): boolean {\n if (options.kinds && options.kinds.length > 0) {\n if (!options.kinds.some((k) => k.toLowerCase() === event.kind.toLowerCase())) return false;\n }\n if (options.networks && options.networks.length > 0) {\n if (!options.networks.some((n) => n.toLowerCase() === event.network.toLowerCase())) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * Subscribe to the facilitator's live traffic stream.\n *\n * Works in Node 18+ and in browsers: it uses `fetch` and the response body\n * stream rather than `EventSource`, so it also works where custom headers are\n * needed (`EventSource` cannot send them).\n *\n * Iteration ends when the server closes the connection or the `signal` aborts.\n * It does NOT reconnect on its own — reconnect policy belongs to the caller, who\n * is the only one who knows whether a gap matters.\n *\n * @throws {TrafficStreamError} 404 when the operator disabled the stream, 503\n * with `retryAfter` when it is at subscriber capacity.\n */\nexport async function* streamTrafficEvents(\n options: StreamTrafficEventsOptions = {}\n): AsyncGenerator<TrafficEvent, void, undefined> {\n const baseUrl = (options.facilitatorUrl || DEFAULT_FACILITATOR_URL).replace(/\\/$/, '');\n const response = await fetch(`${baseUrl}/events`, {\n method: 'GET',\n headers: { Accept: 'text/event-stream', ...(options.headers || {}) },\n signal: options.signal,\n });\n\n if (!response.ok) {\n const body = await response.text().catch(() => '');\n if (response.status === 404) {\n throw new TrafficStreamError(\n `GET /events is disabled on this facilitator (operator set X402_EVENTS_ENABLED=false): ${body}`,\n 404\n );\n }\n if (response.status === 503) {\n const header = response.headers.get('retry-after');\n const retryAfter = header ? Number(header) : undefined;\n throw new TrafficStreamError(\n `GET /events is at subscriber capacity; retry after ${header ?? 'unknown'}s. ` +\n `This is admission control, not an outage.`,\n 503,\n Number.isFinite(retryAfter) ? retryAfter : undefined\n );\n }\n throw new TrafficStreamError(`GET /events failed: ${response.status} - ${body}`, response.status);\n }\n\n if (!response.body) {\n throw new TrafficStreamError('GET /events returned no body to stream', response.status);\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n const parser = new SSEParser();\n\n try {\n for (;;) {\n const { done, value } = await reader.read();\n if (done) return;\n for (const frame of parser.push(decoder.decode(value, { stream: true }))) {\n const event = parseTrafficEvent(frame);\n if (event && matchesFilters(event, options)) yield event;\n }\n }\n } finally {\n // Releasing the lock lets the caller's `break` actually close the socket\n // instead of leaking a half-read response.\n reader.releaseLock();\n }\n}\n","/**\n * uvd-x402-sdk - ERC-8128 HTTP Message Signature Signer\n *\n * Signs HTTP requests per ERC-8128 (Signed HTTP Requests with Ethereum,\n * RFC 9421 profile) so agents can authenticate against APIs that reject\n * API keys and only accept wallet signing (e.g. Execution Market, where\n * `EM_API_KEYS_ENABLED=false` in production).\n *\n * Flow:\n * 1. Fetch a fresh single-use nonce from the server (`fetchNonce`)\n * 2. Build the RFC 9421 signature base from request components\n * 3. Sign with EIP-191 personal_sign\n * 4. Produce `Signature` + `Signature-Input` (+ `Content-Digest`) headers\n *\n * Wire format: pinned by the F3-1 golden vectors (`src/erc8128.vectors.json`)\n * — `alg=\"eip191\"` always emitted, keyid ALWAYS lowercase, params in the\n * order `created;expires;nonce;keyid;alg`. Byte-equality against the vectors\n * is enforced in `src/erc8128.test.ts`.\n *\n * Three signing entry points:\n * - {@link signRequest} — raw private key (ethers Wallet), for scripts /\n * bots that hold the key in env.\n * - {@link signRequestWithWallet} — any {@link SigningWalletAdapter}\n * (EnvKeyAdapter, OWSWalletAdapter, custom); only `getAddress()` and\n * `signMessage()` are used, the key never leaves the adapter.\n * - {@link signRequestWithSigner} — callback-based, for browser wallets or\n * out-of-process signers that expose a bare EIP-191 personal_sign.\n *\n * @example Sign a single request\n * ```typescript\n * import { signRequest, fetchNonce } from 'uvd-x402-sdk';\n *\n * const nonce = await fetchNonce('https://api.execution.market');\n * const headers = await signRequest({\n * privateKey: process.env.WALLET_PRIVATE_KEY!,\n * method: 'POST',\n * url: 'https://api.execution.market/api/v1/tasks',\n * body: '{\"title\": \"test\"}',\n * nonce,\n * chainId: 8453,\n * });\n * // headers = { Signature: '...', 'Signature-Input': '...', 'Content-Digest': '...' }\n * ```\n *\n * @example Auto-signing fetch wrapper\n * ```typescript\n * import { createSignedFetch, EnvKeyAdapter } from 'uvd-x402-sdk';\n *\n * const signedFetch = createSignedFetch({\n * wallet: new EnvKeyAdapter(), // or privateKey: '...'\n * apiBase: 'https://api.execution.market',\n * });\n *\n * const resp = await signedFetch('/api/v1/tasks', {\n * method: 'POST',\n * body: JSON.stringify({ title: 'test' }),\n * });\n * ```\n *\n * Reference:\n * - ERC-8128: https://eip.tools/eip/8128\n * - RFC 9421: https://www.rfc-editor.org/rfc/rfc9421\n * - ERC-191: https://eips.ethereum.org/EIPS/eip-191\n */\n\nimport { ethers } from 'ethers';\nimport { X402Error } from './types';\nimport type { SigningWalletAdapter } from './wallet';\n\n/** Default label for ERC-8128 signatures */\nconst DEFAULT_LABEL = 'eth';\n\n/** Signature algorithm parameter — pinned by F3-1 (always emitted) */\nconst ALG = 'eip191';\n\n/** Default validity window (seconds) — server policy typically caps at 300 */\nconst DEFAULT_VALIDITY_SEC = 300;\n\n/** Default EVM chain ID for the keyid (Base mainnet, the production auth chain) */\nconst DEFAULT_CHAIN_ID = 8453;\n\n/**\n * Request components shared by every ERC-8128 signing entry point.\n */\nexport interface ERC8128RequestOptions {\n /** HTTP method (GET, POST, etc.) */\n method: string;\n /** Full URL of the request (authority + path + query are covered) */\n url: string;\n /**\n * Request body (for POST/PUT/PATCH). Omit for bodyless requests.\n * Must be byte-identical to what is sent on the wire — the\n * `Content-Digest` covers it.\n */\n body?: string;\n /** Single-use nonce from the server. Required by most servers. */\n nonce?: string;\n /** EVM chain ID for the keyid (default: 8453 = Base) */\n chainId?: number;\n /** Signature label (default: \"eth\") */\n label?: string;\n /** Signature validity window in seconds (default: 300) */\n validitySec?: number;\n}\n\nexport interface SignRequestOptions extends ERC8128RequestOptions {\n /** Hex-encoded private key (with or without 0x prefix) */\n privateKey: string;\n}\n\nexport interface SignRequestWithSignerOptions extends ERC8128RequestOptions {\n /** Signer address (any case — lowercased for the keyid per F3-1) */\n address: string;\n /**\n * EIP-191 personal_sign callback over the RFC 9421 signature base.\n * Must return the 65-byte signature (r||s||v) as 0x-prefixed hex.\n * The private key never leaves the signer (OWS vault, browser wallet).\n */\n signMessage: (signatureBase: string) => Promise<string> | string;\n}\n\nexport interface SignatureHeaders {\n Signature: string;\n 'Signature-Input': string;\n 'Content-Digest'?: string;\n}\n\n/**\n * Configuration for {@link createSignedFetch}. Provide exactly one signer:\n * a raw `privateKey` or a `wallet` adapter.\n */\nexport interface CreateSignedFetchConfig {\n /** Origin of the API (e.g. \"https://api.execution.market\") */\n apiBase: string;\n /** EVM chain ID for the keyid (default: 8453 = Base) */\n chainId?: number;\n /** Hex-encoded private key (with or without 0x prefix) */\n privateKey?: string;\n /** SigningWalletAdapter — the key never leaves the adapter */\n wallet?: SigningWalletAdapter;\n}\n\n/**\n * Sign an HTTP request per ERC-8128 with a raw private key.\n *\n * Thin wrapper over {@link signRequestWithSigner} using an ethers Wallet.\n *\n * @returns Headers to merge into the request (Signature, Signature-Input, Content-Digest).\n */\nexport async function signRequest(options: SignRequestOptions): Promise<SignatureHeaders> {\n const key = options.privateKey.startsWith('0x')\n ? options.privateKey\n : `0x${options.privateKey}`;\n const wallet = new ethers.Wallet(key);\n return signRequestWithSigner({\n address: wallet.address,\n signMessage: (signatureBase) => wallet.signMessage(signatureBase),\n method: options.method,\n url: options.url,\n body: options.body,\n nonce: options.nonce,\n chainId: options.chainId,\n label: options.label,\n validitySec: options.validitySec,\n });\n}\n\n/**\n * Sign an HTTP request per ERC-8128 with a {@link SigningWalletAdapter}.\n *\n * Only `getAddress()` and `signMessage()` (EIP-191 personal_sign) are used —\n * the private key never leaves the adapter. Works with EnvKeyAdapter,\n * OWSWalletAdapter, or any custom adapter.\n *\n * @returns Headers to merge into the request (Signature, Signature-Input, Content-Digest).\n */\nexport async function signRequestWithWallet(\n wallet: SigningWalletAdapter,\n options: ERC8128RequestOptions\n): Promise<SignatureHeaders> {\n return signRequestWithSigner({\n ...options,\n address: wallet.getAddress(),\n signMessage: (signatureBase) => wallet.signMessage(signatureBase),\n });\n}\n\n/**\n * Sign an HTTP request per ERC-8128 with a signing callback.\n *\n * For signers that never expose the raw key (OWS vault, browser wallets):\n * the callback receives the RFC 9421 signature base and returns the EIP-191\n * personal_sign signature as 0x-hex.\n *\n * @returns Headers to merge into the request (Signature, Signature-Input, Content-Digest).\n */\nexport async function signRequestWithSigner(\n options: SignRequestWithSignerOptions\n): Promise<SignatureHeaders> {\n const {\n address: rawAddress,\n signMessage,\n method,\n url,\n body,\n nonce,\n chainId = DEFAULT_CHAIN_ID,\n label = DEFAULT_LABEL,\n validitySec = DEFAULT_VALIDITY_SEC,\n } = options;\n\n // CRITICAL: lowercase — checksummed keyid caused the v9.x silent-auth INC.\n const address = rawAddress.toLowerCase();\n\n const parsed = new URL(url);\n const authority = parsed.host;\n const path = parsed.pathname || '/';\n const query = parsed.search || undefined; // includes '?' prefix\n\n const now = Math.floor(Date.now() / 1000);\n const created = now;\n const expires = now + validitySec;\n\n const keyid = `erc8128:${chainId}:${address}`;\n\n // Determine covered components\n const covered: string[] = ['@method', '@authority', '@path'];\n if (query) {\n covered.push('@query');\n }\n\n const headers: SignatureHeaders = {\n Signature: '',\n 'Signature-Input': '',\n };\n\n if (body !== undefined) {\n const digest = computeContentDigest(body);\n headers['Content-Digest'] = digest;\n covered.push('content-digest');\n }\n\n // Build signature base\n const sigBase = buildSignatureBase({\n method,\n authority,\n path,\n query,\n contentDigest: headers['Content-Digest'],\n covered,\n created,\n expires,\n nonce,\n keyid,\n });\n\n // EIP-191 personal_sign via the callback — the key stays in the signer\n const sigHex = await signMessage(sigBase);\n\n // Encode signature as base64 (RFC 8941 byte sequence)\n const sigBytes = ethers.getBytes(sigHex.startsWith('0x') ? sigHex : `0x${sigHex}`);\n const sigB64 = ethers.encodeBase64(sigBytes);\n\n // Build headers\n const sigParams = buildSignatureParams({ covered, created, expires, nonce, keyid });\n\n headers.Signature = `${label}=:${sigB64}:`;\n headers['Signature-Input'] = `${label}=${sigParams}`;\n\n return headers;\n}\n\n/**\n * Fetch a fresh single-use nonce from the server.\n *\n * @param apiBase - Origin of the API (e.g. \"https://api.execution.market\")\n * — the `/api/v1/auth/erc8128/nonce` path is appended here.\n * @param timeoutMs - Request timeout in milliseconds (default: 10000).\n * @returns The nonce value (single-use, short TTL — fetch one per request).\n */\nexport async function fetchNonce(apiBase: string, timeoutMs = 10000): Promise<string> {\n const url = `${apiBase.replace(/\\/$/, '')}/api/v1/auth/erc8128/nonce`;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n\n try {\n const resp = await fetch(url, { signal: controller.signal });\n if (!resp.ok) {\n throw new Error(`Failed to fetch nonce: ${resp.status} ${resp.statusText}`);\n }\n const data = (await resp.json()) as { nonce: string };\n return data.nonce;\n } finally {\n clearTimeout(timer);\n }\n}\n\n/**\n * Create a fetch wrapper that auto-signs requests with ERC-8128\n * (nonce fetch + signature headers on every call).\n *\n * @example\n * ```typescript\n * const signedFetch = createSignedFetch({\n * wallet: new EnvKeyAdapter(), // or privateKey: '...'\n * apiBase: 'https://api.execution.market',\n * chainId: 8453,\n * });\n *\n * const resp = await signedFetch('/api/v1/tasks', {\n * method: 'POST',\n * body: JSON.stringify({ title: 'test' }),\n * });\n * ```\n */\nexport function createSignedFetch(config: CreateSignedFetchConfig) {\n const { apiBase, chainId, privateKey, wallet } = config;\n\n if (!privateKey && !wallet) {\n throw new X402Error(\n 'createSignedFetch requires a signer: pass privateKey or wallet.',\n 'WALLET_NOT_CONNECTED'\n );\n }\n\n return async (path: string, init?: RequestInit): Promise<Response> => {\n const url = `${apiBase.replace(/\\/$/, '')}${path}`;\n const method = (init?.method || 'GET').toUpperCase();\n const body = init?.body ? String(init.body) : undefined;\n\n // Fresh single-use nonce per request\n const nonce = await fetchNonce(apiBase);\n\n // Sign request\n const requestOptions: ERC8128RequestOptions = { method, url, body, nonce, chainId };\n const sigHeaders = wallet\n ? await signRequestWithWallet(wallet, requestOptions)\n : await signRequest({ ...requestOptions, privateKey: privateKey! });\n\n // Merge headers\n const headers = new Headers(init?.headers);\n headers.set('Signature', sigHeaders.Signature);\n headers.set('Signature-Input', sigHeaders['Signature-Input']);\n if (sigHeaders['Content-Digest']) {\n headers.set('Content-Digest', sigHeaders['Content-Digest']);\n }\n if (body) {\n headers.set('Content-Type', headers.get('Content-Type') || 'application/json');\n }\n\n return fetch(url, { ...init, headers, method });\n };\n}\n\n// ---------------------------------------------------------------------------\n// Signature-base construction (exported: browser / out-of-process signers\n// build the exact same base and sign it elsewhere)\n// ---------------------------------------------------------------------------\n\nfunction computeContentDigest(body: string): string {\n const hash = ethers.sha256(ethers.toUtf8Bytes(body));\n // hash is 0x-prefixed hex, convert to raw bytes then base64\n const b64 = ethers.encodeBase64(ethers.getBytes(hash));\n return `sha-256=:${b64}:`;\n}\n\nexport interface SignatureBaseParams {\n method: string;\n authority: string;\n path: string;\n query?: string;\n contentDigest?: string;\n covered: string[];\n created: number;\n expires: number;\n nonce?: string;\n keyid: string;\n}\n\n/**\n * Build the RFC 9421 signature base — the exact string that gets EIP-191\n * personal_signed. Exported so external signers (OWS, browser) can reproduce\n * it byte-for-byte; pinned by the F3-1 golden vectors.\n */\nexport function buildSignatureBase(params: SignatureBaseParams): string {\n const lines: string[] = [];\n\n for (const component of params.covered) {\n switch (component) {\n case '@method':\n lines.push(`\"@method\": ${params.method.toUpperCase()}`);\n break;\n case '@authority':\n lines.push(`\"@authority\": ${params.authority}`);\n break;\n case '@path':\n lines.push(`\"@path\": ${params.path}`);\n break;\n case '@query':\n lines.push(`\"@query\": ${params.query || '?'}`);\n break;\n case 'content-digest':\n lines.push(`\"content-digest\": ${params.contentDigest || ''}`);\n break;\n }\n }\n\n const sigParams = buildSignatureParams({\n covered: params.covered,\n created: params.created,\n expires: params.expires,\n nonce: params.nonce,\n keyid: params.keyid,\n });\n lines.push(`\"@signature-params\": ${sigParams}`);\n\n return lines.join('\\n');\n}\n\nexport interface SignatureParamsInput {\n covered: string[];\n created: number;\n expires: number;\n nonce?: string;\n keyid: string;\n}\n\n/**\n * Build the `@signature-params` value per RFC 9421, in the pinned order\n * `created;expires;nonce;keyid;alg` (F3-1).\n */\nexport function buildSignatureParams(params: SignatureParamsInput): string {\n const compStr = params.covered.map((c) => `\"${c}\"`).join(' ');\n const parts: string[] = [`(${compStr})`];\n parts.push(`created=${params.created}`);\n parts.push(`expires=${params.expires}`);\n if (params.nonce) {\n parts.push(`nonce=\"${params.nonce}\"`);\n }\n parts.push(`keyid=\"${params.keyid}\"`);\n parts.push(`alg=\"${ALG}\"`);\n return parts.join(';');\n}\n","/**\n * uvd-x402-sdk - Escrow Pre-Auth Builder (sign-on-assignment)\n *\n * Builds and signs the EIP-3009 `ReceiveWithAuthorization` that locks a\n * bounty in the x402r AuthCaptureEscrow, and packs it into the raw-JSON\n * `X-Payment-Auth` wrapper the Ultravioleta Facilitator's `/settle` expects.\n * Used by marketplaces built on the escrow rail (e.g. Execution Market's\n * universal escrow, ADR-002).\n *\n * >>> PROTOCOL CONSTRAINT <<<\n * The EIP-3009 nonce is `AuthCaptureEscrow.getHash(paymentInfo)` which\n * INCLUDES the receiver — the escrow signature can only be created AT\n * ASSIGNMENT, when the worker/payee is known. Never design flows that sign\n * an escrow auth before the receiver is chosen (\"stored pre-auth with late\n * receiver fill\" is on-chain unsound).\n *\n * Fail-loud policy: an incomplete network config, an unknown tier, a bounty\n * outside the on-chain deposit limit, or a `maxFeeBps` that cannot cover the\n * operator's static fee all throw instead of falling back — a silent\n * fallback would sign an EIP-3009 authorization with the WRONG EIP-712\n * domain (chainId + verifyingContract): a mismatched, wallet-draining auth.\n *\n * Wire format is pinned by golden vectors (`src/escrow-preauth.vectors.json`):\n * payer-zeroed raw-keccak nonce (`keccak(chainId, escrow,\n * keccak(PAYMENT_INFO_TYPEHASH, paymentInfo tuple with payer=0))`),\n * `ReceiveWithAuthorization` typed data, raw JSON (NOT base64) wrapper.\n * Byte-parity with the production references is enforced in\n * `src/escrow-preauth.test.ts`.\n *\n * @example Sign the escrow lock at assignment time\n * ```typescript\n * import { buildEscrowPreAuth, EnvKeyAdapter } from 'uvd-x402-sdk';\n *\n * // Server-published escrow config (e.g. GET /api/v1/h2a/payment-config\n * // on Execution Market — escrow_networks[network]).\n * const paymentAuth = await buildEscrowPreAuth(new EnvKeyAdapter(), {\n * networkConfig: config.escrow.networks.base,\n * payerWallet: '0xPublisher...',\n * workerWallet: '0xWorker...', // committed by the nonce\n * bountyAtomic: '100000', // $0.10 in 6-decimal USDC\n * reviewDeadlineSec: taskDeadlineEpoch,\n * });\n * // Send as the X-Payment-Auth header (raw JSON, NOT base64).\n * ```\n *\n * Reference implementations (kept in byte-parity via the shared vectors):\n * - Python: `em_plugin_sdk.escrow_signing.build_escrow_pre_auth`\n * (production reference, derived from `uvd_x402_sdk.advanced_escrow`)\n * - Browser (viem): Execution Market `dashboard/src/services/h2aSigning.ts`\n */\n\nimport { ethers } from 'ethers';\nimport { X402Error } from './types';\nimport {\n needsAccountWrap,\n replaySafeTypedData,\n resolveDelegation,\n wrapSignature,\n type DelegationResolver,\n} from './erc7702.js';\n\nconst ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';\n\nconst USDC_DECIMALS = 6;\n\n/** AuthCaptureEscrow deposit condition: $100 max per deposit. */\nexport const ESCROW_DEPOSIT_LIMIT_USD = 100;\n\n/**\n * StaticFeeCalculator: canonical 13% flat fee. The signed maxFeeBps MUST\n * cover it or the on-chain authorize reverts (`FeeBoundsIncompatible`) — the\n * guard runs on the way IN, so a bound that is too low never opens the escrow\n * at all. It is not a way to pay less.\n *\n * This is a CEILING TO PLAN AGAINST, not a reading of any one deployment. The\n * operator fee is an immutable of each PaymentOperator instance, chosen from\n * `OperatorConfig.feeCalculator` when the factory deploys it, so two operators\n * on the same chain can charge differently and neither is knowable from here.\n *\n * Measured 2026-09-05: every `operator` address in {@link ESCROW_CONTRACTS} that\n * answered is the PaymentOperatorFactory, not a deployed operator — it exposes\n * `ESCROW()` and `operators(bytes32)` and reverts on `FEE_CALCULATOR()`,\n * `FEE_RECIPIENT()` and `release(...)`. Confirmed on Base mainnet, Base Sepolia\n * and Arbitrum, and matched by x402-rs `docs/X402R_MULTICHAIN_DEPLOYMENT.md`,\n * which labels those same addresses \"PaymentOperatorFactory\".\n *\n * cast call 0x3D0837fF8Ea36F417261577b9BA568400A840260 \\\n * \"ESCROW()(address)\" --rpc-url https://mainnet.base.org\n * # 0xb9488351E48b23D798f24e8174514F28B741Eb4f (factory immutable)\n * cast call 0x3D0837fF8Ea36F417261577b9BA568400A840260 \\\n * \"FEE_CALCULATOR()(address)\" --rpc-url https://mainnet.base.org\n * # execution reverted (operator-only getter)\n *\n * So read the fee off the operator you were actually given — the marketplace\n * publishes it in {@link EscrowNetworkConfig} — and pass `max_fee_bps` when it\n * differs. This constant is only the default bound.\n */\nexport const OPERATOR_FEE_BPS = 1300;\n\n/**\n * Hard cap the shared ProtocolFeeConfig puts on the PROTOCOL's slice, mirrored\n * from `ProtocolFeeConfig.MAX_PROTOCOL_FEE_BPS` (x402-rs\n * `contracts/src/plugins/fees/ProtocolFeeConfig.sol`). `getProtocolFeeBps`\n * clamps to it, so no deployment can ever charge more than this on top of the\n * operator's own fee.\n *\n * Measured on Base mainnet 2026-09-05 against the ProtocolFeeConfig the SDK\n * ships for chain 8453 (`0x59314674BAbb1a24Eb2704468a9cCdD50668a1C6`):\n *\n * cast call 0x59314674BAbb1a24Eb2704468a9cCdD50668a1C6 \\\n * \"MAX_PROTOCOL_FEE_BPS()(uint256)\" --rpc-url https://mainnet.base.org\n * # 500\n * cast call 0x59314674BAbb1a24Eb2704468a9cCdD50668a1C6 \\\n * \"calculator()(address)\" --rpc-url https://mainnet.base.org\n * # 0x0000000000000000000000000000000000000000 -> protocol fee is 0 today\n */\nexport const MAX_PROTOCOL_FEE_BPS = 500;\n\n/**\n * Fee-bound defaults for optional config keys only — never for the domain.\n *\n * `PaymentOperator` charges `protocolFee + operatorFee` and compares that SUM\n * against the signed `maxFeeBps` (`_calculateFees`, then the guard in\n * `authorize`/`charge`). So the only bound guaranteed never to revert is the\n * canonical operator fee plus the protocol's hard cap — derived here rather\n * than re-typed, so the two can never drift apart.\n */\nexport const DEFAULT_MIN_FEE_BPS = 0;\nexport const DEFAULT_MAX_FEE_BPS = OPERATOR_FEE_BPS + MAX_PROTOCOL_FEE_BPS;\n\n/**\n * EIP-712 type for the escrow flow. The token collector pulls the funds, so\n * the scheme is ReceiveWithAuthorization (not TransferWithAuthorization).\n */\nconst RECEIVE_WITH_AUTHORIZATION_TYPES = {\n ReceiveWithAuthorization: [\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};\n\n/**\n * ABI type of the paymentInfo tuple — mirrors AdvancedEscrowClient /\n * em_plugin_sdk.escrow_signing (unnamed components, positional encoding).\n */\nconst PAYMENT_INFO_TUPLE =\n 'tuple(address,address,address,address,uint120,uint48,uint48,uint48,uint16,uint16,address,uint256)';\n\n/** Per-tier expiry windows in seconds, relative to now() at signing. */\nexport interface EscrowTierWindows {\n pre: number;\n auth: number;\n refund: number;\n}\n\n/** Canonical fallback — mirrors uvd_x402_sdk TIER_TIMINGS. */\nexport const ESCROW_TIER_WINDOWS: Record<string, EscrowTierWindows> = {\n micro: { pre: 3600, auth: 7200, refund: 86400 },\n standard: { pre: 7200, auth: 86400, refund: 604800 },\n};\n\n/**\n * Human review windows. Agents approve in seconds, so the short SDK tier\n * windows (micro auth = 2h) work for them. A HUMAN publisher reviews on\n * their own schedule — if authorizationExpiry passes before approval, the\n * on-chain release REVERTS (AfterAuthorizationExpiry). So release/refund\n * windows are extended to comfortably outlast the deadline + review buffer.\n */\nexport const REVIEW_WINDOW_SEC = 7 * 24 * 3600; // >=7 days to approve after the deadline\nexport const REFUND_WINDOW_SEC = 7 * 24 * 3600; // +7 days to refund after that\n\n/**\n * One network's escrow parameters, as published by the marketplace server\n * (e.g. Execution Market's `GET /api/v1/h2a/payment-config` →\n * `escrow_networks[network]`). Snake_case on purpose: pass the server's\n * JSON straight through so the SDK builds the paymentInfo EXACTLY like the\n * production reference.\n */\nexport interface EscrowNetworkConfig {\n chain_id: number;\n operator: string;\n escrow: string;\n token_collector: string;\n usdc: string;\n usdc_domain_name: string;\n usdc_domain_version: string;\n /** 32-byte hex PAYMENT_INFO_TYPEHASH (with or without 0x prefix). */\n payment_info_typehash: string;\n /** Server-published tier windows; falls back to ESCROW_TIER_WINDOWS. */\n tiers?: Record<string, EscrowTierWindows>;\n min_fee_bps?: number;\n max_fee_bps?: number;\n}\n\n/** paymentInfo exactly as serialized in the X-Payment-Auth wrapper. */\nexport interface EscrowPaymentInfo {\n operator: string;\n receiver: string;\n token: string;\n /** Atomic units, as string (uint120 on-chain). */\n maxAmount: string;\n preApprovalExpiry: number;\n authorizationExpiry: number;\n refundExpiry: number;\n minFeeBps: number;\n maxFeeBps: number;\n feeReceiver: string;\n /** 32-byte hex. */\n salt: string;\n}\n\nconst REQUIRED_NETWORK_KEYS: Array<keyof EscrowNetworkConfig> = [\n 'chain_id',\n 'operator',\n 'escrow',\n 'token_collector',\n 'usdc',\n 'usdc_domain_name',\n 'usdc_domain_version',\n 'payment_info_typehash',\n];\n\nfunction hex32(value: string): string {\n return value.startsWith('0x') ? value : `0x${value}`;\n}\n\n/** 32 random bytes as 0x-hex (WebCrypto when available, ethers otherwise). */\nfunction randomSalt(): string {\n const webCrypto = (globalThis as { crypto?: Crypto }).crypto;\n if (webCrypto?.getRandomValues) {\n const bytes = new Uint8Array(32);\n webCrypto.getRandomValues(bytes);\n return ethers.hexlify(bytes);\n }\n return ethers.hexlify(ethers.randomBytes(32));\n}\n\n/**\n * Compute the escrow EIP-3009 nonce = `AuthCaptureEscrow.getHash(paymentInfo)`.\n *\n * `keccak(chainId, escrow, keccak(PAYMENT_INFO_TYPEHASH, paymentInfo tuple\n * with payer=0))` — the payer slot is zeroed for the payer-agnostic hash;\n * the RECEIVER is part of the hash, which is why the signature commits to\n * the chosen worker. Port of `AdvancedEscrowClient._compute_nonce` /\n * `em_plugin_sdk.escrow_signing.compute_escrow_nonce`.\n *\n * @param chainId - EVM chain id.\n * @param escrowAddress - AuthCaptureEscrow contract on that chain.\n * @param paymentInfoTypehash - 32-byte hex typehash from the server config.\n * @param pi - paymentInfo exactly as serialized on the wire.\n * @returns 32-byte hex nonce (0x-prefixed, lowercase).\n */\nexport function computeEscrowNonce(\n chainId: number,\n escrowAddress: string,\n paymentInfoTypehash: string,\n pi: EscrowPaymentInfo\n): string {\n const coder = ethers.AbiCoder.defaultAbiCoder();\n\n const piTuple = [\n ethers.getAddress(pi.operator),\n ZERO_ADDRESS, // payer = 0 for the payer-agnostic hash\n ethers.getAddress(pi.receiver),\n ethers.getAddress(pi.token),\n BigInt(pi.maxAmount), // uint120\n pi.preApprovalExpiry, // uint48\n pi.authorizationExpiry, // uint48\n pi.refundExpiry, // uint48\n pi.minFeeBps, // uint16\n pi.maxFeeBps, // uint16\n ethers.getAddress(pi.feeReceiver),\n BigInt(hex32(pi.salt)), // uint256\n ];\n\n const piHash = ethers.keccak256(\n coder.encode(['bytes32', PAYMENT_INFO_TUPLE], [hex32(paymentInfoTypehash), piTuple])\n );\n return ethers.keccak256(\n coder.encode(\n ['uint256', 'address', 'bytes32'],\n [chainId, ethers.getAddress(escrowAddress), piHash]\n )\n );\n}\n\n/**\n * Minimal signer for {@link buildEscrowPreAuth}: EIP-712 typed-data signing\n * over the full typed-data JSON string (`domain`, `types`, `primaryType`,\n * `message`) — the same contract as `SigningWalletAdapter.signTypedData`,\n * so every adapter (EnvKeyAdapter, OWSWalletAdapter, custom) satisfies it\n * structurally. Browser wallets can wrap their own signTypedData in this\n * shape; the key never leaves the signer.\n */\nexport interface EscrowPreAuthSigner {\n signTypedData(typedData: string): Promise<{ signature: string }>;\n}\n\nexport interface EscrowPreAuthParams {\n /** Network escrow config as published by the marketplace server. */\n networkConfig: EscrowNetworkConfig;\n /**\n * Publisher wallet (payer). Not checked against the signer's address —\n * payer binding is enforced on-chain and by the backend, not here.\n */\n payerWallet: string;\n /** Chosen worker's wallet (escrow receiver — committed by the nonce). */\n workerWallet: string;\n /** Bounty in atomic units (6-decimal USDC). */\n bountyAtomic: string | bigint;\n /** Expiry tier; windows come from config when present. Default 'micro'. */\n tier?: string;\n /**\n * Task deadline (epoch seconds). The release/refund windows are extended\n * to outlast it + a review buffer so a human publisher can still approve\n * after the worker delivers. When omitted, falls back to now()-based\n * windows.\n */\n reviewDeadlineSec?: number;\n /**\n * On-chain deposit limit in USD (AuthCaptureEscrow deposit condition).\n * Default {@link ESCROW_DEPOSIT_LIMIT_USD}; override only when the server\n * publishes a different limit.\n */\n depositLimitUsd?: number;\n /**\n * How to find out whether `payerWallet` is EIP-7702-delegated, and to what.\n *\n * Optional, and its absence is honest rather than convenient: with no resolver\n * the verdict is UNKNOWN and this function signs the ordinary way, exactly as\n * it did before. Pass one — {@link rpcDelegationResolver} or your own — as soon\n * as your payers can be delegated accounts, because a delegated payer signing\n * the wrong dialect produces an authorization that **cannot settle on-chain**\n * and only fails at lock time.\n *\n * When a resolver IS supplied and it reaches no verdict, this throws instead of\n * guessing: an unreadable chain is not a \"not delegated\" answer.\n */\n delegationResolver?: DelegationResolver;\n}\n\n/**\n * Build + sign the escrow lock authorization AT ASSIGNMENT time and return\n * the raw JSON string for the `X-Payment-Auth` header (NOT base64 — the\n * backend relays it verbatim to the Facilitator `/settle`). Mirror of\n * `AdvancedEscrowClient.authorize()`'s /settle payload and of\n * `em_plugin_sdk.escrow_signing.build_escrow_pre_auth`.\n *\n * @throws {X402Error} `INVALID_CONFIG` on an incomplete network config,\n * unknown tier, or a `maxFeeBps` that cannot cover the operator's static\n * fee; `INVALID_AMOUNT` on a bounty outside (0, deposit limit].\n */\nexport async function buildEscrowPreAuth(\n wallet: EscrowPreAuthSigner,\n params: EscrowPreAuthParams\n): Promise<string> {\n const cfg = params.networkConfig;\n\n const missing = REQUIRED_NETWORK_KEYS.filter((key) => !cfg[key]);\n if (missing.length > 0) {\n throw new X402Error(\n `Incomplete escrow network config (missing ${missing.join(', ')}) — ` +\n 'refusing to sign an EIP-3009 authorization with a mismatched domain.',\n 'INVALID_CONFIG'\n );\n }\n\n const maxAmount = BigInt(params.bountyAtomic);\n if (maxAmount <= 0n) {\n throw new X402Error(\n `Bounty must be positive, got ${maxAmount} atomic units`,\n 'INVALID_AMOUNT'\n );\n }\n const depositLimitUsd = params.depositLimitUsd ?? ESCROW_DEPOSIT_LIMIT_USD;\n const depositLimitAtomic = BigInt(Math.round(depositLimitUsd * 10 ** USDC_DECIMALS));\n if (maxAmount > depositLimitAtomic) {\n throw new X402Error(\n `Bounty ${maxAmount} atomic units exceeds the on-chain escrow deposit ` +\n `limit ($${depositLimitUsd}).`,\n 'INVALID_AMOUNT'\n );\n }\n\n const minFeeBps = cfg.min_fee_bps ?? DEFAULT_MIN_FEE_BPS;\n const maxFeeBps = cfg.max_fee_bps ?? DEFAULT_MAX_FEE_BPS;\n if (maxFeeBps < OPERATOR_FEE_BPS) {\n throw new X402Error(\n `maxFeeBps=${maxFeeBps} cannot cover the operator's ${OPERATOR_FEE_BPS} ` +\n 'bps static fee — the on-chain release would revert.',\n 'INVALID_CONFIG'\n );\n }\n\n const tierKey = params.tier ?? 'micro';\n const windows = cfg.tiers?.[tierKey] ?? ESCROW_TIER_WINDOWS[tierKey];\n if (!windows) {\n const known = [...new Set([...Object.keys(cfg.tiers ?? {}), ...Object.keys(ESCROW_TIER_WINDOWS)])].sort();\n throw new X402Error(\n `Unknown escrow tier '${tierKey}' — known tiers: ${known.join(', ')}`,\n 'INVALID_CONFIG'\n );\n }\n\n const now = Math.floor(Date.now() / 1000);\n\n // The release window must outlast the human review. Base it on the task\n // deadline (the worker delivers near it) plus a generous buffer, and never\n // shorter than the SDK tier window. preApprovalExpiry stays short — the\n // lock executes immediately at assignment.\n const reviewBase = Math.max(now, params.reviewDeadlineSec ?? now);\n const authExpiry = Math.max(now + windows.auth, reviewBase + REVIEW_WINDOW_SEC);\n const refundExpiry = Math.max(now + windows.refund, authExpiry + REFUND_WINDOW_SEC);\n\n const paymentInfo: EscrowPaymentInfo = {\n operator: ethers.getAddress(cfg.operator),\n receiver: ethers.getAddress(params.workerWallet),\n token: ethers.getAddress(cfg.usdc),\n maxAmount: maxAmount.toString(),\n preApprovalExpiry: now + windows.pre,\n authorizationExpiry: authExpiry,\n refundExpiry: refundExpiry,\n minFeeBps: minFeeBps,\n maxFeeBps: maxFeeBps,\n feeReceiver: ethers.getAddress(cfg.operator),\n salt: randomSalt(),\n };\n\n const nonce = computeEscrowNonce(\n cfg.chain_id,\n cfg.escrow,\n cfg.payment_info_typehash,\n paymentInfo\n );\n\n const payer = ethers.getAddress(params.payerWallet);\n const tokenCollector = ethers.getAddress(cfg.token_collector);\n\n // String-valued message fields: the typed data travels as JSON to the\n // adapter (SigningWalletAdapter.signTypedData contract), and ethers\n // accepts decimal strings for uint256 / 0x-hex for bytes32.\n const typedData = {\n domain: {\n name: cfg.usdc_domain_name,\n version: cfg.usdc_domain_version,\n chainId: cfg.chain_id,\n verifyingContract: ethers.getAddress(cfg.usdc),\n },\n types: RECEIVE_WITH_AUTHORIZATION_TYPES,\n primaryType: 'ReceiveWithAuthorization',\n message: {\n from: payer,\n to: tokenCollector,\n value: maxAmount.toString(),\n validAfter: '0',\n validBefore: String(paymentInfo.preApprovalExpiry),\n nonce: nonce,\n },\n };\n\n // ── EIP-7702: a DELEGATED payer cannot settle a raw ECDSA authorization ──\n //\n // Once the payer's EOA carries code, USDC validates via ERC-1271 only and raw\n // ECDSA reverts (0x151d90fe) — the lock fails on-chain. Measured in production\n // 2026-07-31: 14 of 14 delegated payers failed; the one plain EOA locked fine.\n //\n // THREE STATES, and the third is the one that matters: an UNKNOWN delegation is\n // NOT \"not delegated\". Collapsing it to false is exactly how the original bug\n // survived eight days — signing raw for an account that can never settle it,\n // silently.\n //\n // AND THE DIALECT DEPENDS ON THE TARGET. \"Delegated\" is not one signature\n // scheme: the account-envelope wrap is Alchemy-SMA-specific. A delegate that\n // validates plain ECDSA through ERC-1271 — Execution Market's FeedbackDelegate,\n // which every account that has rated through the facilitator's rail is pointed\n // at — needs the ORDINARY signature. Wrapping it is as unsettleable as signing\n // raw for an SMA.\n const { delegated, target } = await resolveDelegation(\n payer,\n `eip155:${cfg.chain_id}`,\n params.delegationResolver\n );\n if (delegated === null && params.delegationResolver) {\n throw new X402Error(\n `Could not determine whether ${payer} is EIP-7702-delegated on chain ` +\n `${cfg.chain_id} (the resolver gave no verdict) — refusing to sign an ` +\n 'escrow authorization blindly: the wrong dialect is unsettleable ' +\n 'on-chain and the failure only shows up at lock time. Retry when the ' +\n 'chain is readable.',\n 'INVALID_CONFIG'\n );\n }\n\n let signature: string;\n if (delegated && (needsAccountWrap(target) || target === null)) {\n // SMA-wrap: the known Alchemy account, OR a legacy boolean-only resolver that\n // could not name the target — for which we keep the conservative behaviour\n // rather than silently changing what such callers got. A resolver that\n // returns the target lands any non-SMA delegate in the plain branch below.\n const innerDigest = ethers.TypedDataEncoder.hash(\n typedData.domain,\n typedData.types,\n typedData.message\n );\n const replaySafe = replaySafeTypedData(innerDigest, cfg.chain_id, payer);\n const wrapped = await wallet.signTypedData(\n JSON.stringify({ ...replaySafe, primaryType: 'ReplaySafeHash' })\n );\n if (!wrapped?.signature) {\n throw new X402Error(\n 'The wallet returned no signature for the replay-safe wrap — refusing ' +\n 'to build an unsettleable authorization.',\n 'INVALID_CONFIG'\n );\n }\n signature = wrapSignature(wrapped.signature);\n } else {\n // Plain EOA, unknown-with-no-resolver, or a delegate that takes ordinary\n // ECDSA (FeedbackDelegate and the standard 1271 smart-EOA pattern).\n signature = (await wallet.signTypedData(JSON.stringify(typedData))).signature;\n }\n\n // Raw JSON (NOT base64): the backend relays this verbatim to the\n // Facilitator /settle after validating payer/amount/receiver.\n return JSON.stringify({\n x402Version: 2,\n scheme: 'escrow',\n payload: {\n authorization: {\n from: payer,\n to: tokenCollector,\n value: maxAmount.toString(),\n validAfter: '0',\n validBefore: String(paymentInfo.preApprovalExpiry),\n nonce: nonce,\n },\n signature: signature,\n paymentInfo: paymentInfo,\n },\n paymentRequirements: {\n scheme: 'escrow',\n network: `eip155:${cfg.chain_id}`,\n },\n });\n}\n","/**\n * EIP-7702: make a DELEGATED EOA's EIP-3009 signature settle again.\n *\n * **THE PROBLEM.** A gasless-wallet provider's first sponsored operation on a\n * chain may delegate the user's EOA (EIP-7702) to a smart-account\n * implementation — Alchemy's `SemiModularAccount7702` (`0x69007702…`) is the one\n * seen in the wild. From then on the address HAS code, so Circle's USDC (and any\n * `SignatureChecker` consumer) verifies signatures via **ERC-1271 only**. A raw\n * ECDSA authorization, however perfect, is rejected: `0x151d90fe`. The account is\n * not broken and the signature is not wrong — they simply no longer speak the\n * same dialect.\n *\n * Consequence for anything x402: a delegated payer's `transferWithAuthorization`\n * / `receiveWithAuthorization` becomes **unsettleable on-chain**, so direct x402\n * payments AND marketplace escrow locks both fail. Measured in production\n * 2026-07-31: 14 of 14 delegated agents failed their escrow lock; the one\n * non-delegated agent locked fine. The failure is silent in the worst way — the\n * sellers looked broken and they were correct.\n *\n * **THE FIX** (verified on-chain; the wallet provider needs to change nothing).\n * That account's `isValidSignature` DOES accept the EOA's own ECDSA — it just\n * wants it in the account's envelope. Two steps, both provable against the\n * verified source (`SemiModularAccountBase._exec1271Validation` +\n * `SparseCalldataSegmentLib`):\n *\n * 1. The account does not check `hash` directly; it checks a REPLAY-SAFE hash =\n * EIP-712 over the account's OWN domain\n * `EIP712Domain(uint256 chainId, address verifyingContract=account)` with\n * struct `ReplaySafeHash(bytes32 hash)`. Sign THAT, not the transfer digest.\n * 2. Wrap the 65-byte signature with the account's fallback-validation locator:\n * `0x00 00000000` (validation type 0, entity id 0 = FALLBACK_VALIDATION_ID)\n * `FF` (RESERVED_VALIDATION_DATA_INDEX, the final segment) `00`\n * (SignatureType.EOA).\n *\n * Because step 1 is still an ordinary typed-data signature, a REMOTE signer (a\n * delegated agentic wallet) can produce it: the private key is never needed\n * locally.\n *\n * **THE WRAP IS DELEGATE-SPECIFIC, NOT \"delegated == wrap\".** This is the part\n * that bit us on 2026-08-25, and it is why this module exists in TypeScript at\n * all: the moment a worker rates an agent through the facilitator's EIP-7702\n * feedback rail, their EOA becomes delegated to Execution Market's\n * `FeedbackDelegate` — which validates PLAIN ECDSA\n * (`ECDSA.recover(hash, sig) == address(this)`). Wrapping that signature makes it\n * invalid, so *the act of rating would break the rater's next payment*. Same\n * silent-at-lock-time failure the wrap was built to fix, now caused by\n * over-applying it.\n *\n * **DETECTION IS INJECTABLE, ON PURPOSE.** Knowing whether an address is\n * delegated needs one `eth_getCode` — a chain read, and this SDK does not own an\n * RPC policy. So detection is a callable you pass in ({@link DelegationResolver}).\n * {@link rpcDelegationResolver} ships a default over `fetch`; a caller with its\n * own endpoints, proxy or rotation passes its own.\n *\n * **THE THIRD STATE IS LOAD-BEARING.** A resolver returns `true` / `false` /\n * **`null` = could not tell**. `null` must never collapse to \"not delegated\":\n * that is exactly how the original bug survived eight days — the resolver failed,\n * returned nothing, and the caller's `if (delegated)` read it as falsy and signed\n * raw. **An unreadable answer is not a negative answer.**\n *\n * Port of `uvd_x402_sdk.erc7702` (Python). Keep the two in step: they are the\n * same protocol seen from two languages, and a divergence here is a signature\n * that cannot settle.\n */\n\n/** EIP-7702 delegation designator. */\nexport const DELEGATE_PREFIX = 'ef0100';\n\n/**\n * Delegate targets whose ERC-1271 needs the account-envelope wrap.\n *\n * Only a known Alchemy SMA implementation needs it. Every other delegate signs\n * PLAIN (the standard 1271 \"smart-EOA\" pattern accepts the EOA's own ECDSA), and\n * if some exotic future delegate needs a third dialect it fails VISIBLY at lock\n * time — never silently.\n *\n * Notably NOT here: Execution Market's `FeedbackDelegate` (all nine deploys). An\n * account that has rated through the facilitator's rail is delegated to it and\n * must sign plain.\n */\nexport const SMA_WRAP_TARGETS: readonly string[] = [\n '0x69007702764179f14f51cdce752f4f775d74e139', // Alchemy SemiModularAccount7702\n];\n\n/**\n * `true` only when this delegate target needs the account-envelope wrap.\n *\n * A plain EOA (`target` null/undefined) and any other delegate — FeedbackDelegate,\n * a standard 1271 smart-EOA — do NOT: they take the ordinary ECDSA signature.\n */\nexport function needsAccountWrap(target: string | null | undefined): boolean {\n return !!target && SMA_WRAP_TARGETS.includes(target.toLowerCase());\n}\n\n/**\n * Account fallback-validation locator + final-segment marker + EOA signature type.\n *\n * - `0x00 00000000` — validation type 0, entity id 0 (FALLBACK_VALIDATION_LOOKUP_KEY)\n * - `0xFF` — RESERVED_VALIDATION_DATA_INDEX (getFinalSegment)\n * - `0x00` — SignatureType.EOA\n */\nconst WRAP_PREFIX = '00000000' + '00' + 'ff' + '00';\n\n/**\n * The delegate target this EOA's EIP-7702 code points at, or `null`.\n *\n * `null` for a plain EOA, for non-7702 code, and for anything unparseable — the\n * caller confirms the implementation before applying the wrap.\n */\nexport function delegateTarget(code: string | null | undefined): string | null {\n if (!code) return null;\n const h = (code.startsWith('0x') ? code.slice(2) : code).toLowerCase();\n if (!h.startsWith(DELEGATE_PREFIX) || h.length < 46) return null;\n return `0x${h.slice(6, 46)}`;\n}\n\n/** Wrap a 65-byte ECDSA signature in the account's fallback-EOA envelope. */\nexport function wrapSignature(innerSignature: string): string {\n const s = innerSignature.startsWith('0x') ? innerSignature.slice(2) : innerSignature;\n return `0x${WRAP_PREFIX}${s}`;\n}\n\n/**\n * The typed data whose signature the delegated account accepts.\n *\n * The domain is the ACCOUNT's own — `chainId` + `verifyingContract=account`, the\n * two fields its typehash declares — and the struct is\n * `ReplaySafeHash(bytes32 hash)` over the inner EIP-3009 digest. Signing THIS,\n * not the digest, is what validates.\n */\nexport function replaySafeTypedData(\n innerDigest: string,\n chainId: number,\n account: string\n): { domain: Record<string, unknown>; types: Record<string, unknown>; message: Record<string, unknown> } {\n return {\n domain: { chainId, verifyingContract: account },\n types: { ReplaySafeHash: [{ name: 'hash', type: 'bytes32' }] },\n message: { hash: innerDigest },\n };\n}\n\n/**\n * `(address, network) -> target | true | false | null`.\n *\n * Four answers, richer than a boolean on purpose: a resolver MAY return the\n * delegate **target address** (a string) instead of just `true` — that is what\n * lets the caller pick the right signing dialect (SMA wrap vs plain). `true` =\n * delegated, target unknown; `false` = not delegated; `null` = UNKNOWN\n * (unreadable chain), never \"no\".\n */\nexport type DelegationResolver = (\n address: string,\n network: string\n) => Promise<string | boolean | null> | (string | boolean | null);\n\n/**\n * A default resolver over plain JSON-RPC `eth_getCode`, using `fetch`.\n *\n * Rotates through `urls` and returns `null` when **every** endpoint failed: an\n * unreadable chain is not a \"not delegated\" verdict.\n *\n * A caller with its own RPC policy (a signed proxy, paid endpoints, per-chain\n * routing) should pass its own resolver instead; that is the whole point of the\n * injection.\n */\nexport function rpcDelegationResolver(\n urls: string | string[],\n timeoutMs = 6000\n): DelegationResolver {\n const endpoints = typeof urls === 'string' ? [urls] : [...urls];\n\n return async (address: string): Promise<string | boolean | null> => {\n const addr = (address || '').trim();\n if (!addr || endpoints.length === 0) return null;\n\n for (const url of endpoints) {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n try {\n const res = await fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n jsonrpc: '2.0',\n id: 1,\n method: 'eth_getCode',\n params: [addr.toLowerCase(), 'latest'],\n }),\n signal: controller.signal,\n });\n clearTimeout(timer);\n if (!res.ok) continue;\n const code = (await res.json())?.result;\n if (typeof code === 'string' && code.startsWith('0x')) {\n // Return the TARGET when delegated, so the caller can pick the signing\n // dialect; `false` for a plain EOA (readable, no delegation).\n return delegateTarget(code) ?? false;\n }\n } catch {\n clearTimeout(timer);\n // Rotate to the next endpoint. Exhausting them all is UNKNOWN, below.\n }\n }\n return null;\n };\n}\n\n/** `{ delegated, target }` for one address on one network. */\nexport interface DelegationVerdict {\n /** `null` = UNKNOWN. Never treat it as `false`. */\n delegated: boolean | null;\n /** The delegate implementation, when the resolver could name it. */\n target: string | null;\n}\n\n/**\n * Resolve one address's delegation on one network.\n *\n * - `{delegated: null, target: null}` — unknown (no resolver, or an unreadable\n * chain). NEVER \"no\".\n * - `{delegated: false, target: null}` — a plain EOA.\n * - `{delegated: true, target: '0x…'}` — delegated, and we know to WHAT (pick the\n * dialect from it).\n * - `{delegated: true, target: null}` — delegated, target unknown (a legacy\n * boolean-only resolver).\n */\nexport async function resolveDelegation(\n address: string,\n network: string,\n resolver?: DelegationResolver\n): Promise<DelegationVerdict> {\n if (!resolver) return { delegated: null, target: null };\n\n let v: string | boolean | null;\n try {\n v = await resolver(address, network);\n } catch {\n // A broken resolver is UNKNOWN, not a negative.\n return { delegated: null, target: null };\n }\n\n if (typeof v === 'string') {\n const t = v.trim();\n // Only a real 20-byte address counts as a target. A non-address string is\n // garbage, and garbage is UNKNOWN — never a verdict we sign on.\n if (/^0x[0-9a-fA-F]{40}$/.test(t)) return { delegated: true, target: t };\n return { delegated: null, target: null };\n }\n if (typeof v === 'boolean') return { delegated: v, target: null };\n return { delegated: null, target: null };\n}\n\n/**\n * `true` / `false` / `null` (**unknown**) for one address on one network.\n *\n * Without a resolver the answer is `null`, never `false`: \"nobody asked\" and \"the\n * address is a plain EOA\" are different facts and only one of them is safe to\n * sign on.\n */\nexport async function isDelegated(\n address: string,\n network: string,\n resolver?: DelegationResolver\n): Promise<boolean | null> {\n return (await resolveDelegation(address, network, resolver)).delegated;\n}\n","/**\n * uvd-x402-sdk - Signed lifecycle orders for `release` / `refundInEscrow`.\n *\n * Both actions move money that is ALREADY escrowed, so neither carries an\n * ERC-3009 signature: there is no transfer left to authorize. That left the\n * other half of the question open — who is entitled to ask for the move —\n * and the de-facto answer was \"whoever calls\". On 2026-08-30 a third party\n * probed exactly that: five calls with a fabricated `paymentInfo`, two of\n * them mined, gas spent.\n *\n * This module is the client half of the answer: an EIP-712 order signed by\n * the party the action belongs to, hung off `payload.lifecycleAuth`.\n *\n * >>> THE SIGNER IS INJECTED <<<\n * The SDK never reaches for a key on its own. Any adapter that can sign\n * typed data works — `EnvKeyAdapter` (server / CLI), `OWSWalletAdapter`, a\n * wagmi/viem wallet client in the browser ({@link wagmiLifecycleSigner}), a\n * KMS. In H2A/H2H the PAYER signs in their own browser with the same wallet\n * they paid with, and the marketplace merely transports the block.\n *\n * >>> TWO SHAPES, ONE ORDER <<<\n * `buildLifecycleAuth` does the whole ceremony in one call: it mints the\n * nonce and the deadline, signs through the injected adapter, and returns the\n * block. That is the server and the `wagmi` paths.\n *\n * A publisher's browser cannot use it. There the backend assembles the\n * document — nonce and deadline included — the browser signs whatever it was\n * handed, and gives back a signature and nothing else. That is\n * {@link buildLifecycleTypedData} on one side and\n * {@link lifecycleAuthFromSignature} on the other, and it produces the SAME\n * bytes as the one-call path for the same nonce and deadline, pinned in\n * `src/lifecycle-auth.test.ts`.\n *\n * Source of truth for the format is the facilitator, `x402-rs`\n * `src/payment_operator/lifecycle_auth.rs` (PR #21). The Python twin is\n * `uvd_x402_sdk.escrow_signing.build_lifecycle_auth` (0.78.0); the two must\n * produce byte-identical signatures, pinned here by the shared vector in\n * `src/lifecycle-auth.test.ts`.\n *\n * Facilitator rollout is by `ESCROW_LIFECYCLE_AUTH`: `off` (default, the\n * order is not looked at), `log` (verify when present, log the verdict,\n * never reject) and `enforce`. That is why `lifecycleSigner` is OPTIONAL\n * everywhere: without one, the request goes out byte-for-byte as before.\n *\n * @example Server-side (EnvKeyAdapter)\n * ```typescript\n * import { buildLifecycleAuth, EnvKeyAdapter } from 'uvd-x402-sdk';\n *\n * const auth = await buildLifecycleAuth({\n * action: 'release',\n * paymentInfo: pi, // the SAME camelCase object that is sent\n * payer: payerAddress, // payload.payer — NOT inside paymentInfo\n * amount: '1000000', // the SAME as payload.amount\n * chainId: 8453,\n * wallet: new EnvKeyAdapter(),\n * });\n * // -> payload.lifecycleAuth = auth\n * ```\n */\n\nimport { ethers } from 'ethers';\nimport { X402Error } from './types';\n\n// ============================================================================\n// CONSTANTS — mirrored from lifecycle_auth.rs, do not \"clean up\"\n// ============================================================================\n\n/**\n * EIP-712 domain. `chainId` is the payment network's; there is NO\n * `verifyingContract` because `paymentInfo.operator` already rides inside the\n * signed struct. Copied from `lifecycle_auth.rs:69-70` (DOMAIN_NAME /\n * DOMAIN_VERSION).\n */\nexport const LIFECYCLE_DOMAIN_NAME = 'x402 escrow lifecycle';\nexport const LIFECYCLE_DOMAIN_VERSION = '1';\n\n/**\n * The facilitator's `deadline` ceiling: 900 s (`lifecycle_auth.rs:64`,\n * `DEFAULT_MAX_DEADLINE_SECS`). A leaked order is not a standing permission.\n */\nexport const LIFECYCLE_MAX_DEADLINE_SECS = 900;\n\n/**\n * What we sign by default, leaving 300 s of headroom under the ceiling.\n * Signing the full 900 s is an order that a facilitator clock five seconds\n * behind already reads as `deadline_too_far`: the margin is not cosmetic, it\n * is what separates a valid order from a rejection the caller cannot explain.\n */\nexport const LIFECYCLE_DEFAULT_DEADLINE_SECS = 600;\n\n/** The two wire values, which are also what enters the signature. */\nexport const LIFECYCLE_ACTIONS = ['release', 'refundInEscrow'] as const;\n\nexport type LifecycleAction = (typeof LIFECYCLE_ACTIONS)[number];\n\n/**\n * The EIP-712 types. `PaymentInfo` is the AuthCaptureEscrow type string\n * VERBATIM — the same one this SDK already types for ERC-3009. The field\n * ORDER is part of the type hash: reordering it invalidates every order ever\n * issued. Exact mirror of `lifecycle_auth.rs:73-99`.\n */\nexport const LIFECYCLE_ORDER_TYPES: Record<string, Array<{ name: string; type: string }>> = {\n LifecycleOrder: [\n { name: 'action', type: 'string' },\n { name: 'amount', type: 'uint256' },\n { name: 'deadline', type: 'uint256' },\n { name: 'nonce', type: 'bytes32' },\n { name: 'paymentInfo', type: 'PaymentInfo' },\n ],\n PaymentInfo: [\n { name: 'operator', type: 'address' },\n { name: 'payer', type: 'address' },\n { name: 'receiver', type: 'address' },\n { name: 'token', type: 'address' },\n { name: 'maxAmount', type: 'uint120' },\n { name: 'preApprovalExpiry', type: 'uint48' },\n { name: 'authorizationExpiry', type: 'uint48' },\n { name: 'refundExpiry', type: 'uint48' },\n { name: 'minFeeBps', type: 'uint16' },\n { name: 'maxFeeBps', type: 'uint16' },\n { name: 'feeReceiver', type: 'address' },\n { name: 'salt', type: 'uint256' },\n ],\n};\n\n/**\n * The 11 keys the wire `paymentInfo` MUST carry. `payer` is not among them:\n * it travels as a sibling (`payload.payer`), not inside paymentInfo — that is\n * how the facilitator assembles it (`ContractPaymentInfo::from_lifecycle_payload`,\n * `types.rs:275-290`).\n */\nconst LIFECYCLE_PI_KEYS = [\n 'operator',\n 'receiver',\n 'token',\n 'maxAmount',\n 'preApprovalExpiry',\n 'authorizationExpiry',\n 'refundExpiry',\n 'minFeeBps',\n 'maxFeeBps',\n 'feeReceiver',\n 'salt',\n] as const;\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\n/** The wire `paymentInfo` of a lifecycle request (camelCase, `salt` in hex). */\nexport interface LifecyclePaymentInfo {\n operator: string;\n receiver: string;\n token: string;\n /** Atomic units (uint120 on-chain). */\n maxAmount: string | number | bigint;\n preApprovalExpiry: number | string;\n authorizationExpiry: number | string;\n refundExpiry: number | string;\n minFeeBps: number | string;\n maxFeeBps: number | string;\n feeReceiver: string;\n /** 32-byte hex on the wire; uint256 in the signature. */\n salt: string | number | bigint;\n}\n\n/**\n * Minimal signer for {@link buildLifecycleAuth}: an address plus EIP-712\n * typed-data signing over the full typed-data JSON string. This is the same\n * contract as `SigningWalletAdapter`, so `EnvKeyAdapter` and\n * `OWSWalletAdapter` satisfy it structurally, and a browser wallet only has\n * to wrap its own `signTypedData` in this shape — the key never leaves it.\n */\nexport interface LifecycleSigner {\n /** The EVM address that will be claimed as `lifecycleAuth.signer`. */\n getAddress(): string;\n /** Sign the full EIP-712 JSON (`domain`, `types`, `primaryType`, `message`). */\n signTypedData(typedData: string): Promise<{ signature: string }>;\n}\n\n/** The block that goes in `payload.lifecycleAuth`. */\nexport interface LifecycleAuth {\n /** Who claims to have signed. Checked against the recovered address. */\n signer: string;\n /** Unix seconds after which the order is dead. */\n deadline: number;\n /** 32-byte hex replay guard, consumed by the facilitator on success. */\n nonce: string;\n /** 65-byte EIP-712 signature over the `LifecycleOrder`. */\n signature: string;\n}\n\nexport interface LifecycleTypedDataParams {\n /** `'release'` or `'refundInEscrow'`. */\n action: LifecycleAction;\n /**\n * The paymentInfo EXACTLY as it is serialized on the wire. This same object\n * is signed, which is what keeps the two ends from drifting.\n */\n paymentInfo: LifecyclePaymentInfo;\n /** The escrow's payer — travels as `payload.payer`, not inside paymentInfo. */\n payer: string;\n /** Atomic amount, the SAME one as `payload.amount`. */\n amount: string | number | bigint;\n /** EVM chain id of the payment network. */\n chainId: number;\n /**\n * Unix seconds after which the order is dead. Default: `now + 600`, which\n * leaves 300 s of headroom under the facilitator's 900 s ceiling.\n */\n deadline?: number;\n /**\n * 32 bytes, hex. Default: a fresh random one. Distinct PER ORDER — the\n * facilitator consumes it on acceptance.\n */\n nonce?: string;\n /** Unix seconds, for the `deadline` default and for tests. Default: the clock. */\n now?: number;\n}\n\n/**\n * The EIP-712 document itself: what {@link buildLifecycleTypedData} returns and\n * what {@link lifecycleAuthFromSignature} reads back.\n *\n * Named because it is a WIRE type in the split flow: a backend builds it,\n * ships it to a browser as JSON, and the browser hands it to `signTypedData`.\n * `types` carries no `EIP712Domain` entry — ethers and viem both derive that\n * one, and including it makes ethers throw `ambiguous primary types`.\n */\nexport interface LifecycleTypedData {\n domain: { name: string; version: string; chainId: number };\n types: Record<string, Array<{ name: string; type: string }>>;\n primaryType: 'LifecycleOrder';\n message: Record<string, unknown>;\n}\n\nexport interface BuildLifecycleAuthParams extends LifecycleTypedDataParams {\n /**\n * The signer. Must be the payer, the receiver or the operator owner\n * depending on the action — see the table in the module docblock.\n */\n wallet: LifecycleSigner;\n}\n\n// ============================================================================\n// COERCIONS — each one is a rejection the caller cannot see\n// ============================================================================\n\n/**\n * `salt` is bytes32 on the wire and uint256 in the signature.\n *\n * The facilitator converts it with `U256::from_be_bytes` (`types.rs:288`):\n * the wire hex enters the signed struct as an INTEGER. Signing it as a\n * string yields a different digest and a mute `bad_signature` whose only\n * symptom is that no order ever verifies.\n */\nfunction saltToBigInt(salt: unknown): bigint {\n if (typeof salt === 'bigint') return salt;\n if (typeof salt === 'number') {\n if (!Number.isInteger(salt) || salt < 0) {\n throw new X402Error(`paymentInfo.salt invalid: ${String(salt)}`, 'INVALID_CONFIG');\n }\n return BigInt(salt);\n }\n if (typeof salt === 'string') {\n const trimmed = salt.trim();\n // A bare hex string with no 0x is still hex here: that is how the wire\n // carries it in some payloads, and reading it as decimal would sign a\n // different struct than the one that is sent.\n const hex = trimmed.startsWith('0x') || trimmed.startsWith('0X') ? trimmed : `0x${trimmed}`;\n try {\n return BigInt(hex);\n } catch {\n throw new X402Error(`paymentInfo.salt invalid: ${salt}`, 'INVALID_CONFIG');\n }\n }\n throw new X402Error(`paymentInfo.salt invalid: ${String(salt)}`, 'INVALID_CONFIG');\n}\n\n/** 32-byte hex, lowercase, 0x-prefixed — or a throw naming the real length. */\nfunction nonceToBytes32(nonce: unknown): string {\n if (typeof nonce !== 'string') {\n throw new X402Error(`lifecycleAuth.nonce invalid: ${String(nonce)}`, 'INVALID_CONFIG');\n }\n const raw = nonce.startsWith('0x') || nonce.startsWith('0X') ? nonce.slice(2) : nonce;\n if (!/^[0-9a-fA-F]*$/.test(raw)) {\n throw new X402Error(`lifecycleAuth.nonce is not hex: ${nonce}`, 'INVALID_CONFIG');\n }\n if (raw.length !== 64) {\n throw new X402Error(\n `lifecycleAuth.nonce must be 32 bytes, got ${raw.length / 2}`,\n 'INVALID_CONFIG'\n );\n }\n return `0x${raw.toLowerCase()}`;\n}\n\n/** 32 random bytes as 0x-hex (WebCrypto when available, ethers otherwise). */\nfunction randomNonce(): string {\n const webCrypto = (globalThis as { crypto?: Crypto }).crypto;\n if (webCrypto?.getRandomValues) {\n const bytes = new Uint8Array(32);\n webCrypto.getRandomValues(bytes);\n return ethers.hexlify(bytes);\n }\n return ethers.hexlify(ethers.randomBytes(32));\n}\n\n/**\n * The two values that must be IDENTICAL in the signed document and in the\n * `lifecycleAuth` block, resolved in ONE place so the two entry points cannot\n * drift. {@link buildLifecycleAuth} needs them before signing; the split\n * browser flow reads them back out of the document it built.\n */\nfunction resolveOrderTiming(params: { deadline?: number; nonce?: string; now?: number }): {\n nowSec: number;\n deadline: number;\n nonce: string;\n} {\n const nowSec = params.now === undefined ? Math.floor(Date.now() / 1000) : Math.floor(params.now);\n return {\n nowSec,\n deadline:\n params.deadline === undefined\n ? nowSec + LIFECYCLE_DEFAULT_DEADLINE_SECS\n : Math.floor(params.deadline),\n nonce: params.nonce === undefined ? randomNonce() : params.nonce,\n };\n}\n\nfunction toUintString(value: unknown, field: string): string {\n let n: bigint;\n try {\n n = typeof value === 'bigint' ? value : BigInt(value as string | number);\n } catch {\n throw new X402Error(`${field} must be a non-negative integer, got ${String(value)}`, 'INVALID_CONFIG');\n }\n if (n < 0n) {\n throw new X402Error(`${field} must be a non-negative integer, got ${String(value)}`, 'INVALID_CONFIG');\n }\n return n.toString();\n}\n\n// ============================================================================\n// TYPED DATA\n// ============================================================================\n\n/**\n * The exact EIP-712 document a lifecycle order signs.\n *\n * Kept separate from {@link buildLifecycleAuth} because it is the useful\n * seam: it is what the Python twin mirrors, what a test can poke field by\n * field to confirm the signature stops verifying, and — the reason it is\n * PUBLIC — what a backend hands to a browser that signs.\n *\n * {@link buildLifecycleAuth} cannot serve that browser: it takes an injected\n * `WalletAdapter` and mints its own nonce and deadline, while a publisher\n * signs a document the backend already assembled and hands back only a\n * signature. Build it here, ship it, and reassemble the wire block with\n * {@link lifecycleAuthFromSignature} — which reads `deadline` and `nonce`\n * back out of this same document, so the two cannot disagree.\n *\n * @example The split flow, backend half\n * ```typescript\n * const typedData = buildLifecycleTypedData({\n * action: 'release',\n * paymentInfo: pi, // the SAME object that will be sent\n * payer, // payload.payer\n * amount, // the SAME as payload.amount\n * chainId: 8453,\n * }); // deadline -> now + 600, nonce -> 32 fresh bytes\n * // -> res.json({ typedData }) ... the browser signs it and posts back a signature\n * const lifecycleAuth = lifecycleAuthFromSignature(typedData, signature, payer);\n * ```\n *\n * @throws {X402Error} `INVALID_CONFIG` on an unknown action or a paymentInfo\n * missing a field; `INVALID_AMOUNT` on a negative amount. Nothing IN THE\n * SIGNED STRUCT is defaulted: an invented field is a signature over a\n * different struct than the one that is sent, i.e. a rejection the caller\n * cannot diagnose. `deadline` and `nonce` are the exception because they\n * exist nowhere else — they are born here and read back from the document.\n */\nexport function buildLifecycleTypedData(params: LifecycleTypedDataParams): LifecycleTypedData {\n const { action, paymentInfo, payer, amount, chainId } = params;\n const { deadline, nonce } = resolveOrderTiming(params);\n\n if (!LIFECYCLE_ACTIONS.includes(action)) {\n throw new X402Error(\n `unknown lifecycle action ${String(action)}; the facilitator only signs ${LIFECYCLE_ACTIONS.join(', ')}`,\n 'INVALID_CONFIG'\n );\n }\n\n let amountBig: bigint;\n try {\n amountBig = typeof amount === 'bigint' ? amount : BigInt(amount);\n } catch {\n throw new X402Error(`amount must be an integer >= 0, got ${String(amount)}`, 'INVALID_AMOUNT');\n }\n if (amountBig < 0n) {\n throw new X402Error(`amount must be an integer >= 0, got ${String(amount)}`, 'INVALID_AMOUNT');\n }\n\n const pi = (paymentInfo ?? {}) as unknown as Record<string, unknown>;\n const missing = LIFECYCLE_PI_KEYS.filter((k) => pi[k] === undefined);\n if (missing.length > 0) {\n throw new X402Error(\n `paymentInfo is missing fields that enter the signature: ${missing.join(', ')}. ` +\n 'The paymentInfo that is SENT is the one that is signed; defaulting a field would ' +\n 'sign a different struct than the one that reaches the facilitator.',\n 'INVALID_CONFIG'\n );\n }\n\n return {\n domain: {\n name: LIFECYCLE_DOMAIN_NAME,\n version: LIFECYCLE_DOMAIN_VERSION,\n chainId: Number(chainId),\n },\n types: LIFECYCLE_ORDER_TYPES,\n primaryType: 'LifecycleOrder',\n message: {\n action,\n amount: amountBig.toString(),\n deadline: toUintString(deadline, 'deadline'),\n nonce: nonceToBytes32(nonce),\n paymentInfo: {\n operator: ethers.getAddress(paymentInfo.operator),\n payer: ethers.getAddress(payer),\n receiver: ethers.getAddress(paymentInfo.receiver),\n token: ethers.getAddress(paymentInfo.token),\n maxAmount: toUintString(paymentInfo.maxAmount, 'paymentInfo.maxAmount'),\n preApprovalExpiry: toUintString(paymentInfo.preApprovalExpiry, 'paymentInfo.preApprovalExpiry'),\n authorizationExpiry: toUintString(\n paymentInfo.authorizationExpiry,\n 'paymentInfo.authorizationExpiry'\n ),\n refundExpiry: toUintString(paymentInfo.refundExpiry, 'paymentInfo.refundExpiry'),\n minFeeBps: toUintString(paymentInfo.minFeeBps, 'paymentInfo.minFeeBps'),\n maxFeeBps: toUintString(paymentInfo.maxFeeBps, 'paymentInfo.maxFeeBps'),\n feeReceiver: ethers.getAddress(paymentInfo.feeReceiver),\n // uint256 in the signature, bytes32 on the wire — see saltToBigInt.\n salt: saltToBigInt(paymentInfo.salt).toString(),\n },\n },\n };\n}\n\n// ============================================================================\n// THE ORDER\n// ============================================================================\n\n/**\n * Sign the order and return the complete `payload.lifecycleAuth` block.\n *\n * This is the first link of enforce: the facilitator already verifies these\n * orders in `log` mode and measured ZERO signatures across 17 days of traffic\n * (2,953 release/refund, 22 payers, 9 networks) — the field did not exist and\n * nobody sent it. Under `enforce` today, 100% would be rejected.\n *\n * The signer is INJECTED; the SDK does not read keys from the environment.\n *\n * @throws {X402Error} `INVALID_CONFIG` if the deadline has already passed or\n * sits past the facilitator's 900 s ceiling. It fails HERE and not there:\n * an out-of-window order is an `expired` / `deadline_too_far` that under\n * `enforce` is stuck money, and the caller has no log to see it in.\n */\nexport async function buildLifecycleAuth(\n params: BuildLifecycleAuthParams\n): Promise<LifecycleAuth> {\n const { wallet, ...rest } = params;\n\n const { nowSec, deadline: dl, nonce: nonceHex } = resolveOrderTiming(params);\n\n if (dl < nowSec) {\n throw new X402Error(\n `deadline ${dl} is in the past (now ${nowSec}): the facilitator discards it as \\`expired\\``,\n 'INVALID_CONFIG'\n );\n }\n if (dl - nowSec > LIFECYCLE_MAX_DEADLINE_SECS) {\n throw new X402Error(\n `deadline ${dl} is ${dl - nowSec} s ahead and the facilitator's ceiling is ` +\n `${LIFECYCLE_MAX_DEADLINE_SECS} s (\\`deadline_too_far\\`): a leaked order cannot be a ` +\n 'standing permission',\n 'INVALID_CONFIG'\n );\n }\n\n const typed = buildLifecycleTypedData({ ...rest, deadline: dl, nonce: nonceHex });\n const signed = await wallet.signTypedData(JSON.stringify(typed));\n\n return {\n signer: wallet.getAddress(),\n deadline: dl,\n nonce: nonceToBytes32(nonceHex),\n signature: signed.signature,\n };\n}\n\n/**\n * Reassemble `payload.lifecycleAuth` from a document that was signed\n * ELSEWHERE — the other half of the split flow.\n *\n * `buildLifecycleAuth` owns the whole ceremony: it mints the nonce and the\n * deadline, signs, and returns the block. A publisher's browser owns none of\n * that. It receives a document the backend already assembled and gives back\n * one string. This is the seam where that string becomes a wire block.\n *\n * `deadline` and `nonce` are NOT parameters: they are read out of\n * `typedData.message`, which is the document that was actually hashed. Taking\n * them from the caller would let the block claim a nonce the signature never\n * committed to — a `bad_signature` the caller cannot see, because both halves\n * look right on their own.\n *\n * The signature is NOT recovered here. This SDK's payers include ERC-7702\n * delegated accounts and contract wallets that validate through ERC-1271\n * (`src/erc7702.ts:8`), whose signatures do not ecrecover to their address;\n * `ethers.verifyTypedData` would reject the good ones. Recovery — and the\n * role check that goes with it — is the facilitator's, against the chain.\n *\n * @param typedData - what {@link buildLifecycleTypedData} returned, unmodified.\n * @param signature - the 0x-hex the wallet gave back (`signTypedData`).\n * @param signer - the address that signed, claimed in the block and checked\n * against the recovered one by the facilitator.\n *\n * @throws {X402Error} `INVALID_CONFIG` if the document is not a\n * `LifecycleOrder` for this domain, if the signature is not hex, or if the\n * signer is not an address.\n *\n * @example The browser half\n * ```typescript\n * const signature = await walletClient.signTypedData({\n * domain: typedData.domain,\n * types: typedData.types,\n * primaryType: typedData.primaryType,\n * message: typedData.message,\n * });\n * const lifecycleAuth = lifecycleAuthFromSignature(typedData, signature, address);\n * ```\n */\nexport function lifecycleAuthFromSignature(\n typedData: LifecycleTypedData,\n signature: string,\n signer: string\n): LifecycleAuth {\n const td = (typedData ?? {}) as Partial<LifecycleTypedData>;\n const message = (td.message ?? {}) as Record<string, unknown>;\n\n // A payment's typed data would sail through the shape checks below and\n // produce a block over the wrong struct entirely, so the document is\n // identified before anything is read out of it.\n if (td.primaryType !== 'LifecycleOrder') {\n throw new X402Error(\n `typedData.primaryType must be LifecycleOrder, got ${String(td.primaryType)}: ` +\n 'pass the document buildLifecycleTypedData returned, unmodified',\n 'INVALID_CONFIG'\n );\n }\n const domain = (td.domain ?? {}) as Record<string, unknown>;\n if (\n domain.name !== LIFECYCLE_DOMAIN_NAME ||\n String(domain.version) !== LIFECYCLE_DOMAIN_VERSION\n ) {\n throw new X402Error(\n `typedData.domain must be ${LIFECYCLE_DOMAIN_NAME} v${LIFECYCLE_DOMAIN_VERSION}, got ` +\n `${String(domain.name)} v${String(domain.version)}`,\n 'INVALID_CONFIG'\n );\n }\n if (message.deadline === undefined || message.nonce === undefined) {\n throw new X402Error(\n 'typedData.message carries no deadline/nonce: the wire block reads them from the ' +\n 'document that was signed, it does not invent them',\n 'INVALID_CONFIG'\n );\n }\n\n // uint256 in the signature, a JSON number on the wire. The facilitator's\n // block is typed `u64`, so a deadline that lost precision here is an\n // `expired` on an order whose signature is perfectly good.\n const deadlineBig = BigInt(toUintString(message.deadline, 'typedData.message.deadline'));\n if (deadlineBig > BigInt(Number.MAX_SAFE_INTEGER)) {\n throw new X402Error(\n `typedData.message.deadline ${deadlineBig} does not fit a JSON number`,\n 'INVALID_CONFIG'\n );\n }\n\n if (typeof signature !== 'string' || !/^0x[0-9a-fA-F]+$/.test(signature) ||\n signature.length % 2 !== 0) {\n throw new X402Error(\n `signature must be 0x-prefixed hex, got ${String(signature)}`,\n 'INVALID_CONFIG'\n );\n }\n\n let checksummed: string;\n try {\n checksummed = ethers.getAddress(signer);\n } catch {\n throw new X402Error(`signer is not an EVM address: ${String(signer)}`, 'INVALID_CONFIG');\n }\n\n return {\n signer: checksummed,\n deadline: Number(deadlineBig),\n nonce: nonceToBytes32(message.nonce),\n signature,\n };\n}\n\n// ============================================================================\n// BROWSER SIGNERS\n// ============================================================================\n\n/**\n * Minimal wagmi/viem wallet client: what {@link wagmiLifecycleSigner} needs.\n *\n * Deliberately narrower than this SDK's payment `WalletClient`: a lifecycle\n * domain has NO `verifyingContract`, so a client typed to require one cannot\n * sign these orders.\n */\nexport interface WagmiLifecycleWalletClient {\n account?: { address: string } | null;\n signTypedData(args: {\n domain: Record<string, unknown>;\n types: Record<string, Array<{ name: string; type: string }>>;\n primaryType: string;\n message: Record<string, unknown>;\n }): Promise<string>;\n}\n\n/**\n * Wrap a wagmi/viem wallet client as a {@link LifecycleSigner}, so the PAYER\n * signs the order in their own browser with the same wallet they paid with,\n * and the marketplace only transports the block.\n *\n * @param walletClient - from `useWalletClient()` (wagmi) or `createWalletClient` (viem).\n * @param address - the signing account; defaults to `walletClient.account.address`.\n *\n * @example\n * ```typescript\n * const { data: walletClient } = useWalletClient();\n * const auth = await buildLifecycleAuth({\n * action: 'release',\n * paymentInfo: pi,\n * payer: address,\n * amount: task.bountyAtomic,\n * chainId: 8453,\n * wallet: wagmiLifecycleSigner(walletClient!),\n * });\n * await fetch('/api/tasks/x/approve', {\n * method: 'POST',\n * body: JSON.stringify({ lifecycleAuth: auth }),\n * });\n * ```\n */\nexport function wagmiLifecycleSigner(\n walletClient: WagmiLifecycleWalletClient,\n address?: string\n): LifecycleSigner {\n const account = address ?? walletClient.account?.address;\n if (!account) {\n throw new X402Error(\n 'wagmiLifecycleSigner needs an account: pass one, or connect the wallet client first',\n 'INVALID_CONFIG'\n );\n }\n const checksummed = ethers.getAddress(account);\n return {\n getAddress: () => checksummed,\n async signTypedData(typedData: string) {\n const parsed = JSON.parse(typedData) as {\n domain: Record<string, unknown>;\n types: Record<string, Array<{ name: string; type: string }>>;\n primaryType: string;\n message: Record<string, unknown>;\n };\n const signature = await walletClient.signTypedData({\n domain: parsed.domain,\n types: parsed.types,\n primaryType: parsed.primaryType,\n message: parsed.message,\n });\n return { signature };\n },\n };\n}\n","/** Native Hedera x402 v2/exact. Signing is offline; only the facilitator submits. */\nimport { formatUnits, parseUnits } from 'ethers';\nimport type { ChainConfig, PaymentInfo, TokenType, WalletAdapter, X402Version } from '../../types';\nimport { encodeBase64Json } from '../../utils/base64';\n\nexport const HEDERA_NETWORKS = {\n 'hedera:mainnet': { usdc: '0.0.456858', feePayer: '0.0.10868300', mirror: 'https://mainnet-public.mirrornode.hedera.com' },\n 'hedera:testnet': { usdc: '0.0.429274', feePayer: '0.0.10576385', mirror: 'https://testnet.mirrornode.hedera.com' },\n} as const;\nexport type HederaNetwork = keyof typeof HEDERA_NETWORKS;\n/** Historical identifier; HBAR is for network fees, not supported payments. */\nexport const HBAR_ASSET = '0.0.0';\nconst MAX_AMOUNT = (1n << 63n) - 1n;\n\nexport interface HederaRequirements {\n scheme: 'exact'; network: HederaNetwork; asset: string; amount: string;\n payTo: string; maxTimeoutSeconds: number; extra: { feePayer: string };\n}\nexport interface HederaPaymentPayload {\n x402Version: 2; accepted: HederaRequirements;\n resource?: { url: string; description?: string; mimeType?: string };\n payload: { transaction: string };\n}\nfunction account(value: unknown): string {\n if (typeof value !== 'string' || !/^0\\.0\\.[1-9][0-9]*$/.test(value) || BigInt(value.split('.')[2]) > MAX_AMOUNT) {\n throw new Error('Hedera accounts must be canonical numeric IDs: 0.0.123');\n }\n return value;\n}\nfunction networkInfo(network: string) {\n if (!Object.hasOwn(HEDERA_NETWORKS, network)) throw new Error('Expected hedera:mainnet or hedera:testnet');\n return HEDERA_NETWORKS[network as HederaNetwork];\n}\n/** Validate the entire offer before any signing or network call. */\nexport function validateHederaRequirements(input: unknown): HederaRequirements {\n if (!input || typeof input !== 'object') throw new Error('Hedera requirements must be an object');\n const r = input as HederaRequirements;\n const fields = ['scheme', 'network', 'asset', 'amount', 'payTo', 'maxTimeoutSeconds', 'extra'];\n if (Object.keys(r).length !== fields.length || fields.some(k => !Object.hasOwn(r, k)) || r.scheme !== 'exact') {\n throw new Error('Hedera requires exact v2 requirements without extensions');\n }\n const info = networkInfo(r.network);\n if (r.asset !== info.usdc) throw new Error('Hedera payments support native USDC only; HBAR is for network fees');\n if (typeof r.amount !== 'string' || !/^[1-9][0-9]*$/.test(r.amount) || r.amount.length > 19 || BigInt(r.amount) > MAX_AMOUNT) {\n throw new Error('amount must be a positive canonical atomic integer string within int64');\n }\n if (!Number.isInteger(r.maxTimeoutSeconds) || r.maxTimeoutSeconds < 15 || r.maxTimeoutSeconds > 180) {\n throw new Error('Hedera maxTimeoutSeconds must be 15..180');\n }\n if (!r.extra || Object.keys(r.extra).length !== 1 || !Object.hasOwn(r.extra, 'feePayer')) {\n throw new Error('Hedera extra must contain only feePayer');\n }\n account(r.extra.feePayer); account(r.payTo);\n if (r.payTo === r.extra.feePayer) throw new Error('The fee payer must be distinct from the merchant');\n return { ...r, extra: { ...r.extra } };\n}\n/** Native USDC amounts have 6 decimals. HBAR is used only for network fees. */\nexport function buildHederaRequirements(options: {\n network: HederaNetwork; payTo: string; amountAtomic: string; asset?: 'usdc' | string;\n feePayer?: string; maxTimeoutSeconds?: number;\n}): HederaRequirements {\n const info = networkInfo(options.network);\n return validateHederaRequirements({\n scheme: 'exact', network: options.network,\n asset: !options.asset || options.asset === 'usdc' ? info.usdc : options.asset,\n amount: options.amountAtomic, payTo: options.payTo, maxTimeoutSeconds: options.maxTimeoutSeconds ?? 180,\n extra: { feePayer: options.feePayer ?? info.feePayer },\n });\n}\n/** Merchant /verify or /settle body. Pass the merchant's OWN offer, never the buyer's price. */\nexport function buildHederaRequest(paymentPayload: HederaPaymentPayload, requirements: HederaRequirements) {\n const r = validateHederaRequirements(requirements);\n const p = paymentPayload;\n const accepted = validateHederaRequirements(p.accepted);\n if (p.x402Version !== 2 || Object.keys(p).some(k => !['x402Version', 'accepted', 'resource', 'payload'].includes(k)) ||\n Object.keys(r).some(k => k === 'extra' ? r.extra.feePayer !== accepted.extra.feePayer : r[k as keyof HederaRequirements] !== accepted[k as keyof HederaRequirements])) {\n throw new Error('Hedera requires v2 and an exact accepted echo without extensions');\n }\n if (!p.payload || Object.keys(p.payload).length !== 1 || typeof p.payload.transaction !== 'string') {\n throw new Error('Hedera payload must contain only transaction');\n }\n return { x402Version: 2 as const, paymentPayload: p, paymentRequirements: r };\n}\n\n/** Native buyer adapter. The optional @hiero-ledger/sdk peer is loaded only when used. */\nexport class HederaProvider implements WalletAdapter {\n readonly id = 'hedera-native';\n readonly name = 'Hedera Native';\n readonly networkType = 'hedera' as const;\n readonly network: HederaNetwork;\n readonly accountId: string;\n readonly feePayer: string;\n private privateKey: string;\n private connected = false;\n\n constructor(options: { accountId: string; privateKey: string; network: HederaNetwork; feePayer?: string }) {\n const info = networkInfo(options.network);\n this.network = options.network;\n this.accountId = account(options.accountId);\n this.feePayer = account(options.feePayer ?? info.feePayer);\n if (this.accountId === this.feePayer) throw new Error('Buyer and fee payer must be distinct');\n this.privateKey = options.privateKey;\n // Keep key material out of JSON.stringify(provider), including diagnostic logs.\n Object.defineProperty(this, 'privateKey', { enumerable: false });\n }\n isAvailable(): boolean { return true; }\n async connect(chainName = this.network): Promise<string> {\n if (chainName !== this.network) throw new Error('Provider is bound to another Hedera ledger');\n await this.key();\n this.connected = true;\n return this.accountId;\n }\n async disconnect(): Promise<void> { this.connected = false; }\n getAddress(): string | null { return this.connected ? this.accountId : null; }\n\n private async key() {\n let sdk: typeof import('@hiero-ledger/sdk');\n try { sdk = await import('@hiero-ledger/sdk'); }\n catch { throw new Error('Install @hiero-ledger/sdk to sign native Hedera payments'); }\n try { return { sdk, key: sdk.PrivateKey.fromStringDer(this.privateKey) }; }\n catch { throw new Error('Invalid Hedera DER private key (value redacted)'); }\n }\n async createPaymentPayload(accepted: HederaRequirements, resource?: HederaPaymentPayload['resource']): Promise<HederaPaymentPayload> {\n const r = validateHederaRequirements(accepted);\n if (r.network !== this.network || r.extra.feePayer !== this.feePayer) throw new Error(\"Offer does not match the signer's ledger and trusted fee payer\");\n if (r.payTo === this.accountId) throw new Error('Buyer and merchant must be distinct');\n const { sdk, key } = await this.key();\n const tx = new sdk.TransferTransaction()\n .setTransactionId(sdk.TransactionId.generate(this.feePayer))\n .setNodeAccountIds(['0.0.3', '0.0.4', this.network === 'hedera:mainnet' ? '0.0.7' : '0.0.5'].map(n => sdk.AccountId.fromString(n)))\n .setTransactionValidDuration(r.maxTimeoutSeconds)\n .setMaxTransactionFee(sdk.Hbar.fromTinybars('100000000'))\n .setRegenerateTransactionId(false);\n tx.addTokenTransfer(r.asset, this.accountId, '-' + r.amount).addTokenTransfer(r.asset, r.payTo, r.amount);\n await tx.freeze().sign(key);\n // Browser-safe encoding; protobuf TransactionList, NOT a single Transaction.\n let binary = '';\n for (const byte of tx.toBytes()) binary += String.fromCharCode(byte);\n const p: HederaPaymentPayload = { x402Version: 2, accepted: r, payload: { transaction: btoa(binary) } };\n if (resource) p.resource = { ...resource };\n return p;\n }\n async signPayment(paymentInfo: PaymentInfo, chain: ChainConfig): Promise<string> {\n if (!this.connected) throw new Error('Hedera wallet is not connected');\n if (chain.name !== this.network || paymentInfo.x402Version === 1) throw new Error('Hedera requires this ledger and x402 v2');\n if (paymentInfo.extensions && Object.keys(paymentInfo.extensions).length) throw new Error('Hedera extensions are unsupported');\n if (!paymentInfo.accepted) throw new Error('Hedera signing requires the exact accepted offer from the 402');\n const r = validateHederaRequirements(paymentInfo.accepted);\n const tokenType = paymentInfo.tokenType ?? 'usdc';\n const asset = tokenType === 'usdc' ? networkInfo(this.network).usdc : '';\n if (r.asset !== asset || r.payTo !== paymentInfo.recipient || parseUnits(paymentInfo.amount, 6).toString() !== r.amount) {\n throw new Error('Offer does not match the approved recipient, asset and amount');\n }\n return JSON.stringify(await this.createPaymentPayload(r, paymentInfo.resource));\n }\n encodePaymentHeader(payload: string, chain: ChainConfig, version: X402Version = 2): string {\n if (version !== 2 || chain.name !== this.network) throw new Error('Hedera supports only x402 v2 on the bound ledger');\n const p = JSON.parse(payload) as HederaPaymentPayload;\n buildHederaRequest(p, p.accepted);\n return encodeBase64Json(p);\n }\n async getBalance(chain: ChainConfig, tokenType: TokenType = 'usdc'): Promise<string> {\n if (chain.name !== this.network) throw new Error('Provider is bound to another Hedera ledger');\n const info = networkInfo(this.network);\n if (!['usdc', 'hbar'].includes(tokenType)) throw new Error('Unsupported Hedera token');\n const path = tokenType === 'hbar' ? '' : `/tokens?token.id=${info.usdc}`;\n const response = await fetch(`${info.mirror}/api/v1/accounts/${this.accountId}${path}`, { signal: AbortSignal.timeout(15000) });\n if (!response.ok) throw new Error(`Hedera balance HTTP ${response.status}`);\n const data = await response.json();\n const amount = tokenType === 'hbar' ? data.balance?.balance : data.tokens?.[0]?.balance ?? 0;\n if (!Number.isSafeInteger(amount) || amount < 0) throw new Error('Mirror returned an unsafe balance');\n return formatUnits(BigInt(amount), tokenType === 'hbar' ? 8 : 6);\n }\n}\nexport default HederaProvider;\n","import { parseFacilitatorReceipt, receiptFromErrorBody, mergePaymentResponseHeaders, validatePurchaseContext, type FacilitatorReceipt } from \"../receipts\";\nimport { bytesToHex, randomBytes } from '@noble/hashes/utils';\nexport * from \"../receipts\";\nimport { parseUnits } from 'ethers';\nimport { buildHederaRequirements, type HederaNetwork } from '../providers/hedera';\n/**\n * uvd-x402-sdk - Backend Utilities\n *\n * Server-side utilities for building x402 payment APIs.\n * These utilities help backend developers:\n * - Build verify/settle requests for the facilitator\n * - Parse X-PAYMENT headers from incoming requests\n * - Configure CORS for x402 payment flows\n * - Create atomic payment handlers\n * - Discover and register resources via Bazaar Discovery API\n * - Manage escrow payments with refund and dispute resolution\n *\n * @example Basic payment flow\n * ```ts\n * import {\n * parsePaymentHeader,\n * FacilitatorClient,\n * X402_CORS_HEADERS,\n * } from 'uvd-x402-sdk/backend';\n *\n * // Parse payment from request header\n * const payment = parsePaymentHeader(req.headers['x-payment']);\n *\n * // Verify with facilitator\n * const client = new FacilitatorClient();\n * const verifyResult = await client.verify(payment, paymentRequirements);\n *\n * // If valid, provide service then settle\n * const settleResult = await client.settle(payment, paymentRequirements);\n * ```\n *\n * @example Escrow payment with refund support\n * ```ts\n * import { EscrowClient } from 'uvd-x402-sdk/backend';\n *\n * const escrow = new EscrowClient();\n *\n * // Hold payment in escrow\n * const escrowPayment = await escrow.createEscrow({\n * paymentHeader: req.headers['x-payment'],\n * requirements: paymentRequirements,\n * escrowDuration: 86400, // 24 hours\n * });\n *\n * // After service delivered, release to recipient\n * await escrow.release(escrowPayment.id);\n *\n * // Or if service failed, request refund\n * await escrow.requestRefund({\n * escrowId: escrowPayment.id,\n * reason: 'Service not delivered',\n * });\n * ```\n *\n * @example Resource discovery\n * ```ts\n * import { BazaarClient } from 'uvd-x402-sdk/backend';\n *\n * const bazaar = new BazaarClient();\n * const resources = await bazaar.discover({\n * category: 'ai',\n * network: 'base',\n * maxPrice: '0.10',\n * });\n * ```\n */\n\nimport type {\n X402Header,\n X402PayloadData,\n X402Version,\n} from '../types';\nimport { decodeX402Header, chainToCAIP2, parseNetworkIdentifier } from '../utils';\nimport {\n REVIEW_WINDOW_SEC,\n REFUND_WINDOW_SEC,\n DEFAULT_MIN_FEE_BPS,\n DEFAULT_MAX_FEE_BPS,\n OPERATOR_FEE_BPS,\n} from '../escrow-preauth';\nimport { buildLifecycleAuth } from '../lifecycle-auth';\nimport type {\n LifecycleAction,\n LifecycleAuth,\n LifecyclePaymentInfo,\n LifecycleSigner,\n} from '../lifecycle-auth';\nimport { X402Error } from '../types';\nimport { getChainByName, isUsdPegged, usdConversionError } from '../chains';\nimport {\n AUTHORIZATION_ALREADY_SETTLED,\n AUTHORIZATION_IN_FLIGHT,\n DEFAULT_RETRY_AFTER_SECONDS,\n SETTLEMENT_UNCONFIRMED,\n carryFailureFields,\n isAuthorizationAlreadyUsed,\n isAuthorizationInFlight,\n isReplayableLeaseReason,\n facilitatorFetch,\n failureFields,\n parseFacilitatorErrorBody,\n readFacilitatorError,\n} from './facilitator-error';\nimport type { FacilitatorErrorInfo, FacilitatorFailureFields } from './facilitator-error';\n\n// A facilitator refusal is DATA, not prose. `402` and `503` say opposite things\n// and this file used to answer both with `success: false` plus a sentence --\n// see ./facilitator-error.ts for why that costs the buyer a second payment.\nexport {\n AMBIGUOUS_LEASE_REASONS,\n AUTHORIZATION_ALREADY_SETTLED,\n AUTHORIZATION_IN_FLIGHT,\n DEFAULT_FACILITATOR_RETRIES,\n DEFAULT_RETRY_AFTER_SECONDS,\n MAX_RETRY_AFTER_SECONDS,\n RECEIPT_REQUEST_CONFLICT,\n REPLAYABLE_LEASE_REASONS,\n SETTLEMENT_UNCONFIRMED,\n WRITER_LEASE_REASONS,\n carryFailureFields,\n facilitatorFetch,\n isAmbiguousLeaseReason,\n isAuthorizationAlreadyUsed,\n isAuthorizationInFlight,\n isReplayableLeaseReason,\n isSettlementUnconfirmed,\n parseFacilitatorErrorBody,\n parseRetryAfterSeconds,\n readFacilitatorError,\n} from './facilitator-error';\nexport type {\n AdmittedAuthorizationCode,\n FacilitatorErrorInfo,\n FacilitatorFailureFields,\n FacilitatorFetchOptions,\n ParsedFacilitatorErrorBody,\n WriterLeaseReason,\n} from './facilitator-error';\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\n/**\n * Payment requirements sent to the facilitator\n */\nexport interface PaymentRequirements {\n /** Payment scheme */\n scheme: 'exact' | 'escrow' | 'commerce';\n /** Network name (v1) or CAIP-2 identifier (v2) */\n network: string;\n /** Maximum amount required in atomic units (e.g., \"1000000\" for 1 USDC) */\n maxAmountRequired: string;\n /** Resource URL being paid for */\n resource: string;\n /** Description of what's being paid for */\n description: string;\n /** MIME type of the resource */\n mimeType: string;\n /** Recipient address for payment */\n payTo: string;\n /** Maximum timeout in seconds */\n maxTimeoutSeconds: number;\n /** Token contract address */\n asset: string;\n /** Optional output schema for the resource */\n outputSchema?: unknown;\n /** Optional extra data */\n extra?: unknown;\n}\n\n/**\n * Verify request body for the facilitator /verify endpoint -- the **v1**\n * envelope. {@link VerifyRequestV2} is the other one.\n */\nexport interface VerifyRequest {\n /**\n * Always `1`: this marker names the ENVELOPE, and this envelope is v1.\n *\n * Narrowed from `X402Version` on 2026-09-04. A `VerifyRequest` carrying `2`\n * was always an uninhabitable value -- a body declaring v2 while shaped as\n * v1 -- and typing it as `1 | 2` is what let the payer's marker be copied in\n * here. The payer's version lives in `paymentPayload.x402Version`, which is\n * still the full union.\n */\n x402Version: 1;\n paymentPayload: X402Header;\n paymentRequirements: PaymentRequirements;\n}\n\n/**\n * Settle request body for the facilitator /settle endpoint -- the **v1**\n * envelope. {@link SettleRequestV2} is the other one.\n */\nexport interface SettleRequest {\n /** Always `1` -- see {@link VerifyRequest.x402Version}. */\n x402Version: 1;\n paymentPayload: X402Header;\n paymentRequirements: PaymentRequirements;\n}\n\n/**\n * Verify response from the facilitator\n */\nexport interface VerifyResponse extends FacilitatorFailureFields {\n receipt?: FacilitatorReceipt | null;\n isValid: boolean;\n /**\n * Why the payment is not valid.\n *\n * Read `retryable` before showing this to anyone. When `retryable` is true the\n * facilitator reached NO VERDICT -- it did not reject the payment, so this\n * string is a transport diagnosis, not a rejection, and re-signing on it makes\n * the buyer pay twice.\n */\n invalidReason?: string;\n payer?: string;\n network?: string;\n /**\n * The `Idempotency-Key` this verification carried. Settle the same payment\n * with it (`settle(..., { idempotencyKey })`) so both calls present one\n * purchase binding. Merchant-private: never forward it to the buyer.\n */\n idempotencyKey?: string;\n}\n\n/**\n * Settle response from the facilitator\n */\nexport interface SettleResponse extends FacilitatorFailureFields {\n receipt?: FacilitatorReceipt | null;\n success: boolean;\n transactionHash?: string;\n network?: string;\n /**\n * Transport-level failure (unreachable facilitator, non-2xx, timeout).\n *\n * `success: false` with `retryable: true` is NOT a rejected payment. The\n * authorization is untouched and the same one must be resent; treating it as\n * a refusal and asking for a new signature charges the buyer twice.\n */\n error?: string;\n /**\n * The facilitator's own reason when it settled nothing — e.g. a transfer that\n * mined and reverted. Distinct from `error` above, which is this client\n * failing to ask; this one is the facilitator answering \"no\".\n */\n errorReason?: string;\n /** The address the facilitator confirmed as the payer. */\n payer?: string;\n /**\n * Settlement proof, present when the ERC-8004 extension asked for it.\n *\n * Typed here rather than only on {@link SettleResponseWithProof} because\n * `settle()` returns it whenever the facilitator sends it, and it is what\n * DX402's `anchorEvidence` needs to reach `verified: true`.\n */\n proofOfPayment?: ProofOfPayment;\n /**\n * The facilitator answered `Idempotent-Replayed: true`: this is its stored\n * answer to an EARLIER settle of this authorization, and no new money moved.\n *\n * It is this caller's own purchase only when the call carried the binding\n * that admitted it -- the same `idempotencyKey`, or the same\n * `X-UVD-Purchase` context. A settle made with a fresh key and no context\n * cannot have admitted anything before, so this client, `verifyAndSettle`\n * and both middlewares answer such a replay as\n * {@link AUTHORIZATION_ALREADY_SETTLED} (or {@link AUTHORIZATION_IN_FLIGHT})\n * instead of a success: the resource must not be served again. Facilitators\n * from 2.39.0 refuse that resend with the same codes themselves.\n */\n replayed?: boolean;\n /**\n * The `Idempotency-Key` this settle carried. After a lost response, resend\n * the same payment with it to receive the original answer instead of a\n * `409`. Merchant-private: never forward it to the buyer.\n */\n idempotencyKey?: string;\n}\n\n/**\n * Options for building payment requirements\n */\nexport interface PaymentRequirementsOptions {\n /** Amount in human-readable format (e.g., \"1.00\") */\n amount: string;\n /** Recipient address */\n recipient: string;\n /** Resource URL being protected */\n resource: string;\n /** Chain name (e.g., \"base\") */\n chainName?: string;\n /** Description of the resource */\n description?: string;\n /** MIME type of the resource */\n mimeType?: string;\n /** Timeout in seconds (default: 300) */\n timeoutSeconds?: number;\n /** x402 version to use */\n x402Version?: X402Version;\n}\n\n/**\n * x402 payment option advertised in a 402 response.\n *\n * The SDK keeps the response shape richer than the minimal protocol fields so\n * servers can preserve settlement-critical metadata such as payTo and extra.\n */\nexport interface PaymentAcceptance {\n network: string;\n asset: string;\n amount: string;\n /**\n * Payment scheme. REQUIRED by the facilitator's v2 `PaymentRequirementsV2`.\n *\n * Optional here only so existing callers keep compiling — when it is absent,\n * `buildRequirementFromAcceptance` defaults it to `'exact'`. Do not treat its\n * optionality as \"the facilitator does not need it\": an accepts[] entry that\n * reaches a v2 client without a scheme is unpayable.\n */\n scheme?: string;\n payTo?: string;\n facilitator?: string;\n resource?: string;\n description?: string;\n mimeType?: string;\n maxTimeoutSeconds?: number;\n outputSchema?: unknown;\n extra?: unknown;\n}\n\n/**\n * Verified payment context attached by server middleware.\n */\nexport interface VerifiedPaymentState {\n payment: X402Header;\n requirements: PaymentRequirements;\n verifyResult: VerifyResponse;\n /**\n * Settles once; later calls return the same result. A facilitator replay that\n * this request did not bind (no `X-UVD-Purchase`) comes back as\n * {@link AUTHORIZATION_ALREADY_SETTLED} or {@link AUTHORIZATION_IN_FLIGHT},\n * never as a success, so a replayed X-PAYMENT is not served twice. The\n * receipt headers are added only while the response has not been sent.\n */\n settle: () => Promise<SettleResponse>;\n /** The key sent on this payment's `/verify` and `/settle`. Merchant-private. */\n idempotencyKey?: string;\n}\n\n/**\n * Shared server middleware options.\n */\nexport interface PaymentMiddlewareOptions extends FacilitatorClientOptions {\n /** Alias for baseUrl to keep middleware options ergonomic */\n facilitatorUrl?: string;\n /**\n * Settlement behavior after verification.\n * - manual: verify only; caller settles explicitly\n * - before-handler: settle immediately before calling next()\n */\n settlementStrategy?: 'manual' | 'before-handler';\n}\n\n/**\n * Custom resolver for selecting the correct payment requirement when multiple\n * accepts are advertised.\n */\nexport type PaymentRequirementResolver = (\n payment: X402Header,\n requirements: PaymentRequirements[]\n) => PaymentRequirements | null | Promise<PaymentRequirements | null>;\n\n// ============================================================================\n// HEADER PARSING\n// ============================================================================\n\n/**\n * Parse X-PAYMENT or PAYMENT-SIGNATURE header value\n *\n * @param headerValue - Base64-encoded header value (or undefined/null)\n * @returns Parsed x402 header object, or null if invalid\n *\n * @example\n * ```ts\n * // Express.js\n * const payment = parsePaymentHeader(req.headers['x-payment']);\n * if (!payment) {\n * return res.status(400).json({ error: 'Invalid payment header' });\n * }\n * ```\n */\nexport function parsePaymentHeader(\n headerValue: string | undefined | null\n): X402Header | null {\n if (!headerValue) {\n return null;\n }\n\n try {\n return decodeX402Header(headerValue);\n } catch {\n return null;\n }\n}\n\n/**\n * Extract payment header from request headers object\n *\n * Checks both X-PAYMENT and PAYMENT-SIGNATURE headers.\n *\n * @param headers - Request headers object (case-insensitive)\n * @returns Parsed x402 header object, or null if not found/invalid\n *\n * @example\n * ```ts\n * const payment = extractPaymentFromHeaders(req.headers);\n * ```\n */\nexport function extractPaymentFromHeaders(\n headers: Record<string, string | string[] | undefined>\n): X402Header | null {\n // Normalize header keys to lowercase\n const normalizedHeaders: Record<string, string> = {};\n for (const [key, value] of Object.entries(headers)) {\n if (typeof value === 'string') {\n normalizedHeaders[key.toLowerCase()] = value;\n } else if (Array.isArray(value) && value.length > 0) {\n normalizedHeaders[key.toLowerCase()] = value[0];\n }\n }\n\n // Try X-PAYMENT first, then PAYMENT-SIGNATURE\n const headerValue =\n normalizedHeaders['x-payment'] ||\n normalizedHeaders['payment-signature'];\n\n return parsePaymentHeader(headerValue);\n}\n\n// ============================================================================\n// REQUEST BUILDERS\n// ============================================================================\n\n/**\n * Build payment requirements for the facilitator\n *\n * @param options - Payment requirements options\n * @returns PaymentRequirements object ready for verify/settle\n *\n * @example\n * ```ts\n * const requirements = buildPaymentRequirements({\n * amount: '1.00',\n * recipient: '0x1234...',\n * resource: 'https://api.example.com/premium-data',\n * chainName: 'base',\n * });\n * ```\n */\nexport function buildPaymentRequirements(\n options: PaymentRequirementsOptions\n): PaymentRequirements {\n const {\n amount,\n recipient,\n resource,\n chainName = 'base',\n description = 'Payment for resource access',\n mimeType = 'application/json',\n timeoutSeconds = 300,\n x402Version = 1,\n } = options;\n\n const chain = getChainByName(chainName);\n if (!chain) {\n throw new Error(`Unsupported chain: ${chainName}`);\n }\n\n if (chain.networkType === 'hedera') {\n if (options.x402Version !== 2) throw new Error('Native Hedera supports only x402 v2');\n const native = buildHederaRequirements({ network: chain.name as HederaNetwork,\n payTo: recipient, amountAtomic: parseUnits(amount, 6).toString(),\n maxTimeoutSeconds: Math.min(options.timeoutSeconds ?? 180, 180) });\n return { scheme: 'exact', network: native.network, asset: native.asset,\n maxAmountRequired: native.amount, payTo: recipient, resource, description, mimeType,\n maxTimeoutSeconds: native.maxTimeoutSeconds, extra: native.extra };\n }\n\n // Convert amount to atomic units.\n //\n // Scaling by the decimals only turns dollars into base units when one whole\n // unit IS one dollar. On a chain that settles in its own floating native\n // asset it silently prices the call in that asset instead: XRPL registers\n // native XRP under the `usdc` key, so `\"10.00\"` used to bill 10 XRP. Refusing\n // is the only honest answer -- the SDK has no rate and inventing one would\n // charge a number nobody agreed to.\n if (!isUsdPegged(chain.usdc)) {\n throw new Error(usdConversionError(chain.name, chain.usdc));\n }\n const atomicAmount = Math.floor(\n parseFloat(amount) * Math.pow(10, chain.usdc.decimals)\n ).toString();\n\n // Use CAIP-2 for v2, chain name for v1\n const network = x402Version === 2 ? chainToCAIP2(chainName) : chainName;\n\n return {\n scheme: 'exact',\n network,\n maxAmountRequired: atomicAmount,\n resource,\n description,\n mimeType,\n payTo: recipient,\n maxTimeoutSeconds: timeoutSeconds,\n asset: chain.usdc.address,\n };\n}\n\n/**\n * Build a verify request for the facilitator /verify endpoint\n *\n * @param paymentHeader - Parsed x402 payment header\n * @param requirements - Payment requirements\n * @returns VerifyRequest body ready for fetch/axios\n *\n * @example\n * ```ts\n * const payment = parsePaymentHeader(req.headers['x-payment']);\n * const verifyBody = buildVerifyRequest(payment, requirements);\n *\n * const response = await fetch('https://facilitator.uvd.xyz/verify', {\n * method: 'POST',\n * headers: { 'Content-Type': 'application/json' },\n * body: JSON.stringify(verifyBody),\n * });\n * ```\n */\nexport function buildVerifyRequest(\n paymentHeader: X402Header,\n requirements: PaymentRequirements\n): VerifyRequest {\n return {\n // The literal `1` names THIS ENVELOPE, not the payer's header. Echoing\n // `paymentHeader.x402Version` here -- what this did until 2026-09-04 --\n // let a buyer who declared `2` produce a body that says \"2\" while carrying\n // `paymentRequirements`, which is the v1 shape. The facilitator serves it\n // anyway because its envelope enum is untagged and matches on shape, so\n // nothing broke; but it ALREADY picks the hint in its 400 off this marker:\n //\n // \"This body declares `x402Version: 2`. x402 v2 is a JSON object with\n // `paymentPayload`, `resource` and `accepted`...\"\n //\n // So the day that body fails for any other reason, the diagnosis sends the\n // integrator to document the wrong shape. That inversion -- being told to\n // fix the fields when the wrapper is what is wrong -- is what cost two\n // teams a day. The payer's own marker survives untouched inside\n // `paymentPayload`, where it belongs: it describes the payment, not the\n // envelope carrying it.\n x402Version: 1,\n paymentPayload: paymentHeader,\n paymentRequirements: requirements,\n };\n}\n\n/**\n * Build a settle request for the facilitator /settle endpoint\n *\n * @param paymentHeader - Parsed x402 payment header\n * @param requirements - Payment requirements\n * @returns SettleRequest body ready for fetch/axios\n */\n/**\n * Describes the protected resource, as x402 v2 expects it.\n *\n * Note this is an OBJECT in v2. Sending a bare URL string here is the single\n * most common v2 mistake and it fails as an unhelpful \"no variant matched\"\n * deserialization error at the facilitator, naming no field.\n */\nexport interface ResourceInfoV2 {\n url: string;\n description: string;\n mimeType: string;\n}\n\n/**\n * Payment requirements in x402 v2 form.\n *\n * Differences from v1 that actually bite:\n * - `network` is CAIP-2 (`eip155:8453`), NOT a plain name (`base`). Mixing a v1\n * name into a v2 request fails deserialization, and vice versa.\n * - `maxAmountRequired` is renamed to `amount`.\n * - `resource` / `description` / `mimeType` moved out to {@link ResourceInfoV2}.\n */\nexport interface PaymentRequirementsV2 {\n scheme: string;\n /** CAIP-2 chain id, e.g. `eip155:8453`. */\n network: string;\n asset: string;\n amount: string;\n payTo: string;\n maxTimeoutSeconds: number;\n extra?: unknown;\n}\n\n/** The v2 payment payload — note it carries no top-level scheme/network. */\nexport interface PaymentPayloadV2 {\n x402Version: 2;\n resource: ResourceInfoV2;\n accepted: PaymentRequirementsV2;\n payload: X402PayloadData;\n extensions?: Record<string, unknown>;\n}\n\n/**\n * Verify request body in x402 v2 form.\n *\n * There is deliberately NO `paymentRequirements` key: that is the v1 envelope.\n * v2 carries `resource` and `accepted` at the top level instead.\n */\nexport interface VerifyRequestV2 {\n x402Version: 2;\n paymentPayload: PaymentPayloadV2;\n resource: ResourceInfoV2;\n accepted: PaymentRequirementsV2;\n}\n\n/** Settle request body in x402 v2 form. Same shape as {@link VerifyRequestV2}. */\nexport type SettleRequestV2 = VerifyRequestV2;\n\nfunction buildV2Envelope(\n payload: X402PayloadData,\n resource: ResourceInfoV2,\n accepted: PaymentRequirementsV2\n): VerifyRequestV2 {\n return {\n x402Version: 2,\n // The facilitator reads the payload from here; `resource` and `accepted` are\n // repeated at the top level because the v2 envelope declares both.\n paymentPayload: { x402Version: 2, resource, accepted, payload },\n resource,\n accepted,\n };\n}\n\n/**\n * Build a verify request for the facilitator `/verify` endpoint, in **v2** form.\n *\n * Use this whenever your 402 advertises CAIP-2 networks. {@link buildVerifyRequest}\n * emits the v1 envelope `{x402Version, paymentPayload, paymentRequirements}` and\n * cannot express v2 — putting a v2 payload inside it matches no variant at the\n * facilitator and fails with an error that names no field.\n *\n * @example\n * ```ts\n * const body = buildVerifyRequestV2(\n * payment.payload,\n * { url: 'https://api.example.com/thing', description: 'Thing', mimeType: 'application/json' },\n * { scheme: 'exact', network: 'eip155:8453', asset: '0x8335...', amount: '100000',\n * payTo: '0xabc...', maxTimeoutSeconds: 300 }\n * );\n * ```\n */\nexport function buildVerifyRequestV2(\n payload: X402PayloadData,\n resource: ResourceInfoV2,\n accepted: PaymentRequirementsV2\n): VerifyRequestV2 {\n return buildV2Envelope(payload, resource, accepted);\n}\n\n/**\n * Build a settle request for the facilitator `/settle` endpoint, in **v2** form.\n *\n * See {@link buildVerifyRequestV2} — the envelope is identical.\n */\nexport function buildSettleRequestV2(\n payload: X402PayloadData,\n resource: ResourceInfoV2,\n accepted: PaymentRequirementsV2\n): SettleRequestV2 {\n return buildV2Envelope(payload, resource, accepted);\n}\n\nexport function buildSettleRequest(\n paymentHeader: X402Header,\n requirements: PaymentRequirements\n): SettleRequest {\n return {\n // `1` for the same reason as {@link buildVerifyRequest}: it names the\n // envelope, and `/settle` takes the same body as `/verify`.\n x402Version: 1,\n paymentPayload: paymentHeader,\n paymentRequirements: requirements,\n };\n}\n\n// ----------------------------------------------------------------------------\n// CHOOSING THE ENVELOPE\n// ----------------------------------------------------------------------------\n//\n// Everything above emits ONE envelope and makes the caller pick. That is the\n// whole defect: `FacilitatorClient` picked v1 unconditionally, so a seller whose\n// 402 advertised v2 -- which `createHonoMiddleware` does on its own the moment\n// the accepts carry CAIP-2 ids -- could not call the facilitator at all, and\n// every consumer had to port the v2 body by hand. The functions below make the\n// version a decision rather than a constant.\n\n/**\n * Networks are CAIP-2 in v2 (`eip155:8453`) and plain names in v1 (`base`).\n *\n * The colon is the whole test, and it is the same one `create402Response` and\n * `normalizeRequirementForVersion` already use. Note the SDK's XRPL entries\n * carry no CAIP-2 id yet (the facilitator publishes `xrpl:0` / `xrpl:1`, the\n * registry does not), so XRPL stays on v1 here -- see the CHANGELOG for 2.85.0.\n */\nfunction isCaip2Network(network: string | undefined): boolean {\n return typeof network === 'string' && network.includes(':');\n}\n\n/**\n * The network a payment payload is speaking, wherever that payload keeps it.\n *\n * A **v1** header carries `network` at the top level. A **v2** payload does not\n * carry one AT ALL -- look at {@link PaymentPayloadV2}: there is no top-level\n * `network`, because v2 moved the chain id into `accepted`. So reading only\n * `payload.network` threw\n *\n * TypeError: Cannot read properties of undefined (reading 'includes')\n *\n * on exactly the shape {@link resolveEnvelopeVersion} exists to route -- the\n * default `'auto'` was unusable for any caller holding a real v2 payload.\n * Measured in runtime against 2.78.0, and it is why MeshRelay's turnstile and\n * multibrain pin `x402Version` to 1 or 2 rather than use our default.\n *\n * Undefined is a legitimate answer (a JS caller can hand over anything), and it\n * simply means \"this payload contributes no CAIP-2 evidence\".\n */\nfunction networkOfPayload(payload: X402Header | PaymentPayloadV2): string | undefined {\n const top = (payload as { network?: unknown }).network;\n if (typeof top === 'string') return top;\n const accepted = (payload as { accepted?: { network?: unknown } }).accepted;\n return typeof accepted?.network === 'string' ? accepted.network : undefined;\n}\n\n/**\n * Derive the v2 `resource` object from v1-shaped requirements.\n *\n * v2 moved `resource` / `description` / `mimeType` out of the requirements and\n * into an object of their own, and the facilitator requires ALL THREE keys:\n * measured 2026-09-03, a `resource` carrying only `url` is a 400.\n *\n * The `??` defaults are not decoration. `PaymentRequirements` types these as\n * required, but a JavaScript caller can still hand over an object without them,\n * and a missing key does not fail with \"description is missing\" -- it fails with\n * `data did not match any variant of untagged enum VerifyRequestEnvelope`, which\n * names no field. That error is what cost two teams a day.\n */\nexport function toResourceInfoV2(requirements: PaymentRequirements): ResourceInfoV2 {\n return {\n url: requirements.resource,\n description: requirements.description ?? DEFAULT_PAYMENT_DESCRIPTION,\n mimeType: requirements.mimeType ?? DEFAULT_PAYMENT_MIME_TYPE,\n };\n}\n\n/**\n * Derive v2 `accepted` requirements from v1-shaped requirements.\n *\n * Two renames do the damage, and neither is reported by name when it is wrong:\n * - `maxAmountRequired` is spelled `amount` in v2.\n * - `network` must be CAIP-2; a plain name inside a v2 body is a 400.\n *\n * `extra` is carried through when present -- it is where the EIP-712 domain\n * `name`/`version` live for tokens the facilitator does not know by address, so\n * dropping it breaks EURC and the bridged USDCs.\n *\n * @throws If `requirements.network` has NO CAIP-2 form. `chainToCAIP2` answers\n * with the name unchanged when it does not know a chain, and XRPL maps to\n * itself on purpose -- its v1 string IS its network id. Passing that through\n * would put a plain name inside a v2 body, which is a measured 400 (the same\n * `no variant matched` that names no field). Only reachable by PINNING version\n * 2 on such a network; `auto` leaves them on v1, where they work. Failing here\n * names the network and the fix, which a 400 from the facilitator does not.\n */\nexport function toPaymentRequirementsV2(\n requirements: PaymentRequirements\n): PaymentRequirementsV2 {\n const network = isCaip2Network(requirements.network)\n ? requirements.network\n : chainToCAIP2(requirements.network);\n if (!isCaip2Network(network)) {\n throw new Error(\n `Network '${requirements.network}' has no CAIP-2 form, so it cannot travel in ` +\n 'the x402 v2 envelope. Use x402Version: 1 for this network.'\n );\n }\n\n return {\n scheme: requirements.scheme,\n network,\n asset: requirements.asset,\n amount: requirements.maxAmountRequired,\n payTo: requirements.payTo,\n // Required by the facilitator: omitting it is a 400, measured the same day.\n maxTimeoutSeconds: requirements.maxTimeoutSeconds ?? DEFAULT_PAYMENT_TIMEOUT_SECONDS,\n ...(requirements.extra !== undefined ? { extra: requirements.extra } : {}),\n };\n}\n\n/**\n * Decide which envelope this (payment, requirements) pair has to travel in.\n *\n * `requested` wins when it names a version; `'auto'` (the default) reads the\n * wire.\n *\n * **Auto keys off CAIP-2, NOT off `paymentHeader.x402Version`,** and that is a\n * measured decision rather than a stylistic one. The facilitator's envelope enum\n * is untagged: it matches on SHAPE and ignores the version marker.\n *\n * Re-measured against `https://facilitator.ultravioletadao.xyz/verify` on\n * **2026-09-04** with a fabricated signature. The signature never verifies, so\n * every row is an HTTP 400 and the STATUS discriminates nothing -- what does is\n * the error code. `invalid_request_body` means the facilitator could not\n * deserialize the body; `contract_call_failed` means it read the body, resolved\n * the chain and got as far as the on-chain call, i.e. the envelope was fine.\n *\n * | payload network | requirements network | v1 envelope today |\n * |-----------------|----------------------|-------------------|\n * | `base` | `base` | understood |\n * | `base` (header says `x402Version: 2`) | `base` | understood |\n * | `eip155:8453` | `base` | understood |\n * | `base` | `eip155:8453` | understood |\n * | `eip155:8453` | `eip155:8453` | understood |\n *\n * **The last three rows used to be a hard 400** (`unknown variant\n * \\`eip155:8453\\``) when this function was written on 2026-09-03. The\n * facilitator has since taught the v1 envelope to read CAIP-2, so the original\n * argument for this rule -- \"every CAIP-2 combination is already a 400, so\n * upgrading them cannot regress anyone\" -- **is no longer true**. The rule is\n * unchanged; three other reasons hold it up:\n *\n * 1. A CAIP-2 network on the wire means the 402 that produced it advertised v2.\n * Answering in v2 is speaking the protocol the seller announced.\n * 2. v2-with-CAIP-2 is the only shape BOTH generations of the facilitator\n * accept. v1-with-CAIP-2 is a hard 400 on any build older than 2026-09-04,\n * so choosing v1 there is what breaks against a self-hosted or pinned one.\n * 3. The Python SDK resolves the identical rule, so the same wire produces the\n * same body in both SDKs -- pinned by phase 6 of `npm run test:xlang`.\n *\n * And the marker still decides nothing: row 2 above is served correctly today,\n * so upgrading on the strength of it would change a call that works.\n *\n * The negative half of that measurement, without which \"understood\" proves\n * nothing -- the same run, bodies broken on purpose, all three\n * `invalid_request_body`: a v2 body carrying a plain network name, one with\n * `resource` as a bare string, and one with `accepted` removed. A well-formed\n * v2 body with CAIP-2 reached `contract_call_failed` like the rows above.\n */\nexport function resolveEnvelopeVersion(\n paymentHeader: X402Header | PaymentPayloadV2,\n requirements: PaymentRequirements,\n requested: X402Version | 'auto' = 'auto'\n): X402Version {\n if (requirements.network?.startsWith('hedera:') && requested === 1) {\n throw new Error('Native Hedera supports only x402 v2');\n }\n if (requested !== 'auto') {\n return requested;\n }\n\n return isCaip2Network(networkOfPayload(paymentHeader)) ||\n isCaip2Network(requirements.network)\n ? 2\n : 1;\n}\n\n/**\n * Build a `/verify` body in whichever envelope `version` names.\n *\n * The v1 return is byte-for-byte what {@link buildVerifyRequest} produces, so\n * pinning `1` is exactly today's behaviour.\n *\n * @example\n * ```ts\n * const version = resolveEnvelopeVersion(payment, requirements);\n * const body = buildVerifyRequestForVersion(payment, requirements, version);\n * ```\n */\nexport function buildVerifyRequestForVersion(\n paymentHeader: X402Header,\n requirements: PaymentRequirements,\n version: X402Version\n): VerifyRequest | VerifyRequestV2 {\n if (version === 2) {\n return buildVerifyRequestV2(\n paymentHeader.payload,\n toResourceInfoV2(requirements),\n toPaymentRequirementsV2(requirements)\n );\n }\n\n return buildVerifyRequest(paymentHeader, requirements);\n}\n\n/**\n * Build a `/settle` body in whichever envelope `version` names.\n *\n * See {@link buildVerifyRequestForVersion} -- `/settle` takes the same body as\n * `/verify` in both versions.\n */\nexport function buildSettleRequestForVersion(\n paymentHeader: X402Header,\n requirements: PaymentRequirements,\n version: X402Version\n): SettleRequest | SettleRequestV2 {\n if (version === 2) {\n return buildSettleRequestV2(\n paymentHeader.payload,\n toResourceInfoV2(requirements),\n toPaymentRequirementsV2(requirements)\n );\n }\n\n return buildSettleRequest(paymentHeader, requirements);\n}\n\n// ============================================================================\n// CORS CONFIGURATION\n// ============================================================================\n\n/**\n * Recommended CORS headers for x402 payment APIs\n *\n * These headers allow browsers to send payment headers in cross-origin requests.\n */\nexport const X402_CORS_HEADERS = {\n 'Access-Control-Allow-Headers':\n 'Content-Type, X-PAYMENT, PAYMENT-SIGNATURE, X-UVD-Purchase, Authorization',\n 'Access-Control-Expose-Headers':\n 'X-PAYMENT-RESPONSE, PAYMENT-RESPONSE, PAYMENT-REQUIRED',\n 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',\n} as const;\n\n/**\n * All x402 custom header names that should be allowed in CORS\n */\nexport const X402_HEADER_NAMES = [\n 'X-PAYMENT',\n 'PAYMENT-SIGNATURE',\n 'X-PAYMENT-RESPONSE',\n 'PAYMENT-RESPONSE',\n 'PAYMENT-REQUIRED',\n 'X-UVD-Purchase',\n] as const;\n\n/**\n * Get CORS headers with custom origin\n *\n * @param origin - Allowed origin (use '*' for any, or specific domain)\n * @returns Complete CORS headers object\n *\n * @example\n * ```ts\n * // Express.js middleware\n * app.use((req, res, next) => {\n * const corsHeaders = getCorsHeaders('https://myapp.com');\n * Object.entries(corsHeaders).forEach(([key, value]) => {\n * res.setHeader(key, value);\n * });\n * if (req.method === 'OPTIONS') {\n * return res.status(204).end();\n * }\n * next();\n * });\n * ```\n */\nexport function getCorsHeaders(origin: string = '*'): Record<string, string> {\n return {\n 'Access-Control-Allow-Origin': origin,\n ...X402_CORS_HEADERS,\n };\n}\n\n// ============================================================================\n// FACILITATOR CLIENT\n// ============================================================================\n\n/** The header that binds `/verify` and `/settle` of one payment to one purchase. */\nexport const IDEMPOTENCY_KEY_HEADER = 'Idempotency-Key';\n\n/** The header with which the facilitator marks a stored answer, not a new settle. */\nexport const IDEMPOTENT_REPLAYED_HEADER = 'Idempotent-Replayed';\n\n/**\n * A new, unguessable `Idempotency-Key` for ONE payment.\n *\n * Send the same key on that payment's `/verify` and `/settle` and on every\n * retry of either; after a lost response, the key is what earns the\n * facilitator's original answer back. It is random on purpose: a key derived\n * from the X-PAYMENT would be known to anyone holding the payment, and holding\n * the payment is exactly what the facilitator refuses to accept as a binding.\n * Persist it with your order if you need to resume after a restart.\n */\nexport function createIdempotencyKey(): string {\n return `x402-${bytesToHex(randomBytes(32))}`;\n}\n\n/** Throws on a key the facilitator or a header cannot carry. */\nfunction checkIdempotencyKey(key: string): string {\n // `receipt:` is reserved by the facilitator (400 reserved_idempotency_key),\n // and the legacy store uses the key as a table key: keep it short and plain.\n if (typeof key !== 'string' || !/^[\\x21-\\x7e]{1,255}$/.test(key) || key.startsWith('receipt:')) {\n throw new Error('idempotencyKey must be 1-255 visible ASCII characters and must not start with \"receipt:\"');\n }\n return key;\n}\n\n/** Whether the facilitator marked this answer `Idempotent-Replayed: true`. */\nfunction isReplayed(response: { headers?: { get?: (name: string) => string | null } }): boolean {\n try {\n return response?.headers?.get?.(IDEMPOTENT_REPLAYED_HEADER)?.trim().toLowerCase() === 'true';\n } catch {\n return false;\n }\n}\n\n/**\n * A replay that the request did not bind is somebody else's purchase.\n *\n * Only for a settle whose key is fresh and which carried no purchase context:\n * such a call cannot have admitted the authorization, so a replay reached it\n * through possession of the payment alone. Answered the way facilitator 2.39.0\n * answers it -- `authorization_already_settled` / `authorization_in_flight` --\n * without the success artefacts a caller could deliver on. The receipt stays.\n * A replayed rejection is still the original rejection and passes unchanged.\n */\nfunction refuseUnboundReplay(result: SettleResponse): SettleResponse {\n if (!result.replayed) return result;\n const pending = result.receipt?.status === 'pending' || result.receipt?.status === 'unknown'\n || result.errorCode === 'settlement_in_progress';\n if (!result.success && !pending) return result;\n const {\n transactionHash: _tx, proofOfPayment: _proof, paymentId: _id, transaction: _t,\n retryAfterSeconds, ...rest\n } = result;\n if (result.success) {\n return { ...rest, success: false, error: AUTHORIZATION_ALREADY_SETTLED,\n errorCode: AUTHORIZATION_ALREADY_SETTLED, retryable: false, safeToReplay: false };\n }\n return { ...rest, success: false, error: AUTHORIZATION_IN_FLIGHT, errorCode: AUTHORIZATION_IN_FLIGHT,\n retryable: true, safeToReplay: false, retryAfterSeconds: retryAfterSeconds ?? DEFAULT_RETRY_AFTER_SECONDS };\n}\n\n/** Per-call options of {@link FacilitatorClient.verify} and {@link FacilitatorClient.settle}. */\nexport interface FacilitatorCallOptions {\n /** A validated `X-UVD-Purchase` value, forwarded unchanged (see `validatePurchaseContext`). */\n receiptContext?: string;\n /**\n * The payment's `Idempotency-Key` (see {@link createIdempotencyKey}). Pass the\n * SAME key to `verify` and `settle` of one payment and to their retries.\n * Omitted, the call sends a fresh key and reports it back as\n * `result.idempotencyKey`.\n */\n idempotencyKey?: string;\n}\n\n/** Headers of a `/verify` or `/settle` call: the payment's binding travels on both. */\nfunction facilitatorHeaders(idempotencyKey: string, receiptContext?: string): Record<string, string> {\n return {\n 'Content-Type': 'application/json',\n [IDEMPOTENCY_KEY_HEADER]: idempotencyKey,\n ...(receiptContext ? { 'X-UVD-Purchase': receiptContext } : {}),\n };\n}\n\n/**\n * The failure fields of a `/verify` that names an admitted authorization.\n *\n * `/verify` answers these with HTTP 200 and `isValid: false`, so without this\n * they look like a refused signature -- and a 402 asks the buyer to sign again\n * for a purchase that is already paid or being paid.\n */\nfunction admittedVerdict(result: { isValid?: unknown; invalidReason?: unknown }): FacilitatorFailureFields {\n if (result.isValid !== false) return {};\n if (result.invalidReason === AUTHORIZATION_IN_FLIGHT) {\n return { errorCode: AUTHORIZATION_IN_FLIGHT, retryable: true, safeToReplay: false,\n retryAfterSeconds: DEFAULT_RETRY_AFTER_SECONDS };\n }\n if (result.invalidReason === AUTHORIZATION_ALREADY_SETTLED) {\n return { errorCode: AUTHORIZATION_ALREADY_SETTLED, retryable: false, safeToReplay: false };\n }\n return {};\n}\n\n/**\n * Options for the FacilitatorClient\n */\nexport interface FacilitatorClientOptions {\n /** Base URL of the facilitator (default: https://facilitator.ultravioletadao.xyz) */\n baseUrl?: string;\n /**\n * Request timeout in milliseconds (default: auto per network).\n * When not set, the client uses per-network defaults from ESCROW_TIMEOUT_MS\n * (960s for Ethereum L1, 90s for L2s, 30s for others).\n * Set explicitly to override per-network auto-detection.\n */\n timeout?: number;\n /**\n * Extra attempts after the first when the facilitator answers a refusal it\n * proved it did not execute (`safeToReplay`). Default 2; `0` disables.\n *\n * Only ever spent on `429` and on a `503` naming a pre-execution writer-lease\n * reason. An ambiguous `forward_failed` -- whose write may already have landed\n * -- is never replayed here, at any setting.\n */\n retries?: number;\n /**\n * Which envelope to send to `/verify` and `/settle`. Default `'auto'`.\n *\n * `'auto'` reads the wire: CAIP-2 networks get the v2 envelope, plain names\n * get v1. See {@link resolveEnvelopeVersion} for the measurements behind that\n * rule. Pin `1` or `2` to take the decision yourself -- a pin is honoured\n * even when it contradicts the wire, because choosing the version is the\n * point of the option.\n */\n x402Version?: X402Version | 'auto';\n}\n\n/**\n * Client for interacting with the x402 facilitator API\n *\n * @example\n * ```ts\n * const client = new FacilitatorClient();\n *\n * // Verify a payment\n * const verifyResult = await client.verify(paymentHeader, requirements);\n * if (!verifyResult.isValid) {\n * return res.status(402).json({ error: verifyResult.invalidReason });\n * }\n *\n * // Provide the service, then settle\n * const settleResult = await client.settle(paymentHeader, requirements);\n * if (!settleResult.success) {\n * // Handle settlement failure (maybe refund or retry)\n * }\n * ```\n */\nexport class FacilitatorClient {\n private readonly baseUrl: string;\n private readonly timeout: number;\n private readonly explicitTimeout: boolean;\n private readonly retries: number | undefined;\n private readonly x402Version: X402Version | 'auto';\n\n constructor(options: FacilitatorClientOptions = {}) {\n this.baseUrl = options.baseUrl || 'https://facilitator.ultravioletadao.xyz';\n this.explicitTimeout = options.timeout !== undefined;\n this.timeout = options.timeout || 30000;\n this.retries = options.retries;\n this.x402Version = options.x402Version ?? 'auto';\n }\n\n /**\n * Get timeout for a specific network, using per-chain defaults when no explicit timeout was set.\n */\n private getTimeout(network?: string): number {\n if (this.explicitTimeout) return this.timeout;\n if (!network) return this.timeout;\n // Extract chainId from CAIP-2 format (eip155:1) or legacy names\n const match = network.match(/^eip155:(\\d+)$/);\n if (match) {\n const chainId = parseInt(match[1], 10);\n return ESCROW_TIMEOUT_MS[chainId] || this.timeout;\n }\n // Legacy network name mapping for Ethereum\n if (network === 'ethereum' || network === 'ethereum-mainnet') return ESCROW_TIMEOUT_MS[1];\n return this.timeout;\n }\n\n /**\n * Verify a payment with the facilitator\n *\n * Call this before providing the paid resource to validate the payment.\n *\n * An authorization the facilitator already admitted for another request\n * comes back invalid with `errorCode` {@link AUTHORIZATION_ALREADY_SETTLED}\n * (do not serve, do not ask for a new signature) or\n * {@link AUTHORIZATION_IN_FLIGHT} (`retryable`: the same request learns the\n * verdict later). Neither is a rejected payment: never answer them with 402.\n *\n * @param paymentHeader - Parsed x402 payment header\n * @param requirements - Payment requirements\n * @param options - Purchase context and the payment's `idempotencyKey`\n * @returns Verification result\n */\n async verify(\n paymentHeader: X402Header,\n requirements: PaymentRequirements,\n options: FacilitatorCallOptions = {},\n ): Promise<VerifyResponse> {\n const idempotencyKey = checkIdempotencyKey(options.idempotencyKey ?? createIdempotencyKey());\n // Not `buildVerifyRequest` any more. That one only speaks v1, so a seller\n // advertising CAIP-2 -- which this SDK's own Hono middleware does by itself\n // -- could not reach the facilitator at all: the body came back 400 with\n // `unknown variant \\`eip155:8453\\``, and the buyer saw a broken checkout.\n const body = buildVerifyRequestForVersion(\n paymentHeader,\n requirements,\n resolveEnvelopeVersion(paymentHeader, requirements, this.x402Version)\n );\n\n try {\n const { response, error } = await facilitatorFetch(\n `${this.baseUrl}/verify`,\n {\n method: 'POST',\n headers: facilitatorHeaders(idempotencyKey, options.receiptContext),\n body: JSON.stringify(body),\n },\n { timeoutMs: this.timeout, retries: this.retries },\n );\n\n if (error) {\n // `isValid: false` is unavoidable -- nothing was validated -- but it is\n // no longer the whole story. A caller that answers 402 on this without\n // reading `retryable` tells the buyer their payment was REFUSED and\n // asks them to sign another one, for a payment the facilitator never\n // looked at. That is the double-charge this field exists to prevent.\n return {\n isValid: false,\n invalidReason: error.error,\n ...failureFields(error),\n receipt: receiptFromErrorBody(error.body),\n idempotencyKey,\n };\n }\n\n const result = await response.json();\n return { ...result, ...admittedVerdict(result), receipt: parseFacilitatorReceipt(result.receipt), idempotencyKey };\n } catch (error) {\n // A thrown error is a transport failure (timeout, DNS, connection reset).\n // No verdict was reached either, so it is retryable for exactly the same\n // reason a 503 is -- and it used to be reported as an invalid payment.\n return {\n isValid: false,\n invalidReason: error instanceof Error ? error.message : 'Unknown error',\n retryable: true,\n safeToReplay: false,\n retryAfterSeconds: DEFAULT_RETRY_AFTER_SECONDS,\n idempotencyKey,\n };\n }\n }\n\n /**\n * Settle a payment with the facilitator\n *\n * Call this after providing the paid resource to execute the on-chain transfer.\n *\n * Send the `idempotencyKey` the payment was verified with, and the same one\n * on any retry: it is the binding that earns the original answer back after\n * a lost response (`replayed: true`). Without it, or with another one, an\n * authorization already admitted comes back `409`\n * {@link AUTHORIZATION_ALREADY_SETTLED}, {@link AUTHORIZATION_IN_FLIGHT} or\n * {@link RECEIPT_REQUEST_CONFLICT} -- the X-PAYMENT was used; do not serve it\n * again. With no key and no context the call uses a fresh key, so a replay\n * it receives is refused the same way.\n *\n * @param paymentHeader - Parsed x402 payment header\n * @param requirements - Payment requirements\n * @param options - Purchase context and the payment's `idempotencyKey`\n * @returns Settlement result with transaction hash\n */\n async settle(\n paymentHeader: X402Header,\n requirements: PaymentRequirements,\n options: FacilitatorCallOptions = {},\n ): Promise<SettleResponse> {\n // A fresh key with no purchase context binds nothing an earlier settle\n // could have admitted, so any replay this call receives is unbound.\n const unbound = options.idempotencyKey === undefined && !options.receiptContext;\n const idempotencyKey = checkIdempotencyKey(options.idempotencyKey ?? createIdempotencyKey());\n const body = buildSettleRequestForVersion(\n paymentHeader,\n requirements,\n resolveEnvelopeVersion(paymentHeader, requirements, this.x402Version)\n );\n const settleTimeout = this.getTimeout(requirements.network);\n\n try {\n // A `/settle` refusal that the facilitator proved it did not execute is\n // replayed here with the SAME authorization. That is safe twice over: the\n // facilitator refused in its router before signing anything, and the\n // authorization carries a single-use nonce the chain rejects on a real\n // duplicate. What is NOT replayed is `forward_failed` -- the hop to the\n // lease holder died after handing the write over, so the transfer may\n // already be mining.\n const { response, error } = await facilitatorFetch(\n `${this.baseUrl}/settle`,\n {\n method: 'POST',\n // The same init, key included, goes out on every automatic retry.\n headers: facilitatorHeaders(idempotencyKey, options.receiptContext),\n body: JSON.stringify(body),\n },\n { timeoutMs: settleTimeout, retries: this.retries },\n );\n\n if (error) {\n return {\n success: false,\n error: error.error,\n ...failureFields(error),\n receipt: receiptFromErrorBody(error.body),\n idempotencyKey,\n };\n }\n\n const result = await response.json();\n // Read all three spellings. The facilitator's canonical name for this\n // field is `transaction`, and this client used to read only the two\n // camel/snake variants — so it silently returned `undefined` for the\n // most important field a settle produces. A consumer failed closed on\n // that and revoked access to a payment that had already settled\n // on-chain: the money moved, the receipt was unreadable.\n //\n // The server now emits all three, but this fallback stays: it makes the\n // client work against facilitators that have not deployed that yet, and\n // against any that only ever emitted the canonical name.\n const transactionHash =\n result.transaction ?? result.transactionHash ?? result.transaction_hash;\n if (result.success && !transactionHash) {\n // Never let a missing hash pass as a normal success. A caller that\n // gates access on the receipt needs to know the receipt is absent,\n // not infer it from an undefined field.\n console.warn(\n '[x402] settle reported success but carried no transaction hash under ' +\n 'transaction/transactionHash/transaction_hash — treat delivery as unconfirmed'\n );\n }\n const settled: SettleResponse = {\n // Read the facilitator's verdict instead of asserting one.\n //\n // This was the literal `true`, so a settle was reported successful\n // whenever the HTTP call was — and \"the request arrived\" is not \"the\n // money moved\". A payment that MINES AND THEN REVERTS is answered with\n // 200 and `success: false` (x402-rs src/chain/evm.rs:1343, serialised\n // through StatusCode::OK), which is precisely the case a caller most\n // needs to hear about. Every consumer doing `result.success === true`\n // was reading a constant, so a reverted payment was booked as settled\n // and no reconciliation path could ever fire.\n //\n // Absent `success` is treated as NOT successful: a facilitator that\n // does not say it worked has not said it worked.\n success: result.success === true,\n transactionHash,\n network: result.network,\n // Why it failed, when it did. Without this the caller gets `success:\n // false` and no way to tell a reverted transfer from a rejected\n // authorization except by parsing prose.\n errorReason: result.errorReason ?? result.error_reason,\n // The settlement proof, when the facilitator attached one (it does for\n // the ERC-8004 extension). Dropping it here made `verified: true`\n // unreachable for DX402 anchoring through this client: `anchorEvidence`\n // documents proofOfPayment as the only thing that gets there, the\n // facilitator returns it, and this method threw it away — so a seller\n // using the SDK end to end could only ever produce provisional anchors.\n proofOfPayment: result.proofOfPayment ?? result.proof_of_payment,\n payer: result.payer,\n receipt: parseFacilitatorReceipt(result.receipt),\n paymentId: result.paymentId,\n ...(result.receipt?.status === \"unknown\" || result.receipt?.status === \"pending\" ? { retryable: true, safeToReplay: false } : {}),\n // `202 settlement_in_progress` and friends: a 2xx that names its state.\n ...(!result.success && typeof result.error === 'string' && result.error ? { errorCode: result.error } : {}),\n ...(isReplayed(response) ? { replayed: true } : {}),\n idempotencyKey,\n };\n return unbound ? refuseUnboundReplay(settled) : settled;\n } catch (error) {\n // Timeout or connection failure. The write may have landed -- this is the\n // same ambiguity as `forward_failed`, so it is retryable but never\n // replayed automatically. Reconcile on-chain, or by transaction hash,\n // before sending anything again -- with `idempotencyKey`, which is what\n // gets the original answer back.\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error',\n retryable: true,\n safeToReplay: false,\n retryAfterSeconds: DEFAULT_RETRY_AFTER_SECONDS,\n idempotencyKey,\n };\n }\n }\n\n /**\n * Verify and settle atomically\n *\n * Convenience method that verifies first, then settles if valid.\n * Use this for simple payment flows where you don't need custom logic between verify and settle.\n *\n * Both steps carry ONE `Idempotency-Key` (`options.idempotencyKey`, or a\n * fresh one reported back as `idempotencyKey`). With a fresh key and no\n * purchase context, a replay of an earlier settle is not this purchase and\n * comes back `settled: false` with `errorCode`\n * {@link AUTHORIZATION_ALREADY_SETTLED}.\n *\n * @param paymentHeader - Parsed x402 payment header\n * @param requirements - Payment requirements\n * @param options - Purchase context and the payment's `idempotencyKey`\n * @returns Combined result with verify and settle status\n */\n async verifyAndSettle(\n paymentHeader: X402Header,\n requirements: PaymentRequirements,\n options: FacilitatorCallOptions = {},\n ): Promise<\n {\n verified: boolean;\n settled: boolean;\n transactionHash?: string;\n error?: string;\n /** The facilitator answered from its record of an earlier settle. */\n replayed?: boolean;\n /** The key both steps carried. Merchant-private. */\n idempotencyKey: string;\n } & FacilitatorFailureFields\n > {\n const unbound = options.idempotencyKey === undefined && !options.receiptContext;\n const binding = { ...options, idempotencyKey: checkIdempotencyKey(options.idempotencyKey ?? createIdempotencyKey()) };\n const { idempotencyKey } = binding;\n // Verify first\n const verifyResult = await this.verify(paymentHeader, requirements, binding);\n if (!verifyResult.isValid) {\n // Carry the refusal's shape up. Flattening it to `verified: false` here\n // would undo the whole point one level below: the caller could not tell a\n // rejected authorization from a facilitator that never answered.\n return {\n verified: false,\n settled: false,\n error: verifyResult.invalidReason,\n ...carryFailureFields(verifyResult),\n idempotencyKey,\n };\n }\n\n // Settle, under the key the verification carried.\n const answered = await this.settle(paymentHeader, requirements, binding);\n const settleResult = unbound ? refuseUnboundReplay(answered) : answered;\n return {\n verified: true,\n settled: settleResult.success,\n transactionHash: settleResult.transactionHash,\n error: settleResult.error,\n ...carryFailureFields(settleResult),\n ...(settleResult.replayed ? { replayed: true } : {}),\n idempotencyKey,\n };\n }\n\n /**\n * Check if the facilitator is healthy\n *\n * @returns True if the facilitator is responding\n */\n async healthCheck(): Promise<boolean> {\n try {\n const response = await fetch(`${this.baseUrl}/health`, {\n method: 'GET',\n });\n return response.ok;\n } catch {\n return false;\n }\n }\n\n /**\n * Get the facilitator version info\n *\n * @returns Version info (e.g., { version: \"1.37.0\" })\n */\n async getVersion(): Promise<{ version: string; [key: string]: unknown }> {\n const response = await fetch(`${this.baseUrl}/version`, {\n method: 'GET',\n });\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`GET /version failed: ${response.status} - ${errorText}`);\n }\n return await response.json();\n }\n\n /**\n * Get the facilitator's supported networks and payment schemes\n *\n * @returns Supported networks/schemes with 'kinds' array\n *\n * @example\n * ```ts\n * const supported = await client.getSupported();\n * for (const kind of supported.kinds) {\n * console.log(`${kind.network} - ${kind.scheme}`);\n * }\n * ```\n */\n async getSupported(): Promise<{\n kinds: Array<{ network: string; scheme: string; [key: string]: unknown }>;\n [key: string]: unknown;\n }> {\n const response = await fetch(`${this.baseUrl}/supported`, {\n method: 'GET',\n });\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`GET /supported failed: ${response.status} - ${errorText}`);\n }\n return await response.json();\n }\n\n /**\n * Aggregated totals per network and asset (`GET /api/stats`).\n *\n * **An index, not a ledger.** Records are written best-effort AFTER\n * settlement, so an outage loses rows while payments proceed — verify\n * anything that matters against the transaction hash. Counting starts when\n * the operator enabled the store, so earlier operations are UNKNOWN, not\n * zero. And unless `X402_EVENTS_PUBLISH_FAILURES=true`, operations that ERROR\n * are not recorded at all: a 100% success rate means \"no failures were\n * recorded\".\n *\n * `volumeAtomic` is a STRING (u256-shaped; a JS number loses precision above\n * 2^53) and each row carries its own `decimals`. **Use that, never a\n * constant** — USDC is 6 decimals nearly everywhere and 18 on BSC, so scaling\n * by 6 there overstates volume by 10^12. `decimals` is null when the asset is\n * unrecognised; render the atomic value rather than guessing a scale.\n */\n async getStats(): Promise<{\n totals: { settlesOk: number; settlesFailed: number; verifies: number; networks: number };\n byNetworkAndAsset: Array<{\n network: string;\n asset: string;\n settlesOk: number;\n settlesFailed: number;\n verifies: number;\n volumeAtomic: string;\n decimals: number | null;\n lastTs: number;\n }>;\n [key: string]: unknown;\n }> {\n const response = await fetch(`${this.baseUrl}/api/stats`, { method: 'GET' });\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`GET /api/stats failed: ${response.status} - ${errorText}`);\n }\n return await response.json();\n }\n\n /**\n * Recent recorded operations, newest first (`GET /transactions`).\n *\n * There is **no pagination and no cursor**: this returns the newest N,\n * walking back at most 30 days. With 10,000 rows you get the newest 200, not\n * page one of fifty. `limit` is clamped to 200 by the facilitator.\n *\n * `network` matches the canonical slug `/supported` uses, which is not always\n * the alias you may send — `skale` is accepted inbound but records say\n * `skale-base`.\n */\n async getTransactions(options: { limit?: number; network?: string } = {}): Promise<{\n transactions: Array<Record<string, unknown>>;\n count: number;\n [key: string]: unknown;\n }> {\n const params = new URLSearchParams();\n if (options.limit !== undefined) params.set('limit', String(options.limit));\n if (options.network) params.set('network', options.network);\n const query = params.toString();\n const response = await fetch(\n `${this.baseUrl}/transactions${query ? `?${query}` : ''}`,\n { method: 'GET' }\n );\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`GET /transactions failed: ${response.status} - ${errorText}`);\n }\n return await response.json();\n }\n\n /**\n * Get the facilitator's blocked/sanctioned addresses\n *\n * @returns Blacklist info (totalBlocked, loadedAtStartup, addresses)\n *\n * @example\n * ```ts\n * const bl = await client.getBlacklist();\n * console.log(`Blocked: ${bl.totalBlocked} addresses`);\n * ```\n */\n async getBlacklist(): Promise<{\n totalBlocked: number;\n loadedAtStartup: boolean;\n [key: string]: unknown;\n }> {\n const response = await fetch(`${this.baseUrl}/blacklist`, {\n method: 'GET',\n });\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`GET /blacklist failed: ${response.status} - ${errorText}`);\n }\n return await response.json();\n }\n\n /**\n * Negotiate payment requirements with the facilitator via POST /accepts.\n *\n * Sends merchant payment requirements to the facilitator, which matches\n * them against its supported capabilities and returns enriched requirements\n * with facilitator data (feePayer, tokens, escrow configuration).\n *\n * This is used by Faremeter middleware and clients that need to discover\n * what the facilitator can settle before constructing payment authorizations.\n *\n * @param paymentRequirements - List of payment requirement objects\n * @param x402Version - x402 protocol version (default: 2)\n * @returns List of enriched payment requirements with facilitator extras\n *\n * @example\n * ```ts\n * const enriched = await client.accepts([\n * {\n * scheme: 'exact',\n * network: 'base-mainnet',\n * maxAmountRequired: '1000000',\n * resource: 'https://api.example.com/data',\n * payTo: '0xMerchant...',\n * },\n * ]);\n * // enriched[0].extra.feePayer is now set\n * ```\n */\n async accepts(\n paymentRequirements: PaymentRequirements[],\n x402Version: number = 2\n ): Promise<PaymentRequirements[]> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(`${this.baseUrl}/accepts`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n x402Version,\n accepts: paymentRequirements,\n }),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Facilitator /accepts error: ${response.status} - ${errorText}`);\n }\n\n const data = await response.json();\n return data.accepts || [];\n } catch (error) {\n clearTimeout(timeoutId);\n throw error;\n }\n }\n}\n\n// ============================================================================\n// ATOMIC PAYMENT HELPERS\n// ============================================================================\n\n/**\n * Create a 402 Payment Required response\n *\n * @param requirements - Payment requirements\n * @param options - Additional response options\n * @returns Object with status code, headers, and body for the 402 response\n *\n * @example\n * ```ts\n * // Express.js\n * app.get('/premium-data', (req, res) => {\n * const payment = extractPaymentFromHeaders(req.headers);\n *\n * if (!payment) {\n * const { status, headers, body } = create402Response({\n * amount: '1.00',\n * recipient: '0x...',\n * resource: 'https://api.example.com/premium-data',\n * });\n * return res.status(status).set(headers).json(body);\n * }\n *\n * // Verify and serve...\n * });\n * ```\n */\nexport function create402Response(\n requirements: PaymentRequirementsOptions,\n options: {\n accepts?: PaymentAcceptance[];\n } = {}\n): {\n status: 402;\n headers: Record<string, string>;\n body: Record<string, unknown>;\n} {\n const primaryRequirement = buildPaymentRequirements(requirements);\n const version = requirements.x402Version\n || ((options.accepts && options.accepts.length > 0)\n || primaryRequirement.network.includes(':')\n || (options.accepts || []).some((accept) => accept.network.includes(':'))\n ? 2\n : 1);\n const advertisedRequirements = [\n normalizeRequirementForVersion(primaryRequirement, version),\n ...(options.accepts || []).map((accept) =>\n buildRequirementFromAcceptance(accept, primaryRequirement.resource, version, primaryRequirement)\n ),\n ];\n const body = create402ResponseBody(advertisedRequirements[0], advertisedRequirements, version);\n\n return {\n status: 402,\n headers: {\n 'Content-Type': 'application/json',\n ...X402_CORS_HEADERS,\n },\n body,\n };\n}\n\nconst DEFAULT_PAYMENT_DESCRIPTION = 'Payment required';\nconst DEFAULT_PAYMENT_MIME_TYPE = 'application/json';\nconst DEFAULT_PAYMENT_TIMEOUT_SECONDS = 300;\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\nfunction resolveAdvertisedVersion(\n accepts: PaymentAcceptance[],\n requestedVersion?: X402Version | 'auto'\n): X402Version {\n if (requestedVersion && requestedVersion !== 'auto') {\n return requestedVersion;\n }\n\n if (accepts.length > 1 || accepts.some((accept) => accept.network.includes(':'))) {\n return 2;\n }\n\n return 1;\n}\n\nfunction normalizeRequirementForVersion(\n requirements: PaymentRequirements,\n version: X402Version\n): PaymentRequirements {\n return {\n ...requirements,\n network: version === 2\n ? (requirements.network.includes(':') ? requirements.network : chainToCAIP2(requirements.network))\n : (requirements.network.includes(':') ? parseNetworkIdentifier(requirements.network) : requirements.network),\n };\n}\n\nfunction buildRequirementFromAcceptance(\n accept: PaymentAcceptance,\n resource: string,\n version: X402Version,\n defaults?: PaymentRequirements\n): PaymentRequirements {\n const payTo = accept.payTo ?? defaults?.payTo;\n if (!payTo) {\n throw new Error('Payment accepts entries must include payTo');\n }\n\n return normalizeRequirementForVersion({\n // Honour a caller-supplied scheme; 'exact' is the default, not an override.\n // Hardcoding it silently discarded 'escrow' / 'commerce' accepts.\n scheme: (accept.scheme as PaymentRequirements['scheme']) ?? 'exact',\n network: accept.network,\n maxAmountRequired: accept.amount,\n resource: accept.resource ?? defaults?.resource ?? resource,\n description: accept.description ?? defaults?.description ?? DEFAULT_PAYMENT_DESCRIPTION,\n mimeType: accept.mimeType ?? defaults?.mimeType ?? DEFAULT_PAYMENT_MIME_TYPE,\n payTo,\n asset: accept.asset,\n maxTimeoutSeconds: accept.maxTimeoutSeconds ?? defaults?.maxTimeoutSeconds ?? DEFAULT_PAYMENT_TIMEOUT_SECONDS,\n ...(accept.outputSchema !== undefined\n ? { outputSchema: accept.outputSchema }\n : defaults?.outputSchema !== undefined\n ? { outputSchema: defaults.outputSchema }\n : {}),\n ...(accept.extra !== undefined\n ? { extra: accept.extra }\n : defaults?.extra !== undefined\n ? { extra: defaults.extra }\n : {}),\n }, version);\n}\n\nfunction toPaymentAcceptance(\n requirements: PaymentRequirements,\n facilitator?: string\n): PaymentAcceptance {\n return {\n network: requirements.network,\n asset: requirements.asset,\n amount: requirements.maxAmountRequired,\n // scheme is REQUIRED by the facilitator's v2 PaymentRequirementsV2. Dropping it\n // here produced an accepts[] entry that no v2 client could pay: the spec makes\n // the client echo the accept verbatim, so the omission travelled downstream and\n // died in deserialization with an error naming no field.\n scheme: requirements.scheme,\n payTo: requirements.payTo,\n resource: requirements.resource,\n description: requirements.description,\n mimeType: requirements.mimeType,\n maxTimeoutSeconds: requirements.maxTimeoutSeconds,\n ...(facilitator ? { facilitator } : {}),\n ...(requirements.outputSchema !== undefined ? { outputSchema: requirements.outputSchema } : {}),\n ...(requirements.extra !== undefined ? { extra: requirements.extra } : {}),\n };\n}\n\nfunction create402ResponseBody(\n primaryRequirement: PaymentRequirements,\n advertisedRequirements: PaymentRequirements[],\n version: X402Version,\n facilitator?: string\n): Record<string, unknown> {\n const normalizedPrimary = normalizeRequirementForVersion(primaryRequirement, version);\n const normalizedAdvertised = advertisedRequirements.map((requirements) =>\n normalizeRequirementForVersion(requirements, version)\n );\n\n const body: Record<string, unknown> = {\n x402Version: version,\n ...normalizedPrimary,\n };\n\n if (version === 2 && normalizedAdvertised.length > 1) {\n body.accepts = normalizedAdvertised.map((requirements) =>\n toPaymentAcceptance(requirements, facilitator)\n );\n }\n\n return body;\n}\n\nfunction getComparableNetwork(network: string): string {\n return parseNetworkIdentifier(network).toLowerCase();\n}\n\nfunction getPaymentRecipient(payment: X402Header): string | undefined {\n const payload = payment.payload as unknown;\n if (!isObject(payload)) {\n return undefined;\n }\n const authorization = payload.authorization;\n\n if (isObject(authorization) && typeof authorization.to === 'string') {\n return authorization.to.toLowerCase();\n }\n\n if (typeof payload.to === 'string') {\n return payload.to.toLowerCase();\n }\n\n return undefined;\n}\n\nfunction getPaymentAmount(payment: X402Header): string | undefined {\n const payload = payment.payload as unknown;\n if (!isObject(payload)) {\n return undefined;\n }\n const authorization = payload.authorization;\n\n if (isObject(authorization) && typeof authorization.value === 'string') {\n return authorization.value;\n }\n\n if (typeof payload.amount === 'string') {\n return payload.amount;\n }\n\n return undefined;\n}\n\nfunction getPaymentAsset(payment: X402Header): string | undefined {\n const payload = payment.payload as unknown;\n if (!isObject(payload)) {\n return undefined;\n }\n\n if (typeof payload.tokenContract === 'string') {\n return payload.tokenContract.toLowerCase();\n }\n\n return undefined;\n}\n\nasync function resolvePaymentRequirement(\n payment: X402Header,\n requirements: PaymentRequirements[],\n resolver?: PaymentRequirementResolver\n): Promise<{ requirement: PaymentRequirements | null; reason?: string }> {\n const normalizedRequirements = requirements.map((requirements) =>\n normalizeRequirementForVersion(requirements, payment.x402Version)\n );\n\n if (resolver) {\n const resolved = await resolver(payment, normalizedRequirements);\n return {\n requirement: resolved\n ? normalizeRequirementForVersion(resolved, payment.x402Version)\n : null,\n ...(resolved ? {} : { reason: 'Custom requirement resolver did not return a matching requirement.' }),\n };\n }\n\n const networkMatches = normalizedRequirements.filter((requirements) =>\n getComparableNetwork(requirements.network) === getComparableNetwork(payment.network)\n );\n\n if (networkMatches.length === 0) {\n return {\n requirement: null,\n reason: `No advertised payment requirement matched network ${payment.network}.`,\n };\n }\n\n let matches = networkMatches;\n\n const paymentRecipient = getPaymentRecipient(payment);\n if (paymentRecipient) {\n const recipientMatches = matches.filter((requirements) =>\n requirements.payTo.toLowerCase() === paymentRecipient\n );\n if (recipientMatches.length === 0) {\n return {\n requirement: null,\n reason: 'Payment recipient does not match any advertised requirement.',\n };\n }\n matches = recipientMatches;\n }\n\n const paymentAmount = getPaymentAmount(payment);\n if (paymentAmount) {\n const amountMatches = matches.filter((requirements) =>\n requirements.maxAmountRequired === paymentAmount\n );\n if (amountMatches.length === 0) {\n return {\n requirement: null,\n reason: 'Payment amount does not match any advertised requirement.',\n };\n }\n matches = amountMatches;\n }\n\n const paymentAsset = getPaymentAsset(payment);\n if (paymentAsset) {\n const assetMatches = matches.filter((requirements) =>\n requirements.asset.toLowerCase() === paymentAsset\n );\n if (assetMatches.length === 0) {\n return {\n requirement: null,\n reason: 'Payment asset does not match any advertised requirement.',\n };\n }\n matches = assetMatches;\n }\n\n if (matches.length !== 1) {\n return {\n requirement: null,\n reason: 'Payment matched multiple advertised requirements. Advertise unique network/payTo/amount combinations or provide resolveRequirement().',\n };\n }\n\n return { requirement: matches[0] };\n}\n\n/**\n * The settle of ONE merchant request, under the key its verification carried.\n *\n * The key is fresh for this request, so a replay without the buyer's\n * `X-UVD-Purchase` was earned by possession of the X-PAYMENT alone -- a resend,\n * not this purchase -- and is refused (see {@link refuseUnboundReplay}). With a\n * context, the facilitator already checked the buyer's capability, and a\n * replay is how a resumed purchase gets its answer back.\n */\nfunction createVerifiedPaymentState(\n client: FacilitatorClient,\n payment: X402Header,\n requirements: PaymentRequirements,\n verifyResult: VerifyResponse,\n binding: { idempotencyKey: string; receiptContext?: string },\n onSettled?: (result: SettleResponse) => void,\n): VerifiedPaymentState {\n let settlePromise: Promise<SettleResponse> | null = null;\n return {\n payment,\n requirements,\n verifyResult,\n idempotencyKey: binding.idempotencyKey,\n settle: () => {\n if (!settlePromise) {\n settlePromise = client.settle(payment, requirements, binding).then(answer => {\n const result = binding.receiptContext ? answer : refuseUnboundReplay(answer);\n // The payment is settled whatever happens to a header: never let\n // attaching the receipt turn this result into a rejected promise.\n try { onSettled?.(result); } catch (error) {\n console.warn('[x402] settled, but the payment response headers could not be attached:', error);\n }\n return result;\n });\n }\n return settlePromise;\n },\n };\n}\n\n/**\n * The result as propagated to the buyer in `PAYMENT-RESPONSE`: everything but\n * the merchant's `Idempotency-Key`, which is a binding and stays server-side.\n */\nfunction propagatedResult(result: VerifyResponse | SettleResponse): Record<string, unknown> {\n const { idempotencyKey: _key, ...propagated } = result;\n return propagated;\n}\n\n/** The answer to an authorization the facilitator admitted for another request. */\nexport interface PaymentConflictResponse {\n /** `409` when the payment was used; `503` + `Retry-After` while it is in flight. */\n status: 409 | 503;\n headers: Record<string, string>;\n body: {\n error: string;\n /** The facilitator's code, e.g. `authorization_already_settled`. */\n reason?: string;\n retryable: boolean;\n retryAfterSeconds?: number;\n safeToReplay: boolean;\n };\n}\n\n/**\n * Build the answer to a verify or settle that names an admitted authorization,\n * or `null` when the result is something else.\n *\n * - {@link AUTHORIZATION_IN_FLIGHT} -> `503` + `Retry-After`: resend the SAME\n * request (with its `X-UVD-Purchase`, if it had one) to learn the verdict;\n * never sign a new authorization while this one may still settle.\n * - {@link AUTHORIZATION_ALREADY_SETTLED}, {@link RECEIPT_REQUEST_CONFLICT} and\n * any other `409` from the facilitator -> `409`, not retryable: this X-PAYMENT\n * was already used and the purchase is not served again.\n *\n * Never `402` -- the payment was not refused, and a new signature would pay a\n * second time -- and never `500`.\n */\nexport function buildPaymentConflictResponse(\n failure: FacilitatorFailureFields & { error?: string; invalidReason?: string },\n): PaymentConflictResponse | null {\n if (isAuthorizationInFlight(failure)) {\n const { headers, body } = buildUnavailableResponse('Payment authorization in flight', failure);\n return { status: 503, headers, body: { ...body, reason: AUTHORIZATION_IN_FLIGHT } };\n }\n const used = isAuthorizationAlreadyUsed(failure);\n if (!used && failure.status !== 409) return null;\n return {\n status: 409,\n headers: {},\n body: {\n error: used ? 'Payment authorization already used' : 'Payment request conflict',\n reason: failure.errorCode ?? failure.invalidReason ?? failure.error,\n retryable: false,\n safeToReplay: false,\n },\n };\n}\n\n/** The body of a no-verdict refusal. See {@link buildUnavailableResponse}. */\nexport interface UnavailableBody {\n /** Human-readable summary. Never says the payment was rejected. */\n error: string;\n /** The facilitator's own reason, under whichever field it populated. */\n reason?: string;\n /** Always `true` — this response exists to say \"no verdict\", not \"refused\". */\n retryable: true;\n /** Whole seconds to wait, mirroring the `Retry-After` header. */\n retryAfterSeconds: number;\n /**\n * `false` for `forward_failed` and for a bare timeout: the write may already\n * have landed, so the caller must reconcile before resending.\n */\n safeToReplay: boolean;\n}\n\n/** A framework-agnostic HTTP response. See {@link buildUnavailableResponse}. */\nexport interface UnavailableResponse {\n /** Always 503. */\n status: 503;\n /** `Retry-After`, ready to spread onto any framework's header setter. */\n headers: Record<string, string>;\n body: UnavailableBody;\n /** Same value as the header, already clamped to a whole second >= 1. */\n retryAfterSeconds: number;\n}\n\n/**\n * Build the answer to a facilitator refusal that reached NO VERDICT.\n *\n * `verify` returns invalid for two different things: a payment that was\n * REJECTED, and a facilitator that never reached a verdict (`retryable`).\n * Answering `402` in the second case tells the buyer to sign a NEW\n * authorization while the first one is still live and still spendable by the\n * facilitator — so the buyer pays twice. The correct answer is `503` plus\n * `Retry-After`, which asks for the SAME credential again.\n *\n * This returns plain data — status, headers, body — so a handler written\n * without Express (Lambda, Hono, a Next route, Fastify, a bare `Response`) can\n * answer correctly without re-deriving the rule. The Express and Hono\n * middlewares in this SDK both build their reply from it.\n *\n * @param message - Summary for the `error` field, e.g. `'Payment verification unavailable'`\n * @param failure - The facilitator result. Only its failure fields are read.\n *\n * @example Lambda / any framework\n * ```ts\n * const verifyResult = await client.verify(payment, requirements);\n * if (!verifyResult.isValid && verifyResult.retryable) {\n * const r = buildUnavailableResponse('Payment verification unavailable', verifyResult);\n * return { statusCode: r.status, headers: r.headers, body: JSON.stringify(r.body) };\n * }\n * ```\n *\n * @example Web `Response`\n * ```ts\n * const r = buildUnavailableResponse('Payment settlement unavailable', settleResult);\n * return Response.json(r.body, { status: r.status, headers: r.headers });\n * ```\n */\nexport function buildUnavailableResponse(\n message: string,\n failure: FacilitatorFailureFields & { error?: string; invalidReason?: string },\n): UnavailableResponse {\n const seconds = Math.max(1, Math.ceil(failure.retryAfterSeconds ?? DEFAULT_RETRY_AFTER_SECONDS));\n return {\n status: 503,\n headers: { 'Retry-After': String(seconds) },\n body: {\n error: message,\n reason: failure.reason ?? failure.invalidReason ?? failure.error,\n retryable: true,\n retryAfterSeconds: seconds,\n safeToReplay: failure.safeToReplay === true,\n },\n retryAfterSeconds: seconds,\n };\n}\n\n/**\n * Answer a no-verdict facilitator refusal as 503 + `Retry-After`.\n *\n * The body repeats the facilitator's own `reason` and a `retryable` flag so a\n * client that only reads JSON still learns the payment was not rejected. The\n * header is a whole-second integer, as RFC 9110 requires.\n *\n * Express-shaped wrapper over {@link buildUnavailableResponse}, which is the\n * public, framework-agnostic form of the same decision.\n */\nfunction respondUnavailable(\n res: ExpressLikeResponse,\n message: string,\n failure: FacilitatorFailureFields & { error?: string; invalidReason?: string },\n): void {\n respondExpress(res, buildUnavailableResponse(message, failure));\n}\n\n/** Send a framework-agnostic `{ status, headers, body }` through Express. */\nfunction respondExpress(\n res: ExpressLikeResponse,\n { status, headers, body }: { status: number; headers: Record<string, string>; body: unknown },\n): void {\n const staged = res.status(status);\n if (Object.keys(headers).length > 0 && typeof staged.set === 'function') {\n staged.set(headers).json(body);\n return;\n }\n staged.json(body);\n}\n\n/** The slice of an Express `res` the middleware uses. Readers are optional for doubles. */\ntype ExpressLikeResponse = {\n set?: (headers: Record<string, string>) => unknown;\n /** Node's reader of a header already set, e.g. by a CORS middleware. */\n getHeader?: (name: string) => unknown;\n /** Express's alias of `getHeader`. */\n get?: (name: string) => unknown;\n /** True once the response went out; headers can no longer be added. */\n headersSent?: boolean;\n status: (code: number) => {\n json: (body: unknown) => void;\n set: (headers: Record<string, string>) => { json: (body: unknown) => void };\n };\n};\n\n/**\n * Add the payment result headers to an Express response, merging the CORS\n * expose list and the cache directives the application already set.\n *\n * Skipped once the response was sent: in `'manual'` mode a handler may answer\n * first and settle afterwards, and `res.set` then throws ERR_HTTP_HEADERS_SENT.\n */\nfunction setExpressPaymentHeaders(res: ExpressLikeResponse, result: VerifyResponse | SettleResponse): void {\n if (!result.receipt || !res.set || res.headersSent) return;\n const current = (name: string): string | undefined => {\n const value = res.getHeader ? res.getHeader(name) : res.get?.(name);\n if (value === undefined || value === null) return undefined;\n return Array.isArray(value) ? value.join(', ') : String(value);\n };\n res.set(mergePaymentResponseHeaders(propagatedResult(result), current));\n}\n\n/**\n * Create an Express-compatible middleware for x402 payments\n *\n * @param getRequirements - Function to get payment requirements for a request\n * @param options - Middleware options\n * @returns Express middleware function\n *\n * @example\n * ```ts\n * const paymentMiddleware = createPaymentMiddleware(\n * (req) => ({\n * amount: '1.00',\n * recipient: process.env.PAYMENT_RECIPIENT,\n * resource: `${req.protocol}://${req.get('host')}${req.originalUrl}`,\n * }),\n * { facilitatorUrl: 'https://facilitator.uvd.xyz' }\n * );\n *\n * app.get('/premium/*', paymentMiddleware, async (req, res) => {\n * const settleResult = await req.x402?.settle();\n * if (!settleResult?.success) {\n * return res.status(500).json({ error: settleResult?.error });\n * }\n *\n * res.json({ premium: 'data' });\n * });\n * ```\n */\nexport function createPaymentMiddleware(\n getRequirements: (req: { headers: Record<string, string | string[] | undefined> }) => PaymentRequirementsOptions,\n options: PaymentMiddlewareOptions = {}\n): (\n req: { headers: Record<string, string | string[] | undefined>; x402?: VerifiedPaymentState; method?: string; url?: string; originalUrl?: string; rawBody?: Uint8Array },\n res: ExpressLikeResponse,\n next: () => void\n) => Promise<void> {\n const client = new FacilitatorClient({\n baseUrl: options.facilitatorUrl || options.baseUrl,\n timeout: options.timeout,\n retries: options.retries,\n });\n const settlementStrategy = options.settlementStrategy || 'before-handler';\n\n return async (req, res, next) => {\n // Extract payment header\n const payment = extractPaymentFromHeaders(req.headers);\n\n // If no payment, return 402\n if (!payment) {\n const reqOptions = getRequirements(req);\n const { status, headers, body } = create402Response(reqOptions);\n res.status(status).set(headers).json(body);\n return;\n }\n\n // Build requirements and verify\n const reqOptions = getRequirements(req);\n const requirements = buildPaymentRequirements(reqOptions);\n let receiptContext: string | undefined;\n try {\n const entry = Object.entries(req.headers).find(([name]) => name.toLowerCase() === 'x-uvd-purchase')?.[1];\n if (entry !== undefined) {\n if (typeof entry !== 'string' || !req.method || (!['GET', 'HEAD'].includes(req.method.toUpperCase()) && !req.rawBody)) throw new Error('receipt context requires method and exact raw body');\n const actualUrl = new URL(req.originalUrl || req.url || reqOptions.resource, reqOptions.resource).toString();\n receiptContext = validatePurchaseContext(entry, req.method, actualUrl, req.rawBody || new Uint8Array());\n requirements.resource = actualUrl;\n }\n } catch { res.status(400).json({ error: 'receipt_context_mismatch' }); return; }\n // One key for this payment's verify, settle and their retries.\n const binding = { idempotencyKey: createIdempotencyKey(), receiptContext };\n const verifyResult = await client.verify(payment, requirements, binding);\n setExpressPaymentHeaders(res, verifyResult);\n\n if (!verifyResult.isValid) {\n // An authorization already admitted for another request: 409 when it was\n // used, 503 while it settles. Serving it would deliver the purchase twice.\n const conflict = buildPaymentConflictResponse(verifyResult);\n if (conflict) {\n respondExpress(res, conflict);\n return;\n }\n // 402 says \"your payment was REJECTED, sign a new authorization\". Sending\n // it for a facilitator that never reached a verdict is what makes the\n // buyer pay twice: their first authorization was never refused and is\n // still perfectly good. A no-verdict answer must keep the credential\n // alive, so it goes out as 503 + Retry-After instead.\n if (verifyResult.retryable) {\n respondUnavailable(res, 'Payment verification unavailable', verifyResult);\n return;\n }\n res.status(402).json({\n error: 'Payment verification failed',\n reason: verifyResult.invalidReason,\n });\n return;\n }\n\n req.x402 = createVerifiedPaymentState(client, payment, requirements, verifyResult, binding,\n result => setExpressPaymentHeaders(res, result));\n\n if (settlementStrategy === 'before-handler') {\n const settleResult = await req.x402.settle();\n if (!settleResult.success) {\n // A replayed or conflicting authorization is not a server fault: 409,\n // or 503 while in flight -- and the handler never runs.\n const conflict = buildPaymentConflictResponse(settleResult);\n if (conflict) {\n respondExpress(res, conflict);\n return;\n }\n // Same distinction on the settle side. A 500 tells a client its request\n // is broken and to stop; a settle that reached no verdict is the one\n // case where retrying the identical request is correct.\n //\n // `settlement_unconfirmed` deliberately lands in the 500 branch: its\n // transaction is already broadcast, so \"stop\" is the right instruction\n // and 503 + Retry-After would be an instruction to pay twice.\n if (settleResult.retryable) {\n respondUnavailable(res, 'Payment settlement unavailable', settleResult);\n return;\n }\n res.status(500).json(settlementFailureBody(settleResult, 'Unknown settlement error'));\n return;\n }\n }\n\n next();\n };\n}\n\n// ============================================================================\n// HONO MIDDLEWARE\n// ============================================================================\n\n/**\n * Options for creating a Hono x402 payment middleware\n */\nexport interface HonoMiddlewareOptions extends PaymentMiddlewareOptions {\n /** Payment requirements to advertise */\n accepts: PaymentAcceptance[];\n /** Response version to advertise (defaults to auto) */\n x402Version?: X402Version | 'auto';\n /** Custom requirement resolver for ambiguous multi-accept flows */\n resolveRequirement?: PaymentRequirementResolver;\n}\n\n/**\n * Create a Hono-compatible middleware for x402 payments.\n *\n * Handles the x402 payment flow:\n * 1. Returns 402 with payment requirements if no X-PAYMENT header\n * 2. Verifies the payment with the facilitator\n * 3. Optionally settles before the handler when settlementStrategy is set\n * 4. Passes control to the next handler on success\n *\n * @param options - Middleware options with facilitator URL and payment accepts\n * @returns Hono middleware function\n *\n * @example\n * ```ts\n * import { createHonoMiddleware } from 'uvd-x402-sdk';\n *\n * const paywall = createHonoMiddleware({\n * accepts: [{\n * network: 'skale-base',\n * asset: '0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20',\n * amount: '1000000',\n * payTo: '0xYourWallet',\n * extra: { name: 'Bridged USDC (SKALE Bridge)', version: '2' },\n * }],\n * });\n *\n * app.get('/api/premium', paywall, (c) => {\n * return c.json({ message: 'Premium content!' });\n * });\n * ```\n */\n/**\n * The body for a settle failure the caller must NOT retry.\n *\n * When the facilitator answered `settlement_unconfirmed` the transaction was\n * broadcast and may be mined, and the hash plus `paymentId` are the only way\n * anyone downstream can find out which. Dropping them at this hop rebuilds, one\n * layer up, exactly the dead end the facilitator change removed: \"something\n * went wrong, and here is nothing you can look up\".\n *\n * `retryable: false` is stated rather than implied — the buyer's client reads\n * JSON, and a bare `500` is only a convention.\n */\nfunction settlementFailureBody(\n failure: FacilitatorFailureFields & { error?: string },\n fallbackReason: string,\n): Record<string, unknown> {\n return {\n error: 'Payment settlement failed',\n reason: failure.error || fallbackReason,\n retryable: false,\n ...(failure.errorCode !== undefined ? { errorCode: failure.errorCode } : {}),\n ...(failure.transaction !== undefined ? { transaction: failure.transaction } : {}),\n ...(failure.paymentId !== undefined ? { paymentId: failure.paymentId } : {}),\n };\n}\n\n/** {@link respondUnavailable} for a Hono context. */\nfunction honoUnavailable(\n c: HonoLikeContext,\n message: string,\n failure: FacilitatorFailureFields & { error?: string; invalidReason?: string },\n): unknown {\n return respondHono(c, buildUnavailableResponse(message, failure));\n}\n\n/** Send a framework-agnostic `{ status, headers, body }` through Hono. */\nfunction respondHono(\n c: HonoLikeContext,\n { status, headers, body }: { status: number; headers: Record<string, string>; body: unknown },\n): unknown {\n for (const [name, value] of Object.entries(headers)) {\n c.header?.(name, value);\n }\n return c.json(body, status);\n}\n\n/** The slice of a Hono `Context` the middleware uses. Optional parts fit older doubles. */\ntype HonoLikeContext = {\n req: { header: (name: string) => string | undefined; url: string; method?: string; raw?: Request };\n json: (body: unknown, status?: number) => unknown;\n set?: (key: string, value: unknown) => void;\n /** Hono's response-header setter. Optional so older context doubles still fit. */\n header?: (name: string, value: string) => void;\n /** Hono's response so far, read to merge with headers a CORS middleware set. */\n res?: { headers: { get: (name: string) => string | null } };\n /** True once a handler's response was committed to the context. */\n finalized?: boolean;\n};\n\n/**\n * Add the payment result headers through Hono, merging the CORS expose list\n * and the cache directives already on the response instead of replacing them.\n *\n * Skipped once the response was committed, as in Express: a `'manual'` settle\n * after the handler returned must not rebuild a response already handed back.\n */\nfunction setHonoPaymentHeaders(c: HonoLikeContext, result: VerifyResponse | SettleResponse): void {\n if (!result.receipt || !c.header || c.finalized) return;\n const current = (name: string) => c.res?.headers.get(name) ?? undefined;\n for (const [name, value] of Object.entries(mergePaymentResponseHeaders(propagatedResult(result), current))) {\n c.header(name, value);\n }\n}\n\nexport function createHonoMiddleware(options: HonoMiddlewareOptions) {\n const client = new FacilitatorClient({\n baseUrl: options.facilitatorUrl || options.baseUrl,\n timeout: options.timeout,\n retries: options.retries,\n });\n const settlementStrategy = options.settlementStrategy || 'before-handler';\n\n if (!options.accepts[0]) {\n throw new Error('At least one accept entry is required');\n }\n\n return async (\n c: HonoLikeContext,\n next: () => Promise<void>\n ) => {\n const paymentHeader = c.req.header('PAYMENT-SIGNATURE') || c.req.header('X-PAYMENT') || c.req.header('x-payment');\n const advertisedVersion = resolveAdvertisedVersion(options.accepts, options.x402Version);\n const advertisedRequirements = options.accepts.map((accept) =>\n buildRequirementFromAcceptance(accept, c.req.url, advertisedVersion)\n );\n\n if (!paymentHeader) {\n return c.json(\n create402ResponseBody(\n advertisedRequirements[0],\n advertisedRequirements,\n advertisedVersion,\n options.facilitatorUrl\n ),\n 402\n );\n }\n\n const parsed = parsePaymentHeader(paymentHeader);\n if (!parsed) {\n return c.json({ error: 'Invalid X-PAYMENT header' }, 400);\n }\n\n const { requirement, reason } = await resolvePaymentRequirement(\n parsed,\n advertisedRequirements,\n options.resolveRequirement\n );\n\n if (!requirement) {\n return c.json({\n error: 'Payment verification failed',\n reason,\n }, 402);\n }\n\n let receiptContext: string | undefined;\n try {\n const header = c.req.header('X-UVD-Purchase');\n if (header) {\n const method = c.req.method || c.req.raw?.method;\n if (!method || (!['GET', 'HEAD'].includes(method) && !c.req.raw)) throw new Error('raw request required');\n const bytes = c.req.raw ? new Uint8Array(await c.req.raw.clone().arrayBuffer()) : new Uint8Array();\n receiptContext = validatePurchaseContext(header, method, c.req.url, bytes);\n }\n } catch { return c.json({ error: 'receipt_context_mismatch' }, 400); }\n // One key for this payment's verify, settle and their retries.\n const binding = { idempotencyKey: createIdempotencyKey(), receiptContext };\n const verifyResult = await client.verify(parsed, requirement, binding);\n setHonoPaymentHeaders(c, verifyResult);\n if (!verifyResult.isValid) {\n // See the Express branch: an admitted authorization is 409 or 503.\n const conflict = buildPaymentConflictResponse(verifyResult);\n if (conflict) return respondHono(c, conflict);\n // See respondUnavailable: 402 here would tell the buyer to sign again for\n // an authorization the facilitator never rejected.\n if (verifyResult.retryable) {\n return honoUnavailable(c, 'Payment verification unavailable', verifyResult);\n }\n return c.json({\n error: 'Payment verification failed',\n reason: verifyResult.invalidReason,\n }, 402);\n }\n\n const verifiedPayment = createVerifiedPaymentState(client, parsed, requirement, verifyResult, binding,\n result => setHonoPaymentHeaders(c, result));\n c.set?.('x402', verifiedPayment);\n\n if (settlementStrategy === 'before-handler') {\n const settleResult = await verifiedPayment.settle();\n if (!settleResult.success) {\n const conflict = buildPaymentConflictResponse(settleResult);\n if (conflict) return respondHono(c, conflict);\n if (settleResult.retryable) {\n return honoUnavailable(c, 'Payment settlement unavailable', settleResult);\n }\n // See the Express branch: `settlement_unconfirmed` belongs here, with\n // its hash, and not behind a Retry-After.\n return c.json(settlementFailureBody(settleResult, 'Unknown error'), 500);\n }\n }\n\n await next();\n };\n}\n\n// ============================================================================\n// BAZAAR DISCOVERY API\n// ============================================================================\n//\n// The Bazaar is the discovery registry served by the facilitator itself, under\n// `/discovery/*`. There is no separate Bazaar host.\n\n/**\n * Maximum length of the free-text `q` filter.\n *\n * Mirrors the facilitator's `MAX_SEARCH_LEN`; a longer needle is rejected\n * server-side with a 400.\n */\nexport const MAX_SEARCH_LEN = 128;\n\n/**\n * Liveness of a registered resource, as measured by the facilitator's prober.\n *\n * Resources that stop answering are quarantined rather than deleted, so filter\n * on this before paying anyone.\n */\nexport type DiscoveryHealthStatus =\n | 'alive'\n | 'degraded'\n | 'auth_gated'\n | 'quarantined'\n | 'unknown'\n | 'unprobeable';\n\n/** Values accepted by the `health` filter, including the `any` escape hatch. */\nexport const HEALTH_FILTERS = [\n 'alive',\n 'degraded',\n 'auth_gated',\n 'quarantined',\n 'unknown',\n 'unprobeable',\n 'any',\n] as const;\n\n/** Curated tier, in descending order of trust. */\nexport type DiscoveryTier = 'first_party' | 'vip' | 'verified' | 'listed';\n\n/** Values accepted by the `tier` filter. */\nexport const TIER_FILTERS = [\n 'first_party',\n 'vip',\n 'verified',\n 'listed',\n] as const;\n\n/** How a resource got into the registry. */\nexport type DiscoverySource =\n | 'self_registered'\n | 'settlement'\n | 'crawled'\n | 'aggregated';\n\n/** Health of a single resource, as reported by the registry's prober. */\nexport interface DiscoveryHealth {\n /** Last observed liveness */\n status?: DiscoveryHealthStatus;\n /** Unix epoch seconds of the last probe */\n lastChecked?: number;\n /** HTTP status the probe got back (402 is the healthy answer for x402) */\n httpStatus?: number;\n /** Round-trip time of the last probe, in milliseconds */\n latencyMs?: number;\n}\n\n/** Curation metadata attached to a resource. */\nexport interface DiscoveryCuration {\n /** Curated tier */\n tier?: DiscoveryTier;\n /** Human-readable name of the curated set */\n label?: string;\n}\n\n/** One payment method a resource declares. */\nexport interface DiscoveryAccepts {\n /** Payment scheme (\"exact\", \"escrow\", \"commerce\") */\n scheme: string;\n /** CAIP-2 network id, e.g. \"eip155:8453\" */\n network: string;\n /** Token contract address */\n asset?: string;\n /** Price in atomic units of `asset` */\n amount?: string;\n /** Recipient address */\n payTo?: string;\n /** Settlement deadline in seconds */\n maxTimeoutSeconds?: number;\n /** Scheme-specific extras (EIP-712 domain, etc.) */\n extra?: Record<string, unknown>;\n /** Anything the registry adds later */\n [key: string]: unknown;\n}\n\n/**\n * A discoverable paid resource, exactly as `GET /discovery/resources` serves it.\n *\n * Timestamps are Unix epoch **seconds**, not ISO strings and not milliseconds.\n */\nexport interface DiscoveryResource {\n /** Resource URL. This is the registry's primary key -- there is no `id` */\n url: string;\n /** Resource type (\"http\", \"mcp\", \"a2a\") */\n type: string;\n /** x402 protocol version the resource speaks */\n x402Version: number;\n /** Human-readable description */\n description?: string;\n /** Payment methods the resource accepts */\n accepts: DiscoveryAccepts[];\n /** Free-form metadata (category, provider, tags) */\n metadata?: Record<string, unknown>;\n /** How this resource entered the registry */\n source?: DiscoverySource;\n /** Facilitator this resource was aggregated from */\n sourceFacilitator?: string;\n /** Unix epoch seconds when the registry first saw this resource */\n firstSeen?: number;\n /** Unix epoch seconds when the registry last saw this resource */\n lastSeen?: number;\n /** Unix epoch seconds of the last change to this record */\n lastUpdated?: number;\n /** Liveness, when the resource has been probed */\n health?: DiscoveryHealth;\n /** Curation tier, when the resource has been curated */\n curation?: DiscoveryCuration;\n /** Anything the registry adds later */\n [key: string]: unknown;\n}\n\n/** Pagination envelope of `GET /discovery/resources`. */\nexport interface DiscoveryPagination {\n /** Page size that was applied */\n limit: number;\n /** Offset that was applied */\n offset: number;\n /** Total number of resources matching the filters, across all pages */\n total: number;\n}\n\n/** Paginated response from `GET /discovery/resources`. */\nexport interface DiscoveryResponse {\n /** x402 protocol version of the response envelope */\n x402Version: number;\n /** Resources on this page */\n items: DiscoveryResource[];\n /** Pagination state */\n pagination: DiscoveryPagination;\n}\n\n/**\n * Filters for `listResources()`.\n *\n * Every one of these is applied server-side over the whole catalog, so\n * `pagination.total` reflects the filtered set. Filtering a page after the\n * fact is not the same thing and will under-report.\n */\nexport interface DiscoveryListOptions {\n /** Page size (default: 10, max: 100) */\n limit?: number;\n /** Number of resources to skip */\n offset?: number;\n /** Filter by category */\n category?: string;\n /** Filter by network, CAIP-2 or v1 name */\n network?: string;\n /** Filter by provider name */\n provider?: string;\n /** Filter by tag */\n tag?: string;\n /** Filter by how the resource was discovered */\n source?: DiscoverySource;\n /** Filter by originating facilitator */\n sourceFacilitator?: string;\n /** Filter by liveness, or 'any' to opt out of the default visibility rules */\n health?: DiscoveryHealthStatus | 'any';\n /** Filter by curated tier */\n tier?: DiscoveryTier;\n /** Free-text search over url / description / provider / category / tags */\n q?: string;\n}\n\n/** Options for `registerResource()`. */\nexport interface DiscoveryRegisterOptions {\n /** URL of the paid resource. Doubles as its identity in the registry */\n url: string;\n /** Resource type (default: \"http\") */\n type?: string;\n /** Human-readable description */\n description?: string;\n /** Payment methods the resource accepts */\n accepts?: DiscoveryAccepts[];\n /** Free-form metadata (category, provider, tags) */\n metadata?: Record<string, unknown>;\n}\n\n/** Aggregate catalog metrics from `GET /discovery/stats`. */\nexport interface DiscoveryStats {\n /** Every record the registry holds, including quarantined ones */\n total: number;\n /** Records served by default listings */\n visible: number;\n /** Counts by discovery source */\n bySource: Record<string, number>;\n /** Counts by originating facilitator */\n bySourceFacilitator: Record<string, number>;\n /** Counts by CAIP-2 network */\n byNetwork: Record<string, number>;\n /** Counts by curated tier */\n byTier: Record<string, number>;\n /** Counts by liveness */\n byHealth: Record<string, number>;\n /** Unix epoch seconds this snapshot was computed (60s cache) */\n generatedAt?: number;\n}\n\n/** Options for the {@link BazaarClient}. */\nexport interface BazaarClientOptions {\n /** Facilitator base URL (default: https://facilitator.ultravioletadao.xyz) */\n baseUrl?: string;\n /** Request timeout in milliseconds (default: 30000) */\n timeout?: number;\n}\n\n/** Render an epoch-seconds field as a `Date`. */\nexport function epochToDate(seconds?: number): Date | undefined {\n return seconds === undefined ? undefined : new Date(seconds * 1000);\n}\n\n/** True when the last probe reached this resource. */\nexport function isAlive(resource: DiscoveryResource): boolean {\n return resource.health?.status === 'alive';\n}\n\n/**\n * Client for the x402 Bazaar Discovery API.\n *\n * The Bazaar is the facilitator's own registry of x402-enabled resources.\n * Providers register their endpoints and consumers discover them, with a\n * liveness probe and a curation tier attached to every record.\n *\n * @example\n * ```ts\n * const bazaar = new BazaarClient();\n *\n * // Only endpoints a probe actually reached, best-curated first\n * const page = await bazaar.listResources({ limit: 20, health: 'alive', tier: 'vip' });\n * for (const r of page.items) {\n * console.log(r.url, r.health?.status, r.health?.latencyMs, r.curation?.label);\n * }\n *\n * // Free-text search runs server-side over the whole catalog\n * const hits = await bazaar.listResources({ q: 'logs' });\n * console.log(hits.pagination.total);\n *\n * // Register your own\n * await bazaar.registerResource({\n * url: 'https://api.example.com/v1/generate',\n * description: 'Generate images with AI',\n * accepts: [{\n * scheme: 'exact',\n * network: 'eip155:8453',\n * asset: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\n * amount: '10000',\n * payTo: '0xYourWallet...',\n * maxTimeoutSeconds: 60,\n * }],\n * metadata: { category: 'ai', tags: ['image'] },\n * });\n * ```\n */\nexport class BazaarClient {\n private readonly baseUrl: string;\n private readonly timeout: number;\n\n constructor(options: BazaarClientOptions = {}) {\n this.baseUrl = (\n options.baseUrl || 'https://facilitator.ultravioletadao.xyz'\n ).replace(/\\/+$/, '');\n this.timeout = options.timeout || 30000;\n }\n\n /**\n * Issue a request against the facilitator with the configured timeout.\n */\n private async request<T>(path: string, init?: RequestInit): Promise<T> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(`${this.baseUrl}${path}`, {\n ...init,\n headers: { Accept: 'application/json', ...(init?.headers || {}) },\n signal: controller.signal,\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(\n `Bazaar API error: ${response.status} - ${errorText}`\n );\n }\n\n return (await response.json()) as T;\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n /**\n * List resources from the discovery registry.\n *\n * @param options - Server-side filters and pagination\n * @returns One page of resources plus the total across all pages\n *\n * @example\n * ```ts\n * const page = await bazaar.listResources({ network: 'eip155:8453', health: 'alive' });\n * ```\n */\n async listResources(\n options: DiscoveryListOptions = {}\n ): Promise<DiscoveryResponse> {\n if (options.q !== undefined && options.q.length > MAX_SEARCH_LEN) {\n throw new Error(`q must be at most ${MAX_SEARCH_LEN} characters`);\n }\n\n const params = new URLSearchParams();\n params.set('limit', String(options.limit ?? 10));\n params.set('offset', String(options.offset ?? 0));\n if (options.category) params.set('category', options.category);\n if (options.network) params.set('network', options.network);\n if (options.provider) params.set('provider', options.provider);\n if (options.tag) params.set('tag', options.tag);\n if (options.source) params.set('source', options.source);\n if (options.sourceFacilitator)\n params.set('sourceFacilitator', options.sourceFacilitator);\n if (options.health) params.set('health', options.health);\n if (options.tier) params.set('tier', options.tier);\n if (options.q) params.set('q', options.q);\n\n return this.request<DiscoveryResponse>(\n `/discovery/resources?${params.toString()}`\n );\n }\n\n /**\n * Walk the whole filtered catalog, one page at a time.\n *\n * Pages are fetched in sequence rather than in parallel: the read routes are\n * rate limited, and a burst of parallel pages is how a legitimate catalog\n * walk turns into a wall of 429s.\n *\n * @param options - Same filters as {@link listResources}; `limit` is the page size\n *\n * @example\n * ```ts\n * for await (const r of bazaar.iterateResources({ health: 'alive' })) {\n * console.log(r.url);\n * }\n * ```\n */\n async *iterateResources(\n options: DiscoveryListOptions = {}\n ): AsyncGenerator<DiscoveryResource, void, undefined> {\n const pageSize = options.limit ?? 100;\n let offset = options.offset ?? 0;\n\n for (;;) {\n const page = await this.listResources({\n ...options,\n limit: pageSize,\n offset,\n });\n if (page.items.length === 0) return;\n\n for (const item of page.items) yield item;\n\n offset += page.items.length;\n if (offset >= page.pagination.total) return;\n }\n }\n\n /**\n * Look up a single resource by its URL.\n *\n * The registry keys on URL and has no by-id lookup, so this searches and\n * then matches exactly.\n *\n * @param resourceUrl - Exact URL of the resource\n * @returns The resource, or null when it is not registered\n */\n async getResourceByUrl(\n resourceUrl: string\n ): Promise<DiscoveryResource | null> {\n const page = await this.listResources({\n q: resourceUrl.slice(0, MAX_SEARCH_LEN),\n limit: 100,\n health: 'any',\n });\n return page.items.find((item) => item.url === resourceUrl) ?? null;\n }\n\n /**\n * Register a paid resource in the discovery registry.\n *\n * Registration is open and rate limited; re-registering a known URL updates\n * the existing record rather than creating a duplicate.\n *\n * @param options - Resource details\n * @returns The registry's acknowledgement\n */\n async registerResource(\n options: DiscoveryRegisterOptions\n ): Promise<Record<string, unknown>> {\n const payload: Record<string, unknown> = {\n url: options.url,\n type: options.type || 'http',\n description: options.description || '',\n };\n if (options.accepts) payload.accepts = options.accepts;\n if (options.metadata) payload.metadata = options.metadata;\n\n return this.request<Record<string, unknown>>('/discovery/register', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(payload),\n });\n }\n\n /**\n * Aggregate catalog metrics (60s cached server-side).\n *\n * @returns Counts by source, facilitator, network, tier and liveness\n */\n async getStats(): Promise<DiscoveryStats> {\n return this.request<DiscoveryStats>('/discovery/stats');\n }\n\n /**\n * Check that the facilitator serving the registry is up.\n *\n * @returns True when the facilitator answers its health check\n */\n async healthCheck(): Promise<boolean> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n try {\n const response = await fetch(`${this.baseUrl}/health`, {\n method: 'GET',\n signal: controller.signal,\n });\n return response.ok;\n } catch {\n return false;\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n /**\n * @deprecated Renamed to {@link listResources}, which returns the registry's\n * real `{ items, pagination }` envelope. The old `discover()` returned a\n * `{ resources, page, totalPages }` shape that no endpoint ever served.\n */\n async discover(options: DiscoveryListOptions = {}): Promise<DiscoveryResponse> {\n return this.listResources(options);\n }\n}\n\n/**\n * @deprecated Use {@link DiscoveryResource}. The old shape (`id`, `name`,\n * `pricePerRequest`, `isActive`, ISO `createdAt`) described an API that was\n * never deployed.\n */\nexport type BazaarResource = DiscoveryResource;\n\n/** @deprecated Use {@link DiscoveryResponse}. */\nexport type BazaarDiscoverResponse = DiscoveryResponse;\n\n/** @deprecated Use {@link DiscoveryListOptions}. */\nexport type BazaarDiscoverOptions = DiscoveryListOptions;\n\n/** @deprecated Use {@link DiscoveryRegisterOptions}. */\nexport type BazaarRegisterOptions = DiscoveryRegisterOptions;\n\n// ============================================================================\n// ESCROW & REFUND EXTENSION\n// ============================================================================\n\n/**\n * Escrow payment status\n */\nexport type EscrowStatus =\n | 'pending' // Payment initiated, awaiting confirmation\n | 'held' // Funds held in escrow\n | 'released' // Funds released to recipient\n | 'refunded' // Funds returned to payer\n | 'disputed' // Dispute in progress\n | 'expired'; // Escrow expired without resolution\n\n/**\n * Refund request status\n */\nexport type RefundStatus =\n | 'pending' // Refund requested, awaiting processing\n | 'approved' // Refund approved\n | 'rejected' // Refund rejected\n | 'processed' // Refund completed on-chain\n | 'disputed'; // Under dispute review\n\n/**\n * Dispute resolution outcome\n */\nexport type DisputeOutcome =\n | 'pending' // Dispute under review\n | 'payer_wins' // Payer gets refund\n | 'recipient_wins' // Recipient keeps funds\n | 'split'; // Funds split between parties\n\n/**\n * Escrow payment record\n */\nexport interface EscrowPayment {\n /** Unique escrow ID */\n id: string;\n /** Original payment header (base64 encoded) */\n paymentHeader: string;\n /** Current status */\n status: EscrowStatus;\n /** Network where payment was made */\n network: string;\n /** Payer address */\n payer: string;\n /** Recipient address */\n recipient: string;\n /** Amount in atomic units */\n amount: string;\n /** Token/asset contract */\n asset: string;\n /** Resource URL being paid for */\n resource: string;\n /** Escrow expiration timestamp (ISO) */\n expiresAt: string;\n /** Release conditions (optional) */\n releaseConditions?: {\n /** Minimum time before release (seconds) */\n minHoldTime?: number;\n /** Required confirmations */\n confirmations?: number;\n /** Custom condition metadata */\n custom?: unknown;\n };\n /** Transaction hash if released/refunded */\n transactionHash?: string;\n /** Creation timestamp (ISO) */\n createdAt: string;\n /** Last update timestamp (ISO) */\n updatedAt: string;\n}\n\n/**\n * Refund request record\n */\nexport interface RefundRequest {\n /** Unique refund request ID */\n id: string;\n /** Related escrow ID */\n escrowId: string;\n /** Current status */\n status: RefundStatus;\n /** Reason for refund request */\n reason: string;\n /** Additional evidence/details */\n evidence?: string;\n /** Amount requested (may be partial) */\n amountRequested: string;\n /** Amount approved (if any) */\n amountApproved?: string;\n /** Requester (payer) address */\n requester: string;\n /** Transaction hash if processed */\n transactionHash?: string;\n /** Response from recipient/facilitator */\n response?: {\n status: 'approved' | 'rejected';\n reason?: string;\n respondedAt: string;\n };\n /** Creation timestamp (ISO) */\n createdAt: string;\n /** Last update timestamp (ISO) */\n updatedAt: string;\n}\n\n/**\n * Dispute record\n */\nexport interface Dispute {\n /** Unique dispute ID */\n id: string;\n /** Related escrow ID */\n escrowId: string;\n /** Related refund request ID (if any) */\n refundRequestId?: string;\n /** Dispute outcome */\n outcome: DisputeOutcome;\n /** Initiator (payer or recipient) */\n initiator: 'payer' | 'recipient';\n /** Reason for dispute */\n reason: string;\n /** Evidence from payer */\n payerEvidence?: string;\n /** Evidence from recipient */\n recipientEvidence?: string;\n /** Arbitration notes */\n arbitrationNotes?: string;\n /** Amount resolved to payer */\n payerAmount?: string;\n /** Amount resolved to recipient */\n recipientAmount?: string;\n /** Transaction hash(es) for resolution */\n transactionHashes?: string[];\n /** Creation timestamp (ISO) */\n createdAt: string;\n /** Resolution timestamp (ISO) */\n resolvedAt?: string;\n}\n\n/**\n * Options for creating an escrow payment\n */\nexport interface CreateEscrowOptions {\n /** Payment header (from client SDK) */\n paymentHeader: string;\n /** Payment requirements */\n requirements: PaymentRequirements;\n /** Escrow duration in seconds (default: 86400 = 24h) */\n escrowDuration?: number;\n /** Release conditions */\n releaseConditions?: {\n minHoldTime?: number;\n confirmations?: number;\n custom?: unknown;\n };\n}\n\n/**\n * Options for requesting a refund\n */\nexport interface RequestRefundOptions {\n /** Escrow ID to refund */\n escrowId: string;\n /** Reason for refund */\n reason: string;\n /** Amount to refund (full amount if not specified) */\n amount?: string;\n /** Supporting evidence */\n evidence?: string;\n}\n\n/**\n * Options for the EscrowClient\n */\nexport interface EscrowClientOptions {\n /** Base URL of the Escrow API (default: https://escrow.ultravioletadao.xyz) */\n baseUrl?: string;\n /** API key for authenticated operations */\n apiKey?: string;\n /** Request timeout in milliseconds (default: 30000) */\n timeout?: number;\n}\n\n/**\n * Client for x402 Escrow & Refund operations\n *\n * The Escrow system holds payments until service is verified,\n * enabling refunds and dispute resolution.\n *\n * @example\n * ```ts\n * // Create escrow payment (backend)\n * const escrow = new EscrowClient();\n * const escrowPayment = await escrow.createEscrow({\n * paymentHeader: req.headers['x-payment'],\n * requirements: paymentRequirements,\n * escrowDuration: 86400, // 24 hours\n * });\n *\n * // After service is provided, release the escrow\n * await escrow.release(escrowPayment.id);\n *\n * // If service not provided, payer can request refund\n * await escrow.requestRefund({\n * escrowId: escrowPayment.id,\n * reason: 'Service not delivered within expected timeframe',\n * });\n * ```\n */\nexport class EscrowClient {\n private readonly baseUrl: string;\n private readonly apiKey?: string;\n private readonly timeout: number;\n\n constructor(options: EscrowClientOptions = {}) {\n this.baseUrl = options.baseUrl || 'https://escrow.ultravioletadao.xyz';\n this.apiKey = options.apiKey;\n this.timeout = options.timeout || 30000;\n }\n\n private getHeaders(authenticated: boolean = false): Record<string, string> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n };\n if (authenticated && this.apiKey) {\n headers['Authorization'] = `Bearer ${this.apiKey}`;\n }\n return headers;\n }\n\n /**\n * Create an escrow payment\n *\n * Holds the payment in escrow until released or refunded.\n *\n * @param options - Escrow creation options\n * @returns Created escrow payment\n */\n async createEscrow(options: CreateEscrowOptions): Promise<EscrowPayment> {\n const url = `${this.baseUrl}/escrow`;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: this.getHeaders(true),\n body: JSON.stringify({\n paymentHeader: options.paymentHeader,\n paymentRequirements: options.requirements,\n escrowDuration: options.escrowDuration || 86400,\n releaseConditions: options.releaseConditions,\n }),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Escrow API error: ${response.status} - ${errorText}`);\n }\n\n return await response.json();\n } catch (error) {\n clearTimeout(timeoutId);\n throw error;\n }\n }\n\n /**\n * Get escrow payment by ID\n *\n * @param escrowId - Escrow payment ID\n * @returns Escrow payment details\n */\n async getEscrow(escrowId: string): Promise<EscrowPayment> {\n const url = `${this.baseUrl}/escrow/${encodeURIComponent(escrowId)}`;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(url, {\n method: 'GET',\n headers: this.getHeaders(),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Escrow API error: ${response.status} - ${errorText}`);\n }\n\n return await response.json();\n } catch (error) {\n clearTimeout(timeoutId);\n throw error;\n }\n }\n\n /**\n * Release escrow funds to recipient\n *\n * Call this after service has been successfully provided.\n *\n * @param escrowId - Escrow payment ID\n * @returns Updated escrow payment with transaction hash\n */\n async release(escrowId: string): Promise<EscrowPayment> {\n const url = `${this.baseUrl}/escrow/${encodeURIComponent(escrowId)}/release`;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: this.getHeaders(true),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Escrow API error: ${response.status} - ${errorText}`);\n }\n\n return await response.json();\n } catch (error) {\n clearTimeout(timeoutId);\n throw error;\n }\n }\n\n /**\n * Request a refund for an escrow payment\n *\n * Initiates a refund request that must be approved.\n *\n * @param options - Refund request options\n * @returns Created refund request\n */\n async requestRefund(options: RequestRefundOptions): Promise<RefundRequest> {\n const url = `${this.baseUrl}/escrow/${encodeURIComponent(options.escrowId)}/refund`;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: this.getHeaders(true),\n body: JSON.stringify({\n reason: options.reason,\n amount: options.amount,\n evidence: options.evidence,\n }),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Escrow API error: ${response.status} - ${errorText}`);\n }\n\n return await response.json();\n } catch (error) {\n clearTimeout(timeoutId);\n throw error;\n }\n }\n\n /**\n * Approve a refund request (for recipients)\n *\n * @param refundId - Refund request ID\n * @param amount - Amount to approve (may be less than requested)\n * @returns Updated refund request\n */\n async approveRefund(refundId: string, amount?: string): Promise<RefundRequest> {\n const url = `${this.baseUrl}/refund/${encodeURIComponent(refundId)}/approve`;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: this.getHeaders(true),\n body: JSON.stringify({ amount }),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Escrow API error: ${response.status} - ${errorText}`);\n }\n\n return await response.json();\n } catch (error) {\n clearTimeout(timeoutId);\n throw error;\n }\n }\n\n /**\n * Reject a refund request (for recipients)\n *\n * @param refundId - Refund request ID\n * @param reason - Reason for rejection\n * @returns Updated refund request\n */\n async rejectRefund(refundId: string, reason: string): Promise<RefundRequest> {\n const url = `${this.baseUrl}/refund/${encodeURIComponent(refundId)}/reject`;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: this.getHeaders(true),\n body: JSON.stringify({ reason }),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Escrow API error: ${response.status} - ${errorText}`);\n }\n\n return await response.json();\n } catch (error) {\n clearTimeout(timeoutId);\n throw error;\n }\n }\n\n /**\n * Get refund request by ID\n *\n * @param refundId - Refund request ID\n * @returns Refund request details\n */\n async getRefund(refundId: string): Promise<RefundRequest> {\n const url = `${this.baseUrl}/refund/${encodeURIComponent(refundId)}`;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(url, {\n method: 'GET',\n headers: this.getHeaders(),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Escrow API error: ${response.status} - ${errorText}`);\n }\n\n return await response.json();\n } catch (error) {\n clearTimeout(timeoutId);\n throw error;\n }\n }\n\n /**\n * Open a dispute for an escrow payment\n *\n * Initiates arbitration when payer and recipient disagree.\n *\n * @param escrowId - Escrow payment ID\n * @param reason - Reason for dispute\n * @param evidence - Supporting evidence\n * @returns Created dispute\n */\n async openDispute(\n escrowId: string,\n reason: string,\n evidence?: string\n ): Promise<Dispute> {\n const url = `${this.baseUrl}/escrow/${encodeURIComponent(escrowId)}/dispute`;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: this.getHeaders(true),\n body: JSON.stringify({ reason, evidence }),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Escrow API error: ${response.status} - ${errorText}`);\n }\n\n return await response.json();\n } catch (error) {\n clearTimeout(timeoutId);\n throw error;\n }\n }\n\n /**\n * Submit evidence to a dispute\n *\n * @param disputeId - Dispute ID\n * @param evidence - Evidence to submit\n * @returns Updated dispute\n */\n async submitEvidence(disputeId: string, evidence: string): Promise<Dispute> {\n const url = `${this.baseUrl}/dispute/${encodeURIComponent(disputeId)}/evidence`;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: this.getHeaders(true),\n body: JSON.stringify({ evidence }),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Escrow API error: ${response.status} - ${errorText}`);\n }\n\n return await response.json();\n } catch (error) {\n clearTimeout(timeoutId);\n throw error;\n }\n }\n\n /**\n * Get dispute by ID\n *\n * @param disputeId - Dispute ID\n * @returns Dispute details\n */\n async getDispute(disputeId: string): Promise<Dispute> {\n const url = `${this.baseUrl}/dispute/${encodeURIComponent(disputeId)}`;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(url, {\n method: 'GET',\n headers: this.getHeaders(),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Escrow API error: ${response.status} - ${errorText}`);\n }\n\n return await response.json();\n } catch (error) {\n clearTimeout(timeoutId);\n throw error;\n }\n }\n\n /**\n * List escrow payments (with filters)\n *\n * @param options - Filter and pagination options\n * @returns Paginated list of escrow payments\n */\n async listEscrows(options: {\n status?: EscrowStatus;\n payer?: string;\n recipient?: string;\n page?: number;\n limit?: number;\n } = {}): Promise<{\n escrows: EscrowPayment[];\n total: number;\n page: number;\n limit: number;\n hasMore: boolean;\n }> {\n const params = new URLSearchParams();\n if (options.status) params.set('status', options.status);\n if (options.payer) params.set('payer', options.payer);\n if (options.recipient) params.set('recipient', options.recipient);\n if (options.page) params.set('page', options.page.toString());\n if (options.limit) params.set('limit', options.limit.toString());\n\n const url = `${this.baseUrl}/escrow${params.toString() ? `?${params}` : ''}`;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(url, {\n method: 'GET',\n headers: this.getHeaders(true),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Escrow API error: ${response.status} - ${errorText}`);\n }\n\n return await response.json();\n } catch (error) {\n clearTimeout(timeoutId);\n throw error;\n }\n }\n\n /**\n * Query on-chain escrow state from the facilitator\n *\n * Calls POST /escrow/state to read current escrow state without settlement.\n *\n * @param options - Escrow state query parameters\n * @returns On-chain escrow state (status, balance, timestamps)\n *\n * @example\n * ```ts\n * const state = await escrow.getEscrowState({\n * network: 'base-mainnet',\n * payer: '0xPayer...',\n * recipient: '0xRecipient...',\n * nonce: '0x1234...',\n * });\n * console.log(`Status: ${state.status}`);\n * ```\n */\n async getEscrowState(options: {\n network: string;\n payer: string;\n recipient: string;\n nonce: string;\n }): Promise<Record<string, unknown>> {\n const url = `${this.baseUrl}/escrow/state`;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: this.getHeaders(),\n body: JSON.stringify(options),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Escrow API error: ${response.status} - ${errorText}`);\n }\n\n return await response.json();\n } catch (error) {\n clearTimeout(timeoutId);\n throw error;\n }\n }\n\n /**\n * Check Escrow API health\n *\n * @returns True if healthy\n */\n async healthCheck(): Promise<boolean> {\n try {\n const response = await fetch(`${this.baseUrl}/health`, {\n method: 'GET',\n });\n return response.ok;\n } catch {\n return false;\n }\n }\n}\n\n// ============================================================================\n// ESCROW HELPER FUNCTIONS\n// ============================================================================\n\n/**\n * Check if an escrow can be released\n *\n * @param escrow - Escrow payment to check\n * @returns True if the escrow can be released\n */\nexport function canReleaseEscrow(escrow: EscrowPayment): boolean {\n if (escrow.status !== 'held') {\n return false;\n }\n\n // Check expiration\n if (new Date(escrow.expiresAt) < new Date()) {\n return false;\n }\n\n // Check minimum hold time if specified\n if (escrow.releaseConditions?.minHoldTime) {\n const createdAt = new Date(escrow.createdAt);\n const minReleaseTime = new Date(\n createdAt.getTime() + escrow.releaseConditions.minHoldTime * 1000\n );\n if (new Date() < minReleaseTime) {\n return false;\n }\n }\n\n return true;\n}\n\n/**\n * Check if an escrow can be refunded\n *\n * @param escrow - Escrow payment to check\n * @returns True if the escrow can be refunded\n */\nexport function canRefundEscrow(escrow: EscrowPayment): boolean {\n // Can only refund held or pending escrows\n return escrow.status === 'held' || escrow.status === 'pending';\n}\n\n/**\n * Check if an escrow is expired\n *\n * @param escrow - Escrow payment to check\n * @returns True if the escrow is expired\n */\nexport function isEscrowExpired(escrow: EscrowPayment): boolean {\n return new Date(escrow.expiresAt) < new Date();\n}\n\n/**\n * Calculate time remaining until escrow expires\n *\n * @param escrow - Escrow payment to check\n * @returns Milliseconds until expiration (negative if expired)\n */\nexport function escrowTimeRemaining(escrow: EscrowPayment): number {\n return new Date(escrow.expiresAt).getTime() - Date.now();\n}\n\n// ============================================================================\n// ERC-8004 TRUSTLESS AGENTS\n// ============================================================================\n\n/**\n * ERC-8004 extension identifier\n */\nexport const ERC8004_EXTENSION_ID = '8004-reputation';\n\n/**\n * Agent ID type: EVM uses sequential uint256 (number), Solana uses base58 pubkey (string)\n */\nexport type AgentId = number | string;\n\n/**\n * ERC-8004 contract addresses per network\n */\n// Mainnet addresses (CREATE2 deterministic - same on all mainnets)\nconst MAINNET_IDENTITY = '0x8004A169FB4a3325136EB29fA0ceB6D2e539a432';\nconst MAINNET_REPUTATION = '0x8004BAa17C55a88189AE136b182e5fdA19dE9b63';\n// Deployed after the identity/reputation pair, which is why it was missing here.\n// Verified live on all ten EVM mainnets; SKALE Base has no code at this address\n// and is the one mainnet that legitimately has no validation registry.\nconst MAINNET_VALIDATION = '0x8004Cc8439f36fd5F9F049D9fF86523Df6dAAB58';\n\n// Testnet addresses (same on all testnets)\nconst TESTNET_IDENTITY = '0x8004A818BFB912233c491871b3d84c89A494BD9e';\nconst TESTNET_REPUTATION = '0x8004B663056A597Dffe9eCcC1965A193B7388713';\nconst TESTNET_VALIDATION = '0x8004Cb1BF31DAf7788923b405b754f57acEB4272';\n\n// Solana program IDs (QuantuLabs 8004-solana)\nconst SOLANA_AGENT_REGISTRY = '8oo4dC4JvBLwy5tGgiH3WwK4B9PWxL9Z4XjA2jzkQMbQ';\nconst SOLANA_ATOM_ENGINE = 'AToMw53aiPQ8j7iHVb4fGt6nzUNxUhcPc3tbPBZuzVVb';\n\n/**\n * ERC-8004 contract addresses per network (21 networks: 19 EVM + 2 Solana)\n */\nexport const ERC8004_CONTRACTS: Record<string, {\n identityRegistry?: string;\n reputationRegistry?: string;\n validationRegistry?: string;\n agentRegistryProgram?: string;\n atomEngineProgram?: string;\n}> = {\n // Mainnets (11)\n ethereum: {\n identityRegistry: MAINNET_IDENTITY,\n reputationRegistry: MAINNET_REPUTATION,\n validationRegistry: MAINNET_VALIDATION,\n },\n base: {\n identityRegistry: MAINNET_IDENTITY,\n reputationRegistry: MAINNET_REPUTATION,\n validationRegistry: MAINNET_VALIDATION,\n },\n polygon: {\n identityRegistry: MAINNET_IDENTITY,\n reputationRegistry: MAINNET_REPUTATION,\n validationRegistry: MAINNET_VALIDATION,\n },\n arbitrum: {\n identityRegistry: MAINNET_IDENTITY,\n reputationRegistry: MAINNET_REPUTATION,\n validationRegistry: MAINNET_VALIDATION,\n },\n optimism: {\n identityRegistry: MAINNET_IDENTITY,\n reputationRegistry: MAINNET_REPUTATION,\n validationRegistry: MAINNET_VALIDATION,\n },\n celo: {\n identityRegistry: MAINNET_IDENTITY,\n reputationRegistry: MAINNET_REPUTATION,\n validationRegistry: MAINNET_VALIDATION,\n },\n bsc: {\n identityRegistry: MAINNET_IDENTITY,\n reputationRegistry: MAINNET_REPUTATION,\n validationRegistry: MAINNET_VALIDATION,\n },\n monad: {\n identityRegistry: MAINNET_IDENTITY,\n reputationRegistry: MAINNET_REPUTATION,\n validationRegistry: MAINNET_VALIDATION,\n },\n avalanche: {\n identityRegistry: MAINNET_IDENTITY,\n reputationRegistry: MAINNET_REPUTATION,\n validationRegistry: MAINNET_VALIDATION,\n },\n scroll: {\n identityRegistry: MAINNET_IDENTITY,\n reputationRegistry: MAINNET_REPUTATION,\n validationRegistry: MAINNET_VALIDATION,\n },\n // SKALE Base is the one mainnet without a validation registry (no code at\n // the canonical address), so leaving it out is correct, not an omission.\n 'skale-base': {\n identityRegistry: MAINNET_IDENTITY,\n reputationRegistry: MAINNET_REPUTATION,\n },\n // Deprecated alias for 'base' -- kept so existing lookups keep resolving.\n 'base-mainnet': {\n identityRegistry: MAINNET_IDENTITY,\n reputationRegistry: MAINNET_REPUTATION,\n validationRegistry: MAINNET_VALIDATION,\n },\n // Testnets (8)\n 'ethereum-sepolia': {\n identityRegistry: TESTNET_IDENTITY,\n reputationRegistry: TESTNET_REPUTATION,\n validationRegistry: TESTNET_VALIDATION,\n },\n 'base-sepolia': {\n identityRegistry: TESTNET_IDENTITY,\n reputationRegistry: TESTNET_REPUTATION,\n validationRegistry: TESTNET_VALIDATION,\n },\n 'polygon-amoy': {\n identityRegistry: TESTNET_IDENTITY,\n reputationRegistry: TESTNET_REPUTATION,\n validationRegistry: TESTNET_VALIDATION,\n },\n 'arbitrum-sepolia': {\n identityRegistry: TESTNET_IDENTITY,\n reputationRegistry: TESTNET_REPUTATION,\n validationRegistry: TESTNET_VALIDATION,\n },\n 'optimism-sepolia': {\n identityRegistry: TESTNET_IDENTITY,\n reputationRegistry: TESTNET_REPUTATION,\n validationRegistry: TESTNET_VALIDATION,\n },\n 'celo-sepolia': {\n identityRegistry: TESTNET_IDENTITY,\n reputationRegistry: TESTNET_REPUTATION,\n validationRegistry: TESTNET_VALIDATION,\n },\n 'avalanche-fuji': {\n identityRegistry: TESTNET_IDENTITY,\n reputationRegistry: TESTNET_REPUTATION,\n validationRegistry: TESTNET_VALIDATION,\n },\n 'skale-base-sepolia': {\n identityRegistry: TESTNET_IDENTITY,\n reputationRegistry: TESTNET_REPUTATION,\n validationRegistry: TESTNET_VALIDATION,\n },\n // Solana (2) - uses QuantuLabs 8004-solana Anchor program + ATOM Engine\n solana: {\n agentRegistryProgram: SOLANA_AGENT_REGISTRY,\n atomEngineProgram: SOLANA_ATOM_ENGINE,\n },\n 'solana-devnet': {\n agentRegistryProgram: SOLANA_AGENT_REGISTRY,\n atomEngineProgram: SOLANA_ATOM_ENGINE,\n },\n};\n\n/**\n * Return the network name the facilitator actually accepts.\n *\n * `base-mainnet` reads like the canonical spelling and is not: the facilitator\n * answers `400 {\"error\": \"Invalid network: base-mainnet\"}`. Every name is passed\n * through here before it reaches a URL or a request body, so callers holding the\n * old spelling keep working instead of being rejected at the edge.\n */\nexport function wireNetwork(network: string): string {\n return network === 'base-mainnet' ? 'base' : network;\n}\n\n/**\n * Network type for ERC-8004 operations (21 networks: 19 EVM + 2 Solana)\n *\n * These are the names the FACILITATOR accepts, verified against\n * GET /feedback -> supportedNetworks. 'base-mainnet' is kept only as a\n * deprecated alias: the facilitator rejects it outright (400 \"Invalid network\"),\n * so anything passed through this module is normalised to 'base' before it\n * reaches the wire. Use 'base'.\n */\nexport type Erc8004Network =\n // EVM Mainnets\n | 'ethereum' | 'base' | 'polygon' | 'arbitrum' | 'optimism' | 'celo' | 'bsc' | 'monad' | 'avalanche' | 'scroll' | 'skale-base'\n // Deprecated alias, rewritten to 'base' before it reaches the wire\n | 'base-mainnet'\n // EVM Testnets\n | 'ethereum-sepolia' | 'base-sepolia' | 'polygon-amoy' | 'arbitrum-sepolia' | 'optimism-sepolia' | 'celo-sepolia' | 'avalanche-fuji' | 'skale-base-sepolia'\n // Solana (uses QuantuLabs 8004-solana Anchor program + ATOM Engine)\n | 'solana' | 'solana-devnet';\n\n/**\n * Networks where the facilitator serves the RELAYED feedback rail, i.e. where\n * Execution Market has deployed a `FeedbackDelegate` and the facilitator\n * verified it on-chain (code present, and its `REPUTATION_REGISTRY()` reads\n * back that network's registry).\n *\n * Anywhere else `POST /feedback/evm/prepare` answers 400 — and it should. An\n * invented delegate address would send a type-4 transaction to an account with\n * no code behind it, and in the EVM a `.call()` to an address with no code\n * RETURNS SUCCESS. The failure would look exactly like a rating that rated\n * nobody.\n *\n * `avalanche` is absent and is not waiting to join: the C-Chain rejects the\n * transaction type itself (`-32000 transaction type not supported`), so there\n * is nothing to deploy against. Anchor the rating on a chain that supports\n * EIP-7702; the payment stays where it was made.\n */\nexport const RELAYED_FEEDBACK_NETWORKS: readonly Erc8004Network[] = [\n 'base',\n 'ethereum',\n 'polygon',\n 'arbitrum',\n 'optimism',\n 'celo',\n 'bsc',\n 'monad',\n 'base-sepolia',\n] as const;\n\n/**\n * Whether `network` serves the rater-authored feedback rail.\n *\n * Lets a caller route without paying a round trip for a 400. The facilitator\n * re-checks the delegate on-chain on every request regardless — this list is a\n * routing hint, never the authority.\n */\nexport function supportsRelayedFeedback(network: string): boolean {\n return (RELAYED_FEEDBACK_NETWORKS as readonly string[]).includes(wireNetwork(network));\n}\n\n/**\n * Networks where the facilitator serves the rater-authored feedback rail on\n * **Solana**, through `POST /feedback/solana/prepare` + `/submit`.\n *\n * A separate list from {@link RELAYED_FEEDBACK_NETWORKS} on purpose, and the\n * two must never be merged. That one names the chains where Execution Market\n * deployed a `FeedbackDelegate` and the facilitator verified it on-chain; it\n * routes to `/feedback/evm/*`. Adding `solana` to it would send a Solana\n * rating to the EVM route, which answers 400 — and would claim a delegate that\n * does not exist and is not missing.\n *\n * Solana needs no delegate at all: account 0 of the program's `give_feedback`\n * instruction is already declared `[signer, writable] client`, so the rater\n * signs as the author natively and the facilitator only co-signs as fee payer.\n * Nothing is delegated because nothing has to be.\n *\n * Both networks are served by the deployed facilitator (v2.16.0, measured\n * against `GET /supported`).\n */\nexport const SOLANA_FEEDBACK_NETWORKS: readonly Erc8004Network[] = [\n 'solana',\n 'solana-devnet',\n] as const;\n\n/**\n * Whether `network` serves the rater-authored feedback rail on Solana.\n *\n * A routing hint, never the authority: the facilitator re-resolves the\n * programs and the RPC provider per request and answers\n * `400 \"<network> is not a Solana network served by this facilitator\"` for\n * anything else.\n */\nexport function supportsSolanaFeedback(network: string): boolean {\n return (SOLANA_FEEDBACK_NETWORKS as readonly string[]).includes(wireNetwork(network));\n}\n\n/**\n * An EIP-7702 authorization, as a wallet produces it.\n *\n * Needed only the first time a rater rates: it points their EOA at the\n * `FeedbackDelegate`. Once delegated, `prepare` answers `delegated: true` and\n * the submission carries no authorization at all.\n */\nexport interface RelayAuthorizationParams {\n /**\n * Chain the authorization is for.\n *\n * `0` is EIP-7702's wildcard and is valid on EVERY chain — a far broader\n * grant than pinning this one. Send the chain id `prepare` returned.\n */\n chainId: number;\n /**\n * The delegate the account is pointed at. Must be the address `prepare`\n * offered; the facilitator refuses anything else before it pays for a\n * transaction.\n */\n address: string;\n /** The rater account's nonce at the moment the authorization executes */\n nonce: number;\n yParity: number;\n r: string;\n s: string;\n}\n\n/**\n * Request body for `POST /feedback/evm/prepare`.\n *\n * `rater` is the address that will appear on-chain as the author, which is the\n * whole point of this rail.\n */\nexport interface PrepareRelayFeedbackRequest {\n x402Version: 1 | 2;\n network: Erc8004Network;\n feedback: FeedbackParams & { rater: string };\n}\n\n/**\n * Response from `POST /feedback/evm/prepare`.\n *\n * Everything the rater has to sign so the CHAIN records them as the author\n * while the facilitator pays the gas.\n */\nexport interface PrepareRelayFeedbackResponse {\n success: boolean;\n /** The `FeedbackDelegate` the rater's EOA must be delegated to */\n delegate?: string;\n /** Registry calldata the rater is authorising, hex-encoded */\n data?: string;\n /**\n * The value the rater's signature must recover against.\n *\n * **The EIP-191 envelope is already applied here.** A holder of a raw key\n * signs this directly as a prehash (viem's `sign({ hash })`, ethers'\n * `signingKey.sign`). A WALLET must not be handed this value: `personal_sign`\n * applies the envelope itself, so it gets wrapped twice and recovers an\n * address that is not the rater. Wallets sign {@link signingPayload}.\n */\n digest?: string;\n /**\n * The same hash with the envelope still OFF — what a wallet signs.\n *\n * `keccak256('\\x19Ethereum Signed Message:\\n32' || signingPayload)` is\n * exactly {@link digest}, so a client can check the two against each other\n * rather than rebuilding the preimage from `data`.\n *\n * Requires facilitator v1.95.0+. Older facilitators omit it; a client that\n * needs it should fail loudly rather than fall back to signing `digest`\n * through a wallet, which produces a well-formed signature that authorises\n * nobody.\n */\n signingPayload?: string;\n /**\n * The full `eth_signTypedData_v4` payload. **v4 delegates only.**\n *\n * Present exactly when the delegate deployed on that chain is v4, which the\n * facilitator reads from the chain per request rather than assuming from a\n * release. **When it is present, sign IT** — the wallet renders the agent, the\n * score, the tags and the deadline as named fields, so the rater sees what\n * they authorise instead of a hex blob.\n *\n * v4 carries no {@link signingPayload} and needs none: `signTypedData` has no\n * envelope to apply twice, which is the entire class of bug that kept the v3\n * rail at zero signatures for days.\n *\n * Requires facilitator v1.96.0+.\n */\n typedData?: Record<string, unknown>;\n /**\n * Unix seconds after which the authorisation is void. Short on purpose:\n * relaying is permissionless, so a signed authorisation is live in the wild\n * until it expires.\n */\n deadline?: number;\n /** Single-use value binding this authorisation. Echo it back on submit */\n nonce?: string;\n /**\n * Whether the account is already delegated. When `false` the submission MUST\n * carry an `authorization`.\n */\n delegated: boolean;\n /** The account nonce to put in the EIP-7702 authorization, when needed */\n accountNonce?: number;\n chainId: number;\n error?: string;\n network: Erc8004Network;\n}\n\n/**\n * Request body for `POST /feedback/evm/submit`.\n *\n * The feedback parameters are not redundant with `prepare`: the facilitator\n * rebuilds the registry calldata from them and requires the rater's signature\n * to cover exactly that. It does not relay calldata it was handed.\n */\nexport interface SubmitRelayFeedbackRequest {\n x402Version: 1 | 2;\n network: Erc8004Network;\n feedback: FeedbackParams & { rater: string };\n /** The deadline `prepare` returned */\n deadline: number;\n /** The single-use nonce `prepare` returned */\n nonce: string;\n /**\n * The rater's signature. It must recover to `rater` over `digest` — so\n * either a raw-key prehash signature over `digest`, or a wallet\n * `personal_sign` over `signingPayload`. Not `personal_sign` over `digest`.\n */\n signature: string;\n /** Required only when `prepare` answered `delegated: false` */\n authorization?: RelayAuthorizationParams;\n}\n\n/**\n * Request body for `POST /feedback/solana/prepare`.\n *\n * `rater` is REQUIRED here and is a base58 Solana pubkey — an `0x` address is\n * refused (`400 \"rater must be a base58 Solana pubkey on this network\"`).\n * `agentId` is the agent's asset pubkey, also base58.\n */\nexport interface PrepareSolanaFeedbackRequest {\n x402Version: 1 | 2;\n /** One of {@link SOLANA_FEEDBACK_NETWORKS} */\n network: Erc8004Network;\n /**\n * The rating, plus who signs it.\n *\n * **Set `score`.** It is optional on the wire and the ATOM Engine ignores an\n * unscored feedback entirely: the record lands on the agent, the transaction\n * succeeds, and the program reports `had_impact=false` — reputation stays at\n * zero however much unscored feedback accumulates, and it is not retroactive.\n * Omit it only when a deliberately non-scoring record is what you want.\n */\n feedback: FeedbackParams & { rater: string };\n}\n\n/**\n * Response from `POST /feedback/solana/prepare`.\n *\n * Carries an UNSIGNED transaction whose `client` account is the rater. Sign it\n * with the rater's key and hand it back to {@link Erc8004Client.submitSolanaFeedback}.\n */\nexport interface PrepareSolanaFeedbackResponse {\n success: boolean;\n /**\n * base64 of the bincode-serialised unsigned **legacy** transaction — read it\n * with `Transaction.from()`, not `VersionedTransaction`.\n *\n * It expects TWO signatures: the rater's, which you add, and the fee\n * payer's, which `/feedback/solana/submit` adds. Do not re-encode the\n * message or rebuild the instruction — the facilitator rebuilds it from the\n * declared parameters and refuses to co-sign anything that is not\n * byte-for-byte what it offered.\n */\n transaction?: string;\n /** Who must sign as `client`, i.e. who the chain will record as the author */\n rater?: string;\n /** Who pays the fee. Still the facilitator — that is the point */\n feePayer?: string;\n /** The blockhash baked into the message. Submit before it expires */\n blockhash?: string;\n /**\n * Last block height at which this transaction is still valid.\n *\n * Past it the network drops the transaction; nothing is written and nothing\n * is charged. Prepare again rather than resubmitting.\n */\n lastValidBlockHeight?: number;\n error?: string;\n network: Erc8004Network;\n}\n\n/**\n * Request body for `POST /feedback/solana/submit`.\n *\n * The feedback parameters are not redundant with `prepare`: the facilitator\n * re-derives the message from them plus the blockhash carried by\n * {@link transaction}, and refuses to co-sign anything that does not match\n * byte for byte. Signing arbitrary blobs would turn the fee-payer keypair into\n * a public signing oracle — one `system_program::transfer` would empty the\n * wallet with the facilitator's signature on it.\n */\nexport interface SubmitSolanaFeedbackRequest {\n x402Version: 1 | 2;\n network: Erc8004Network;\n /** Exactly what was sent to `prepare`, `rater` included */\n feedback: FeedbackParams & { rater: string };\n /** base64 of the rater-signed transaction */\n transaction: string;\n}\n\n/**\n * Request body for `POST /feedback/response/evm/prepare`.\n *\n * `responder` is the address the chain will record as the author.\n */\nexport interface PrepareRelayResponseRequest {\n x402Version: 1 | 2;\n network: Erc8004Network;\n responder: string;\n agentId: number | string;\n /** WHOSE feedback is being answered — inside the signed struct. */\n clientAddress: string;\n /** Which feedback (1-indexed) — also inside the struct. */\n feedbackIndex: number;\n responseUri: string;\n responseHash?: string;\n}\n\n/** Request body for `POST /feedback/response/evm/submit`. */\nexport interface SubmitRelayResponseRequest {\n x402Version: 1 | 2;\n network: Erc8004Network;\n responder: string;\n agentId: number | string;\n clientAddress: string;\n feedbackIndex: number;\n responseUri: string;\n responseHash?: string;\n deadline: number;\n nonce: string;\n /** The responder's signature over the typed data. */\n signature: string;\n authorization?: RelayAuthorizationParams;\n}\n\n/**\n * Proof of payment returned when settling with ERC-8004 extension\n */\nexport interface ProofOfPayment {\n /** Transaction hash of the settled payment */\n transactionHash: string;\n /** Block number where the transaction was included */\n blockNumber: number;\n /** Network where the payment was settled */\n network: string;\n /** The payer (consumer/client) address */\n payer: string;\n /** The payee (agent/resource owner) address */\n payee: string;\n /** Amount paid in token base units */\n amount: string;\n /** Token contract address */\n token: string;\n /** Unix timestamp of the block */\n timestamp: number;\n /** Keccak256 hash of the payment data for verification */\n paymentHash: string;\n}\n\n/**\n * Extended settle response with ERC-8004 proof of payment\n */\nexport interface SettleResponseWithProof extends SettleResponse {\n /** Proof of payment for ERC-8004 reputation submission */\n proofOfPayment?: ProofOfPayment;\n}\n\n/**\n * Agent identity from the Identity Registry\n */\nexport interface AgentIdentity {\n /** The agent's ID (EVM: sequential uint256, Solana: base58 pubkey string) */\n agentId: AgentId;\n /** Owner address of the agent NFT */\n owner: string;\n /** URI pointing to agent registration file */\n agentUri: string;\n /** Payment wallet address (if set) */\n agentWallet?: string;\n /** Network where the agent is registered */\n network: Erc8004Network;\n}\n\n/**\n * Agent registration file structure (resolved from agentURI)\n */\nexport interface AgentRegistrationFile {\n /** Type identifier */\n type: string;\n /** Agent name */\n name: string;\n /** Agent description */\n description: string;\n /** Image URL */\n image?: string;\n /** List of services the agent provides */\n services: AgentService[];\n /** Whether x402 payments are supported */\n x402Support: boolean;\n /** Whether the agent is active */\n active: boolean;\n /** List of registrations across chains */\n registrations: AgentRegistration[];\n /** Supported trust models */\n supportedTrust: string[];\n}\n\n/**\n * Agent service entry\n */\nexport interface AgentService {\n name: string;\n endpoint: string;\n version?: string;\n}\n\n/**\n * Agent registration reference\n */\nexport interface AgentRegistration {\n agentId: AgentId;\n agentRegistry: string; // Format: {namespace}:{chainId}:{address}\n}\n\n/**\n * Reputation summary for an agent\n */\nexport interface ReputationSummary {\n /** Agent ID (EVM: number, Solana: string) */\n agentId: AgentId;\n /** Number of feedback entries */\n count: number;\n /** Aggregated value */\n summaryValue: number;\n /** Decimal places for summaryValue */\n summaryValueDecimals: number;\n /** Network */\n network: Erc8004Network;\n}\n\n/**\n * Individual feedback entry\n */\nexport interface FeedbackEntry {\n /** Client who submitted the feedback */\n client: string;\n /** Feedback index (1-indexed) */\n feedbackIndex: number;\n /** Feedback value */\n value: number;\n /** Value decimals */\n valueDecimals: number;\n /** Primary tag */\n tag1: string;\n /** Secondary tag */\n tag2: string;\n /** Whether this feedback was revoked */\n isRevoked: boolean;\n}\n\n/**\n * Parameters for submitting reputation feedback\n */\nexport interface FeedbackParams {\n /** The agent's ID (EVM: tokenId number, Solana: base58 pubkey string) */\n agentId: AgentId;\n /** Feedback value (e.g., 87 for 87/100) */\n value: number;\n /** Decimal places for value interpretation (0-18) */\n valueDecimals?: number;\n /** Primary categorization tag (e.g., \"starred\", \"uptime\") */\n tag1?: string;\n /** Secondary categorization tag */\n tag2?: string;\n /** Service endpoint that was used */\n endpoint?: string;\n /** URI to off-chain feedback file (IPFS, HTTPS) */\n feedbackUri?: string;\n /** Keccak256 hash of feedback content (for integrity) */\n feedbackHash?: string;\n /**\n * Quality score 0-100.\n *\n * Solana only, and effectively required there: the ATOM Engine ignores an\n * unscored feedback. It is written to the agent but contributes nothing to\n * reputation, and the program reports `had_impact=false`. This is not\n * retroactive — reputation stays at zero however much unscored feedback\n * accumulates.\n */\n score?: number;\n /** Proof of payment (required for authorized feedback) */\n proof?: ProofOfPayment;\n}\n\n/**\n * Feedback request body for POST /feedback\n */\nexport interface FeedbackRequest {\n /** x402 protocol version */\n x402Version: 1 | 2;\n /** Network where feedback will be submitted */\n network: Erc8004Network;\n /** Feedback parameters */\n feedback: FeedbackParams;\n}\n\n/**\n * Feedback response from POST /feedback\n */\nexport interface FeedbackResponse extends FacilitatorFailureFields {\n /** Whether the feedback was successfully submitted */\n success: boolean;\n /** Transaction hash of the feedback submission */\n transaction?: string;\n /** Feedback index assigned (1-indexed) */\n feedbackIndex?: number;\n /** Error message (if failed) */\n error?: string;\n /** Network where feedback was submitted */\n network: Erc8004Network;\n}\n\n/**\n * Reputation query response\n */\n/**\n * Error from an ERC-8004 lookup, carrying the HTTP status as a field.\n *\n * `notFound` and `retryable` are mutually exclusive and must stay that way in\n * calling code: the facilitator answers 404 for \"this address owns no agent\"\n * and 503 for \"I could not find out\", usually an RPC failure behind it.\n * Treating a 503 as absence is how a transient failure becomes a permanent\n * wrong answer — on a registration path it mints a second agent for an owner\n * who already has one, burning gas and leaving an orphan.\n */\nexport class Erc8004LookupError extends Error {\n /** HTTP status returned by the facilitator */\n readonly status: number;\n /** Raw response body, for debugging */\n readonly body: string;\n /**\n * `Retry-After`, already clamped, when the facilitator sent one.\n *\n * Optional so every existing three-argument construction keeps compiling; it\n * falls back to the default wait rather than to zero, because a caller that\n * retries instantly on a 503 is the load that caused it.\n */\n private readonly retryAfterHint: number | undefined;\n\n constructor(message: string, status: number, body: string, retryAfterSeconds?: number) {\n super(message);\n this.name = 'Erc8004LookupError';\n this.status = status;\n this.body = body;\n this.retryAfterHint = retryAfterSeconds;\n }\n\n /** The address genuinely owns no agent on this network. */\n get notFound(): boolean {\n return this.status === 404;\n }\n\n /**\n * The lookup reached no verdict. Retry; never read as \"owns nothing\".\n *\n * `502` and `504` join `503` and `429` here: a gateway that answered on the\n * facilitator's behalf is exactly as silent about the agent's existence, and\n * reading either as absence has the same consequence -- a duplicate mint.\n *\n * **Except when the body says otherwise.** `POST /register` goes through the\n * same EVM `send_transaction_from` as a settle, so it can answer\n * `settlement_unconfirmed`: the mint was broadcast and may be mined. That is\n * a `502` where retrying is precisely the thing that mints the duplicate this\n * class exists to prevent, so an explicit `retryable: false` wins over the\n * status. See {@link SETTLEMENT_UNCONFIRMED}.\n */\n get retryable(): boolean {\n const parsed = parseFacilitatorErrorBody(this.body);\n if (parsed.retryable === false || parsed.errorCode === SETTLEMENT_UNCONFIRMED) {\n return false;\n }\n return (\n this.status === 429 ||\n this.status === 502 ||\n this.status === 503 ||\n this.status === 504\n );\n }\n\n /**\n * The facilitator's own `reason`, when the body carried one.\n *\n * On a WRITE route this is the writer-lease reason and it decides whether the\n * request may be re-sent; see {@link isReplayableLeaseReason}.\n */\n get reason(): string | undefined {\n return parseFacilitatorErrorBody(this.body).reason;\n }\n\n /** The facilitator's machine-readable `error` code, when the body carried one. */\n get errorCode(): string | undefined {\n return parseFacilitatorErrorBody(this.body).errorCode;\n }\n\n /**\n * A transaction that WAS broadcast and could not be confirmed.\n *\n * Present on `settlement_unconfirmed`. This is what to do INSTEAD of\n * retrying: look it up on chain. An error that carries \"do not retry\" and no\n * hash leaves the caller with nothing to act on.\n */\n get transaction(): string | undefined {\n return parseFacilitatorErrorBody(this.body).transaction;\n }\n\n /** The payment id for {@link transaction}, identical to a successful settle's. */\n get paymentId(): string | undefined {\n return parseFacilitatorErrorBody(this.body).paymentId;\n }\n\n /**\n * The facilitator NAMED a reason proving it executed nothing.\n *\n * False for `forward_failed` and for every unattributed 5xx: \"something\n * answered\" is not evidence that nothing ran. On `/register`, replaying when\n * this is false is the sequence that minted five duplicate agents.\n */\n get safeToReplay(): boolean {\n // Gated on `retryable` so the two can never disagree: an error this SDK\n // will not retry at all must never be described as safe to replay.\n return (\n this.retryable &&\n (this.status === 429 || (this.status === 503 && isReplayableLeaseReason(this.reason)))\n );\n }\n\n /** Seconds to wait before retrying, clamped. Absent when not retryable. */\n get retryAfterSeconds(): number | undefined {\n if (!this.retryable) return undefined;\n return this.retryAfterHint ?? DEFAULT_RETRY_AFTER_SECONDS;\n }\n}\n\n/**\n * ATOM Engine reputation analytics (Solana only).\n *\n * Present only when the agent's `atom_stats` account has been initialized. The\n * facilitator does that during `registerAgent`; agents registered elsewhere may\n * never have it, in which case their feedback is never scored.\n *\n * The engine measures quality through EMA scores, so there are no\n * positive/negative tallies.\n */\nexport interface AtomStats {\n /** Trust tier 0-4 */\n trustTier: number;\n /** Human-readable trust tier */\n trustTierName: string;\n /** Cached quality score */\n qualityScore: number;\n /** Cached loyalty score */\n loyaltyScore: number;\n /** Statistical confidence */\n confidence: number;\n /** Risk assessment (lower is better) */\n riskScore: number;\n /** Client diversity from HyperLogLog */\n diversityRatio: number;\n /** Lowest score ever recorded */\n minScore: number;\n /** Highest score ever recorded */\n maxScore: number;\n /** Most recent score recorded */\n lastScore: number;\n /** Total feedback counted by the engine */\n feedbackCount: number;\n /** Slot of the most recent feedback */\n lastFeedbackSlot: number;\n}\n\nexport interface ReputationResponse {\n agentId: AgentId;\n summary: ReputationSummary;\n feedback?: FeedbackEntry[];\n /** ATOM Engine analytics; absent when the agent has no initialized stats */\n atomStats?: AtomStats | null;\n network: Erc8004Network;\n}\n\n/**\n * Key-value metadata entry for agent registration\n */\nexport interface MetadataEntryParam {\n /** Metadata key */\n key: string;\n /** Metadata value (hex-encoded bytes or UTF-8 string) */\n value: string;\n}\n\n/**\n * Request body for POST /register\n */\nexport interface RegisterAgentRequest {\n /** x402 protocol version */\n x402Version: 1 | 2;\n /** Network where agent will be registered */\n network: Erc8004Network;\n /** URI pointing to agent registration file (IPFS, HTTPS) */\n agentUri: string;\n /** Optional metadata key-value pairs */\n metadata?: MetadataEntryParam[];\n /** Optional recipient address - NFT is transferred to this address after minting */\n recipient?: string;\n}\n\n/**\n * Response from POST /register\n */\nexport interface RegisterAgentResponse extends FacilitatorFailureFields {\n /** Whether registration succeeded */\n success: boolean;\n /** The newly assigned agent ID (EVM: tokenId number, Solana: base58 pubkey string) */\n agentId?: AgentId;\n /** Registration transaction hash */\n transaction?: string;\n /** Transfer transaction hash (if recipient was specified) */\n transferTransaction?: string;\n /** Owner address of the agent NFT */\n owner?: string;\n /** Error message if failed */\n error?: string;\n /** Network where agent was registered */\n network: string;\n}\n\n/**\n * Response from GET /identity/{network}/owner/{address}\n */\nexport interface IdentityByOwnerResponse {\n /** First (lowest) token ID owned by this address */\n agentId: AgentId;\n /** The queried address (checksummed) */\n owner: string;\n /** Agent's registration URI (may be empty) */\n agentUri: string;\n /** Network name */\n network: string;\n /** Total number of agent NFTs owned (as string) */\n balance: string;\n}\n\n/**\n * Response from GET /identity/{network}/{agent_id}/metadata/{key}\n */\n/**\n * Lifecycle of an async registration. `mint_confirmed` and `done` carry an\n * `agentId`; `failed` carries an `error`.\n */\nexport type RegisterJobStatus = 'pending' | 'mint_confirmed' | 'done' | 'failed';\n\n/**\n * Status of an asynchronous registration.\n *\n * Returned by `POST /register` with `Prefer: respond-async` (HTTP 202) and by\n * `GET /register/status/{jobId}`.\n *\n * Terminal jobs are retained for one hour and then age out, after which the\n * status endpoint 404s. Read the agent id before then, or it is only\n * recoverable from the chain.\n */\nexport interface RegisterJobResponse {\n jobId: string;\n status: RegisterJobStatus;\n network?: string;\n agentId?: AgentId;\n transaction?: string;\n transferTransaction?: string;\n owner?: string;\n error?: string;\n}\n\n/** Whether polling can stop: the job either finished or failed. */\nexport function isRegisterJobTerminal(job: RegisterJobResponse): boolean {\n return job.status === 'done' || job.status === 'failed';\n}\n\n/**\n * Thrown when a registration is still running after the wait elapsed.\n *\n * This is emphatically **not** a failure. The mint may still land. `jobId` is a\n * field rather than only part of the message, because the correct recovery is to\n * keep polling `getRegisterStatus(jobId)` — and a caller who cannot reach the id\n * without parsing a string will re-register instead, minting a duplicate agent.\n * That is the exact sequence that once produced five duplicate mints.\n *\n * Never map this to \"registration failed\".\n */\nexport class RegistrationPendingError extends Error {\n readonly jobId: string;\n readonly lastStatus: RegisterJobStatus;\n readonly timeoutMs: number;\n readonly retryable = true;\n\n constructor(jobId: string, lastStatus: RegisterJobStatus, timeoutMs: number) {\n super(\n `Registration job ${jobId} still '${lastStatus}' after ${Math.round(\n timeoutMs / 1000,\n )}s. It may still complete: poll getRegisterStatus('${jobId}') rather than registering again.`,\n );\n this.name = 'RegistrationPendingError';\n this.jobId = jobId;\n this.lastStatus = lastStatus;\n this.timeoutMs = timeoutMs;\n }\n}\n\n/**\n * Present a finished async job in the shape the synchronous call returns.\n *\n * Keeping the return type identical is the whole point of `asyncTransport`:\n * switching transports must not force callers to rewrite anything downstream.\n */\nfunction jobToRegisterResponse(\n job: RegisterJobResponse,\n network: Erc8004Network,\n): RegisterAgentResponse {\n return {\n success: job.status !== 'failed',\n agentId: job.agentId,\n transaction: job.transaction,\n transferTransaction: job.transferTransaction,\n owner: job.owner,\n error: job.error,\n network: (job.network as Erc8004Network) ?? network,\n };\n}\n\nexport interface IdentityMetadataResponse {\n /** Agent ID (EVM: number, Solana: string) */\n agentId: AgentId;\n /** Metadata key */\n key: string;\n /**\n * Raw hex-encoded value. The facilitator sends this as `value`; this field\n * used to be declared as `valueHex`, which no response ever carried, so it\n * was always undefined at runtime.\n */\n value: string;\n /** UTF-8 decoded value (if decodable) */\n valueUtf8?: string;\n /** Whether the entry can still be changed */\n immutable?: boolean;\n /** Network */\n network: string;\n}\n\n/**\n * Response from GET /identity/{network}/total-supply\n *\n * On Solana the counts come from the Metaplex Core collection, not the registry,\n * which keeps no counter of its own.\n */\nexport interface IdentityTotalSupplyResponse {\n /** Registered agents, net of burns */\n totalSupply: number;\n /** All-time mint count (Solana) */\n numMinted?: number;\n /** Metaplex Core collection backing the count (Solana) */\n collection?: string;\n /** Network */\n network: string;\n}\n\n/**\n * Options for the ERC8004Client\n */\nexport interface Erc8004ClientOptions {\n /** Base URL of the facilitator (default: https://facilitator.ultravioletadao.xyz) */\n baseUrl?: string;\n /** Request timeout in milliseconds (default: 30000) */\n timeout?: number;\n /**\n * Extra attempts after the first, spent only on a refusal the facilitator\n * proved it did not execute. Default 2; `0` disables. An ambiguous\n * `forward_failed` is never replayed at any setting.\n */\n retries?: number;\n}\n\n/**\n * Client for ERC-8004 Trustless Agents API\n *\n * Provides methods for:\n * - Registering new agents (gasless, facilitator pays gas)\n * - Registering agents on behalf of users (gasless delegation)\n * - Querying agent identity, metadata, and total supply\n * - Querying agent reputation\n * - Submitting reputation feedback\n * - Revoking feedback\n *\n * @example\n * ```ts\n * const client = new Erc8004Client();\n *\n * // Get agent identity\n * const identity = await client.getIdentity('ethereum', 42);\n * console.log(identity.agentUri);\n *\n * // Get agent reputation\n * const reputation = await client.getReputation('ethereum', 42);\n * console.log(`Score: ${reputation.summary.summaryValue}`);\n *\n * // Submit feedback after payment\n * const result = await client.submitFeedback({\n * x402Version: 1,\n * network: 'ethereum',\n * feedback: {\n * agentId: 42,\n * value: 95,\n * valueDecimals: 0,\n * tag1: 'quality',\n * proof: settleResponse.proofOfPayment,\n * },\n * });\n * ```\n */\nexport class Erc8004Client {\n private readonly baseUrl: string;\n private readonly timeout: number;\n private readonly retries: number | undefined;\n\n constructor(options: Erc8004ClientOptions = {}) {\n this.baseUrl = options.baseUrl || 'https://facilitator.ultravioletadao.xyz';\n this.timeout = options.timeout || 30000;\n this.retries = options.retries;\n }\n\n /**\n * POST a write route, keeping a refusal readable.\n *\n * Every ERC-8004 write goes through the facilitator's EVM writer lease, so\n * every one of them can answer `503` + `reason`. Flattened to a string, those\n * are indistinguishable from \"the registry rejected your feedback\" — and on\n * `/register` the wrong reading re-POSTs a mint that may already have landed,\n * which is precisely how five duplicate agents were once created.\n *\n * A refusal the facilitator proved it did not execute is replayed\n * automatically (`safeToReplay`); `forward_failed` never is.\n */\n private async writeJson(\n url: string,\n body: unknown,\n extraHeaders: Record<string, string> = {},\n ): Promise<{ response: Response; error?: FacilitatorErrorInfo }> {\n return facilitatorFetch(\n url,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n ...extraHeaders,\n },\n body: JSON.stringify(body),\n },\n { timeoutMs: this.timeout, retries: this.retries },\n );\n }\n\n /**\n * Get agent identity from the Identity Registry\n *\n * @param network - Network where agent is registered\n * @param agentId - Agent's tokenId\n * @returns Agent identity information\n */\n async getIdentity(network: Erc8004Network, agentId: AgentId): Promise<AgentIdentity> {\n const url = `${this.baseUrl}/identity/${wireNetwork(network)}/${agentId}`;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(url, {\n method: 'GET',\n headers: { 'Accept': 'application/json' },\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`ERC-8004 API error: ${response.status} - ${errorText}`);\n }\n\n return await response.json();\n } catch (error) {\n clearTimeout(timeoutId);\n throw error;\n }\n }\n\n /**\n * Get agent identity by owner address\n *\n * Resolves the first ERC-8004 agent ID owned by a wallet address on a given network.\n *\n * @param network - Network to query\n * @param address - Owner wallet address\n * @returns Agent identity information including balance\n *\n * @example\n * ```ts\n * const identity = await client.getIdentityByOwner('base-mainnet', '0x52E0...');\n * console.log(`Agent #${identity.agentId}, balance: ${identity.balance}`);\n * ```\n */\n async getIdentityByOwner(network: Erc8004Network, address: string): Promise<IdentityByOwnerResponse> {\n const url = `${this.baseUrl}/identity/${wireNetwork(network)}/owner/${address}`;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n const response = await fetch(url, {\n method: 'GET',\n headers: { Accept: 'application/json' },\n signal: controller.signal,\n }).finally(() => clearTimeout(timeoutId));\n\n if (!response.ok) {\n // 404 and 503 are different answers: \"owns nothing\" versus \"could not\n // find out\". Reading the status out of a message string is how they get\n // collapsed, and collapsing them mints a duplicate agent for an owner\n // who already has one. Carry the status, the reason and the wait as\n // fields.\n const info = await readFacilitatorError(response);\n throw new Erc8004LookupError(\n `ERC-8004 API error: ${info.status} - ${info.body}`,\n info.status,\n info.body,\n info.retryAfterSeconds,\n );\n }\n\n return await response.json();\n }\n\n /**\n * Resolve agent registration file from agentURI\n *\n * @param agentUri - URI pointing to agent registration file\n * @returns Resolved agent registration file\n */\n async resolveAgentUri(agentUri: string): Promise<AgentRegistrationFile> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n // Handle IPFS URIs\n let url = agentUri;\n if (agentUri.startsWith('ipfs://')) {\n const cid = agentUri.replace('ipfs://', '');\n url = `https://ipfs.io/ipfs/${cid}`;\n }\n\n const response = await fetch(url, {\n method: 'GET',\n headers: { 'Accept': 'application/json' },\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n throw new Error(`Failed to resolve agentURI: ${response.status}`);\n }\n\n return await response.json();\n } catch (error) {\n clearTimeout(timeoutId);\n throw error;\n }\n }\n\n /**\n * Get agent reputation from the Reputation Registry\n *\n * @param network - Network where agent is registered\n * @param agentId - Agent's tokenId\n * @param options - Query options (tag filters, include individual feedback, client addresses)\n * @param options.clientAddresses - Comma-separated client addresses to filter by.\n * If omitted, the facilitator auto-discovers all clients via getClients().\n * @returns Reputation summary and optionally individual feedback entries\n */\n async getReputation(\n network: Erc8004Network,\n agentId: AgentId,\n options: {\n tag1?: string;\n tag2?: string;\n includeFeedback?: boolean;\n clientAddresses?: string;\n } = {}\n ): Promise<ReputationResponse> {\n const params = new URLSearchParams();\n if (options.tag1) params.set('tag1', options.tag1);\n if (options.tag2) params.set('tag2', options.tag2);\n if (options.includeFeedback) params.set('includeFeedback', 'true');\n if (options.clientAddresses) params.set('clientAddresses', options.clientAddresses);\n\n const url = `${this.baseUrl}/reputation/${wireNetwork(network)}/${agentId}${params.toString() ? `?${params}` : ''}`;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(url, {\n method: 'GET',\n headers: { 'Accept': 'application/json' },\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`ERC-8004 API error: ${response.status} - ${errorText}`);\n }\n\n return await response.json();\n } catch (error) {\n clearTimeout(timeoutId);\n throw error;\n }\n }\n\n /**\n * Submit reputation feedback for an agent\n *\n * Requires proof of payment for authorized feedback submission.\n *\n * @deprecated On this route the facilitator is the AUTHOR: the registry\n * records `msg.sender`, and that is the facilitator's wallet — which can also\n * revoke what it wrote. On the networks in {@link RELAYED_FEEDBACK_NETWORKS}\n * use {@link Erc8004Client.prepareRelayedFeedback} +\n * {@link Erc8004Client.submitRelayedFeedback} instead, which record the RATER\n * as author. This route still works and is not going away without notice: it\n * is the only one available where no `FeedbackDelegate` is deployed.\n *\n * @param request - Feedback request with agent ID, value, and proof\n * @returns Feedback response with transaction hash\n *\n * @example\n * ```ts\n * // After settling a payment with ERC-8004 extension\n * const settleResult = await facilitator.settle(payment, {\n * ...requirements,\n * extra: { '8004-reputation': { includeProof: true } },\n * });\n *\n * // Submit feedback with proof of payment\n * const feedback = await erc8004.submitFeedback({\n * x402Version: 1,\n * network: 'ethereum',\n * feedback: {\n * agentId: 42,\n * value: 95, // 95/100\n * valueDecimals: 0,\n * tag1: 'quality',\n * tag2: 'response-time',\n * proof: settleResult.proofOfPayment,\n * },\n * });\n * ```\n */\n async submitFeedback(request: FeedbackRequest): Promise<FeedbackResponse> {\n const url = `${this.baseUrl}/feedback`;\n\n try {\n const { response, error } = await this.writeJson(url, {\n ...request,\n network: wireNetwork(request.network),\n });\n\n if (error) {\n return {\n success: false,\n error: error.error,\n network: request.network,\n ...failureFields(error),\n };\n }\n\n return await response.json();\n } catch (error) {\n // Timeout or connection failure: the write may already be on-chain.\n // Retryable, never replayable -- reconcile before resending.\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error',\n network: request.network,\n retryable: true,\n safeToReplay: false,\n retryAfterSeconds: DEFAULT_RETRY_AFTER_SECONDS,\n };\n }\n }\n\n /**\n * Ask the facilitator what the rater must sign to author a rating.\n *\n * Step 1 of the rater-authored rail. Writes nothing on-chain and costs\n * nothing: it reads the delegate, the rater's delegation state and their\n * account nonce, then hands back a digest, a deadline and a single-use nonce.\n *\n * Why this exists: the ERC-8004 Reputation Registry records `msg.sender` as\n * the author, and the deployed implementation has no delegation path — no\n * `giveFeedbackWithSignature`, no ERC-2771 forwarder. So a rating the\n * facilitator relays the ordinary way is a rating attributed to the\n * FACILITATOR. EIP-7702 fixes it without touching the registry: the rater\n * delegates their own EOA to the `FeedbackDelegate` and the transaction is\n * sent TO THE RATER'S ADDRESS, so the registry sees the rater while the\n * facilitator pays.\n *\n * What to do with the answer:\n * 1. Produce the rater's signature. **Which value you sign depends on how you\n * sign it**, and getting it wrong yields a well-formed signature that\n * authorises nobody:\n * - raw key: sign `digest` as a **prehash**. It already carries the\n * EIP-191 envelope.\n * - wallet: `personal_sign` over `signingPayload`. `personal_sign` adds the\n * envelope itself, so signing `digest` with it wraps the value TWICE and\n * recovers a stranger — the only symptom is `relay_bad_signature`.\n * - **unless `typedData` came back** — that chain runs a v4 delegate. Then\n * sign THAT with `eth_signTypedData_v4` and ignore the other two: it is\n * the only form the rater can read, and it has no envelope ambiguity.\n * 2. If `delegated` is `false`, also produce an EIP-7702 authorization over\n * `(chainId, delegate, accountNonce)`.\n * 3. Hand both to {@link submitRelayedFeedback} with the SAME feedback\n * parameters, `deadline` and `nonce`.\n *\n * @param request - Network, rater address and feedback parameters\n * @returns Everything needed to sign, including whether an EIP-7702\n * authorization is still required\n *\n * @example\n * ```ts\n * const prep = await erc8004.prepareRelayedFeedback({\n * x402Version: 1,\n * network: 'base',\n * feedback: { agentId: 18896, value: 95, tag1: 'quality', rater: raterAddress },\n * });\n * // prep.delegated === false -> an EIP-7702 authorization is required\n * ```\n */\n async prepareRelayedFeedback(\n request: PrepareRelayFeedbackRequest,\n ): Promise<PrepareRelayFeedbackResponse> {\n const url = `${this.baseUrl}/feedback/evm/prepare`;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n },\n body: JSON.stringify({ ...request, network: wireNetwork(request.network) }),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorText = await response.text();\n return {\n success: false,\n delegated: false,\n chainId: 0,\n error: `Facilitator error: ${response.status} - ${errorText}`,\n network: request.network,\n };\n }\n\n return await response.json();\n } catch (error) {\n clearTimeout(timeoutId);\n return {\n success: false,\n delegated: false,\n chainId: 0,\n error: error instanceof Error ? error.message : 'Unknown error',\n network: request.network,\n };\n }\n }\n\n /**\n * Relay a rater-authored rating; the facilitator pays the gas.\n *\n * Step 2 of the rater-authored rail. The on-chain record that comes out of it\n * has the RATER as `msg.sender`, so `getClients(agentId)` shows the rater\n * rather than the facilitator.\n *\n * Pass back the same feedback parameters, `deadline` and `nonce` that\n * {@link prepareRelayedFeedback} returned. They are not redundant: the\n * facilitator rebuilds the registry calldata from them and requires the\n * rater's signature to cover exactly that.\n *\n * `authorization` is required only when `prepare` answered\n * `delegated: false`. One that names a different delegate than the one\n * `prepare` offered is refused before any gas is spent.\n *\n * @param request - Feedback parameters plus the rater's signature\n * @returns Feedback response with the transaction hash\n */\n async submitRelayedFeedback(\n request: SubmitRelayFeedbackRequest,\n ): Promise<FeedbackResponse> {\n const url = `${this.baseUrl}/feedback/evm/submit`;\n\n try {\n const { response, error } = await this.writeJson(url, {\n ...request,\n network: wireNetwork(request.network),\n });\n\n if (error) {\n return {\n success: false,\n error: error.error,\n network: request.network,\n ...failureFields(error),\n };\n }\n\n return await response.json();\n } catch (error) {\n // Timeout or connection failure: the write may already be on-chain.\n // Retryable, never replayable -- reconcile before resending.\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error',\n network: request.network,\n retryable: true,\n safeToReplay: false,\n retryAfterSeconds: DEFAULT_RETRY_AFTER_SECONDS,\n };\n }\n }\n\n /**\n * Ask the facilitator for the Solana transaction the rater must sign.\n *\n * Step 1 of the rater-authored rail on Solana. Writes nothing on-chain and\n * costs nothing: it resolves the programs and the agent asset, reads the\n * registry collection and a finalized blockhash, and hands back an UNSIGNED\n * transaction whose `client` account is the rater.\n *\n * Why this exists, and why it is not the EVM rail: the program's\n * `give_feedback` instruction declares account 0 as\n * `[signer, writable] client (feedback author / fee payer)`, and plain\n * `POST /feedback` puts the FACILITATOR's keypair there — so the chain\n * records the facilitator as the author of the rating. Solana carries several\n * signers per transaction natively, so the rater signs as `client` while the\n * facilitator stays the fee payer. **No delegation and no program change**,\n * which is why {@link SOLANA_FEEDBACK_NETWORKS} is its own list and `solana`\n * must never appear in {@link RELAYED_FEEDBACK_NETWORKS} — that one routes to\n * `/feedback/evm/*`, which answers 400 here.\n *\n * What to do with the answer:\n * 1. Deserialise `transaction` — base64 of the bincode-serialised **legacy**\n * transaction, which is `@solana/web3.js`'s `Transaction.from()`, not\n * `VersionedTransaction` — and add the RATER's ed25519 signature. Sign the\n * message as it came: re-encoding it changes bytes the facilitator will\n * compare. The fee payer's slot stays empty; `submit` fills it.\n * 2. Hand it back to {@link Erc8004Client.submitSolanaFeedback} with the SAME\n * feedback parameters, before `lastValidBlockHeight` passes.\n *\n * @param request - Network, rater pubkey and feedback parameters\n * @returns The unsigned transaction, the fee payer and the blockhash window\n *\n * @example\n * ```ts\n * import { Transaction } from '@solana/web3.js';\n *\n * const prep = await erc8004.prepareSolanaFeedback({\n * x402Version: 1,\n * network: 'solana',\n * feedback: {\n * agentId: '7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgHkv',\n * rater: raterPubkey, // base58: who the chain records as the author\n * value: 87,\n * score: 95, // without it the rating counts for nothing\n * tag1: 'quality',\n * },\n * });\n *\n * const tx = Transaction.from(Buffer.from(prep.transaction!, 'base64'));\n * tx.partialSign(raterKeypair);\n * ```\n */\n async prepareSolanaFeedback(\n request: PrepareSolanaFeedbackRequest,\n ): Promise<PrepareSolanaFeedbackResponse> {\n const url = `${this.baseUrl}/feedback/solana/prepare`;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n },\n body: JSON.stringify({ ...request, network: wireNetwork(request.network) }),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorText = await response.text();\n return {\n success: false,\n error: `Facilitator error: ${response.status} - ${errorText}`,\n network: request.network,\n };\n }\n\n return await response.json();\n } catch (error) {\n clearTimeout(timeoutId);\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error',\n network: request.network,\n };\n }\n }\n\n /**\n * Co-sign and send a rater-signed Solana feedback transaction.\n *\n * Step 2 of the rater-authored rail on Solana. What lands on-chain has the\n * RATER as `client`, so the agent's feedback lists the rater rather than the\n * facilitator — and only the rater can revoke it.\n *\n * Pass back the same feedback parameters {@link Erc8004Client.prepareSolanaFeedback}\n * was given. They are not redundant: the facilitator re-derives the message\n * from them plus the blockhash inside the submitted transaction, and refuses\n * to co-sign anything that is not byte-for-byte what it built\n * (`400 \"submitted transaction does not match the one this facilitator built\"`).\n * The rater's signature is verified BEFORE the facilitator adds its own, so a\n * transaction the network would reject never costs a fee.\n *\n * @param request - Feedback parameters plus the rater-signed transaction\n * @returns Feedback response with the transaction signature\n */\n async submitSolanaFeedback(\n request: SubmitSolanaFeedbackRequest,\n ): Promise<FeedbackResponse> {\n const url = `${this.baseUrl}/feedback/solana/submit`;\n\n try {\n const { response, error } = await this.writeJson(url, {\n ...request,\n network: wireNetwork(request.network),\n });\n\n if (error) {\n return {\n success: false,\n error: error.error,\n network: request.network,\n ...failureFields(error),\n };\n }\n\n return await response.json();\n } catch (error) {\n // Timeout or connection failure: the write may already be on-chain.\n // Retryable, never replayable -- and on this rail a resubmission needs a\n // fresh `prepare`, because the blockhash the rater signed over expires.\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error',\n network: request.network,\n retryable: true,\n safeToReplay: false,\n retryAfterSeconds: DEFAULT_RETRY_AFTER_SECONDS,\n };\n }\n }\n\n /**\n * Revoke previously submitted feedback\n *\n * Only the original submitter can revoke their feedback.\n *\n * @param network - Network where feedback was submitted\n * @param agentId - Agent ID\n * @param feedbackIndex - Index of feedback to revoke\n * @returns Revocation result\n */\n async revokeFeedback(\n network: Erc8004Network,\n agentId: AgentId,\n feedbackIndex: number,\n options?: { sealHash?: string; originalFeedback?: Omit<FeedbackParams, 'agentId' | 'proof'> }\n ): Promise<FeedbackResponse> {\n const url = `${this.baseUrl}/feedback/revoke`;\n\n const payload: Record<string, unknown> = {\n x402Version: 1,\n network: wireNetwork(network),\n agentId,\n feedbackIndex,\n };\n // Solana revocations need the SEAL hash of the feedback being revoked. Pass\n // originalFeedback and the facilitator derives it; computing it yourself\n // means reimplementing the program's keccak256 layout exactly.\n if (options?.sealHash) {\n payload.sealHash = options.sealHash;\n } else if (options?.originalFeedback) {\n payload.originalFeedback = options.originalFeedback;\n }\n\n try {\n const { response, error } = await this.writeJson(url, payload);\n\n if (error) {\n return {\n success: false,\n error: error.error,\n network,\n ...failureFields(error),\n };\n }\n\n return await response.json();\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error',\n network,\n retryable: true,\n safeToReplay: false,\n retryAfterSeconds: DEFAULT_RETRY_AFTER_SECONDS,\n };\n }\n }\n\n /**\n * Get ERC-8004 contract addresses for a network\n *\n * @param network - Network to get contracts for\n * @returns Contract addresses or undefined if not deployed\n */\n getContracts(network: Erc8004Network): typeof ERC8004_CONTRACTS[Erc8004Network] | undefined {\n return ERC8004_CONTRACTS[network];\n }\n\n /**\n * Check if ERC-8004 is available on a network\n *\n * @param network - Network to check\n * @returns True if ERC-8004 contracts are deployed\n */\n isAvailable(network: string): network is Erc8004Network {\n return network in ERC8004_CONTRACTS;\n }\n\n /**\n * Get feedback endpoint metadata\n *\n * @returns Endpoint information for /feedback\n */\n async getFeedbackMetadata(): Promise<{\n endpoint: string;\n supportedNetworks: Erc8004Network[];\n version: string;\n }> {\n const url = `${this.baseUrl}/feedback`;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(url, {\n method: 'GET',\n headers: { 'Accept': 'application/json' },\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n throw new Error(`Failed to get feedback metadata: ${response.status}`);\n }\n\n return await response.json();\n } catch (error) {\n clearTimeout(timeoutId);\n throw error;\n }\n }\n\n /**\n * Ask what the RESPONDER must sign to author a response on-chain.\n *\n * The mirror of {@link prepareRelayedFeedback}, for the other write the\n * registry accepts from anybody. `appendResponse` is not agent-only — the\n * registry takes it from any address — so on the plain {@link appendResponse}\n * route the `responder` recorded on-chain is the FACILITATOR. That does not\n * destroy anyone's reputation the way a revoke would; it ties the\n * facilitator's on-chain identity to a third party's content, which is its own\n * kind of wrong.\n *\n * **v4 delegates only.** The v3 delegate accepts exactly two selectors and\n * `appendResponse` is not one of them, so a v3 network answers 400\n * `relay_response_needs_v4` rather than silently falling back to the route\n * this replaces.\n *\n * `clientAddress` and `feedbackIndex` are inside the signed struct: without\n * them one signature would answer any client's rating, or any rating at that\n * index.\n */\n async prepareRelayedResponse(\n request: PrepareRelayResponseRequest\n ): Promise<PrepareRelayFeedbackResponse> {\n return this.postRelay('/feedback/response/evm/prepare', request, {\n success: false,\n delegated: false,\n chainId: 0,\n network: request.network,\n });\n }\n\n /**\n * Relay a responder-authored response; the facilitator pays the gas.\n *\n * Pass back the same parameters, `deadline` and `nonce` that\n * {@link prepareRelayedResponse} returned: the facilitator rebuilds the struct\n * from them and refuses to relay anything the signature does not cover.\n */\n async submitRelayedResponse(\n request: SubmitRelayResponseRequest\n ): Promise<FeedbackResponse> {\n return this.postRelay('/feedback/response/evm/submit', request, {\n success: false,\n network: request.network,\n });\n }\n\n /** Shared POST for the relay routes: a refusal is data, never a throw. */\n private async postRelay<T>(path: string, request: { network: Erc8004Network }, onError: T): Promise<T> {\n try {\n const { response, error } = await this.writeJson(`${this.baseUrl}${path}`, {\n ...request,\n network: wireNetwork(request.network),\n });\n if (error) {\n return { ...onError, error: error.error, ...failureFields(error) };\n }\n return await response.json();\n } catch (error) {\n return {\n ...onError,\n error: error instanceof Error ? error.message : 'Unknown error',\n retryable: true,\n safeToReplay: false,\n retryAfterSeconds: DEFAULT_RETRY_AFTER_SECONDS,\n };\n }\n }\n\n /**\n * Append a response to existing feedback\n *\n * @deprecated On this route the facilitator is the AUTHOR: the registry\n * records `msg.sender` as the `responder`, and that is the facilitator's\n * wallet. Where the delegate is **v4**, use {@link prepareRelayedResponse} +\n * {@link submitRelayedResponse} instead. This route still works and is the\n * only one available where the delegate is still v3.\n *\n * **This is NOT agent-only**, despite what this comment claimed until\n * 2026-08-25. Verified on-chain on 2026-08-18: the registry accepts\n * `appendResponse` from ANY address. There is no identity-owner check, here or\n * in the contract.\n *\n * @param network - Network where feedback was submitted\n * @param agentId - Agent ID\n * @param feedbackIndex - Index of feedback to respond to\n * @param response - Response content\n * @param responseUri - Optional URI to off-chain response file\n * @returns Response result\n *\n * @example\n * ```ts\n * // Agent responds to feedback\n * const result = await erc8004.appendResponse(\n * 'ethereum',\n * 42,\n * 1,\n * 'Thank you for your feedback! We have addressed the issue.',\n * );\n * ```\n */\n async appendResponse(\n network: Erc8004Network,\n agentId: AgentId,\n feedbackIndex: number,\n response: string,\n options?: { responseUri?: string; sealHash?: string }\n ): Promise<FeedbackResponse> {\n const url = `${this.baseUrl}/feedback/response`;\n\n const payload: Record<string, unknown> = {\n x402Version: 1,\n network: wireNetwork(network),\n agentId,\n feedbackIndex,\n response,\n };\n if (options?.responseUri) {\n payload.responseUri = options.responseUri;\n }\n if (options?.sealHash) {\n payload.sealHash = options.sealHash;\n }\n\n try {\n const { response: fetchResponse, error } = await this.writeJson(url, payload);\n\n if (error) {\n return {\n success: false,\n error: error.error,\n network,\n ...failureFields(error),\n };\n }\n\n return await fetchResponse.json();\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error',\n network,\n retryable: true,\n safeToReplay: false,\n retryAfterSeconds: DEFAULT_RETRY_AFTER_SECONDS,\n };\n }\n }\n\n /**\n * Register an agent on the Identity Registry (idempotent)\n *\n * If the recipient already owns an agent on the target network, returns the\n * existing one instead of minting a duplicate. The facilitator pays gas fees.\n * Optionally transfer the NFT to a recipient address (gasless delegation).\n *\n * @param request - Registration request\n * @returns Registration response with agent ID and transaction hash\n *\n * @example\n * ```ts\n * // Register agent owned by facilitator\n * const result = await client.registerAgent({\n * x402Version: 1,\n * network: 'ethereum',\n * agentUri: 'ipfs://QmYourAgentFile',\n * });\n * console.log(`Agent #${result.agentId} registered`);\n *\n * // Register agent and transfer to user\n * const result = await client.registerAgent({\n * x402Version: 1,\n * network: 'ethereum',\n * agentUri: 'ipfs://QmYourAgentFile',\n * recipient: '0xUserAddress...',\n * });\n * console.log(`Agent #${result.agentId} transferred to user`);\n * ```\n */\n async registerAgent(\n request: RegisterAgentRequest,\n options?: { asyncTransport?: boolean; pollIntervalMs?: number; timeoutMs?: number },\n ): Promise<RegisterAgentResponse> {\n // asyncTransport changes how the wait is carried out, not what comes back.\n // The synchronous call holds one HTTP request open for the whole mint, which\n // on a congested chain outlives proxy timeouts; each poll here is short, so\n // nothing in the path can time out ambiguously.\n if (options?.asyncTransport) {\n const job = await this.registerAgentAsync(request);\n const terminal = await this.waitForRegistration(job.jobId, {\n pollIntervalMs: options.pollIntervalMs,\n timeoutMs: options.timeoutMs,\n });\n return jobToRegisterResponse(terminal, request.network);\n }\n\n const url = `${this.baseUrl}/register`;\n\n try {\n const { response, error } = await this.writeJson(url, {\n ...request,\n network: wireNetwork(request.network),\n });\n\n if (error) {\n // The facilitator answers 4xx with a structured RegisterAgentResponse,\n // and on 409 - a registration for this agent is ALREADY IN FLIGHT -\n // that body carries the agent id and tx of the run already underway,\n // plus an explicit \"poll GET /register/status/{jobId}\" hint.\n //\n // Flattening it into a bare string threw away the only thing that lets\n // a caller resolve instead of re-POSTing, and re-POSTing a mint is\n // exactly how duplicate agents get created. Keep the body.\n try {\n const parsed = JSON.parse(error.body) as RegisterAgentResponse;\n if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {\n return {\n ...parsed,\n // Never let a non-2xx body claim success, whatever it says.\n success: false,\n error: parsed.error ?? `Facilitator error: ${error.status}`,\n network: parsed.network ?? request.network,\n ...failureFields(error),\n };\n }\n } catch {\n // Not JSON - fall through to the flattened error.\n }\n return {\n success: false,\n error: error.error,\n network: request.network,\n ...failureFields(error),\n };\n }\n\n return await response.json();\n } catch (error) {\n // A MINT that timed out is the single most dangerous ambiguity in this\n // SDK: the transaction may be mining right now. `safeToReplay: false`\n // says so out loud. Resolve with\n // `GET /identity/{network}/owner/{recipient}` -- honouring its 404-vs-503\n // distinction -- or with `getRegisterStatus`, never by re-POSTing.\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error',\n network: request.network,\n retryable: true,\n safeToReplay: false,\n retryAfterSeconds: DEFAULT_RETRY_AFTER_SECONDS,\n };\n }\n }\n\n /**\n * Start a registration without waiting for the chain to confirm it.\n *\n * Registration waits on a mint receipt, which on a congested chain outlives\n * client and proxy timeouts. A timed-out synchronous call is genuinely\n * ambiguous — the mint may well have landed — and retrying it is how five\n * duplicate agents once got minted. This returns immediately with a job id\n * instead; poll {@link getRegisterStatus} or use {@link waitForRegistration}.\n *\n * On Solana, `recipient` is a base58 address: the facilitator mints,\n * initializes the ATOM stats and transfers, paying every fee.\n */\n async registerAgentAsync(request: RegisterAgentRequest): Promise<RegisterJobResponse> {\n const url = `${this.baseUrl}/register`;\n\n // A 503 here is the SAFE half of the register story: the job was never\n // created, so a replay creates one job, not two. `writeJson` replays only\n // what the facilitator proved it did not execute, and never\n // `forward_failed`.\n const { response, error } = await this.writeJson(\n url,\n { ...request, network: wireNetwork(request.network) },\n { Prefer: 'respond-async' },\n );\n\n if (error) {\n throw new Erc8004LookupError(\n `ERC-8004 API error: ${error.status} - ${error.body}`,\n error.status,\n error.body,\n error.retryAfterSeconds,\n );\n }\n\n return await response.json();\n }\n\n /**\n * Read the current state of an asynchronous registration.\n *\n * Throws {@link Erc8004LookupError} with `notFound` when the job is unknown or\n * has aged out — terminal jobs are kept for one hour.\n */\n async getRegisterStatus(jobId: string): Promise<RegisterJobResponse> {\n const url = `${this.baseUrl}/register/status/${encodeURIComponent(jobId)}`;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n const response = await fetch(url, {\n method: 'GET',\n headers: { Accept: 'application/json' },\n signal: controller.signal,\n }).finally(() => clearTimeout(timeoutId));\n\n if (!response.ok) {\n const info = await readFacilitatorError(response);\n throw new Erc8004LookupError(\n `ERC-8004 API error: ${info.status} - ${info.body}`,\n info.status,\n info.body,\n info.retryAfterSeconds,\n );\n }\n\n return await response.json();\n }\n\n /**\n * Poll an asynchronous registration until it finishes.\n *\n * Rejects on timeout rather than resolving with the last non-terminal status,\n * so \"still pending\" is never mistaken for \"did not happen\": the mint may\n * still land afterwards, and treating a timeout as failure is what leads to\n * registering the same agent twice. Keep the job id and poll again rather\n * than re-registering.\n */\n async waitForRegistration(\n jobId: string,\n options?: { pollIntervalMs?: number; timeoutMs?: number },\n ): Promise<RegisterJobResponse> {\n const pollIntervalMs = options?.pollIntervalMs ?? 2000;\n const timeoutMs = options?.timeoutMs ?? 300_000;\n const deadline = Date.now() + timeoutMs;\n\n for (;;) {\n const job = await this.getRegisterStatus(jobId);\n if (isRegisterJobTerminal(job)) {\n return job;\n }\n if (Date.now() >= deadline) {\n throw new RegistrationPendingError(jobId, job.status, timeoutMs);\n }\n await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));\n }\n }\n\n /**\n * Get registration endpoint metadata\n *\n * @returns Endpoint information for POST /register\n */\n async getRegisterInfo(): Promise<Record<string, unknown>> {\n const url = `${this.baseUrl}/register`;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(url, {\n method: 'GET',\n headers: { 'Accept': 'application/json' },\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`ERC-8004 API error: ${response.status} - ${errorText}`);\n }\n\n return await response.json();\n } catch (error) {\n clearTimeout(timeoutId);\n throw error;\n }\n }\n\n /**\n * Get a specific metadata entry for an agent\n *\n * @param network - Network where agent is registered\n * @param agentId - Agent's tokenId\n * @param key - Metadata key to retrieve\n * @returns Metadata value (hex-encoded and UTF-8 decoded if possible)\n */\n async getIdentityMetadata(\n network: Erc8004Network,\n agentId: AgentId,\n key: string,\n ): Promise<IdentityMetadataResponse> {\n const url = `${this.baseUrl}/identity/${wireNetwork(network)}/${agentId}/metadata/${encodeURIComponent(key)}`;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(url, {\n method: 'GET',\n headers: { 'Accept': 'application/json' },\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`ERC-8004 API error: ${response.status} - ${errorText}`);\n }\n\n return await response.json();\n } catch (error) {\n clearTimeout(timeoutId);\n throw error;\n }\n }\n\n /**\n * Get total number of registered agents on a network\n *\n * @param network - Network to query\n * @returns Total supply count\n */\n async getIdentityTotalSupply(network: Erc8004Network): Promise<IdentityTotalSupplyResponse> {\n const url = `${this.baseUrl}/identity/${wireNetwork(network)}/total-supply`;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(url, {\n method: 'GET',\n headers: { 'Accept': 'application/json' },\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`ERC-8004 API error: ${response.status} - ${errorText}`);\n }\n\n return await response.json();\n } catch (error) {\n clearTimeout(timeoutId);\n throw error;\n }\n }\n}\n\n/**\n * Build payment requirements with ERC-8004 extension\n *\n * Adds the 8004-reputation extension to include proof of payment\n * in settlement responses for reputation submission.\n *\n * @param options - Base payment requirements options\n * @returns Payment requirements with ERC-8004 extension\n *\n * @example\n * ```ts\n * const requirements = buildErc8004PaymentRequirements({\n * amount: '1.00',\n * recipient: '0x...',\n * resource: 'https://api.example.com/service',\n * chainName: 'ethereum',\n * });\n *\n * // Settlement will include proofOfPayment\n * const result = await facilitator.settle(payment, requirements);\n * console.log(result.proofOfPayment);\n * ```\n */\nexport function buildErc8004PaymentRequirements(\n options: PaymentRequirementsOptions\n): PaymentRequirements & { extra: { '8004-reputation': { includeProof: boolean } } } {\n const base = buildPaymentRequirements(options);\n return {\n ...base,\n extra: {\n [ERC8004_EXTENSION_ID]: {\n includeProof: true,\n },\n },\n };\n}\n\n// ============================================================================\n// ADVANCED ESCROW (PaymentOperator - On-Chain Escrow)\n// ============================================================================\n//\n// The 5 Advanced Escrow flows via the PaymentOperator contract:\n// 1. AUTHORIZE - Lock funds in escrow (via facilitator)\n// 2. RELEASE - Capture escrowed funds to receiver (on-chain)\n// 3. REFUND IN ESCROW - Return escrowed funds to payer (on-chain)\n// 4. CHARGE - Direct instant payment without escrow (on-chain)\n// 5. REFUND POST ESCROW - Dispute refund after release (on-chain)\n//\n// Contract mapping:\n// operator.authorize() -> escrow.authorize() (lock funds)\n// operator.release() -> escrow.capture() (pay receiver)\n// operator.refundInEscrow() -> escrow.partialVoid() (refund payer)\n// operator.charge() -> escrow.charge() (direct payment)\n// operator.refundPostEscrow() -> escrow.refund() (dispute refund)\n// ============================================================================\n\n/**\n * PAYMENT_INFO_TYPEHASH used for nonce computation.\n * Must match the on-chain AuthCaptureEscrow contract.\n */\nexport const PAYMENT_INFO_TYPEHASH =\n '0xae68ac7ce30c86ece8196b61a7c486d8f0061f575037fbd34e7fe4e2820c6591';\n\nexport const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';\n\n/**\n * Contract deposit limit (enforced by PaymentOperator condition).\n * As of 2026-02-03, commerce-payments contracts enforce $100 max per deposit.\n */\nexport const DEPOSIT_LIMIT_USDC = '100000000'; // $100 in atomic units (6 decimals)\n\n/**\n * Default facilitator request timeout per chain in milliseconds.\n * Ethereum L1 (~12s blocks) needs much longer than L2s (~2s blocks).\n * Timeout chain: Client > SDK > Facilitator. The facilitator uses 900s for Ethereum L1.\n *\n * These are correct, and they are also a PRODUCT constraint worth reading before\n * you offer a network in a checkout: Ethereum L1 is 960s against 90s for every\n * L2 here. A buyer waiting in a browser will not wait sixteen minutes, so a\n * human-facing flow should offer the L2s and leave L1 to agent-to-agent or\n * batch callers that can tolerate the wait. Do not shorten this to make a\n * checkout feel faster — the value tracks L1 block time and the facilitator's\n * own 900s TxWatcher, and cutting it just times out a payment that was going\n * to land.\n */\nexport const ESCROW_TIMEOUT_MS: Record<number, number> = {\n 1: 960_000, // Ethereum L1: 960s (facilitator uses 900s TxWatcher)\n 11155111: 960_000, // Ethereum Sepolia: same as L1\n 137: 90_000, // Polygon: 90s\n 8453: 90_000, // Base: 90s\n 84532: 90_000, // Base Sepolia: 90s\n 42161: 90_000, // Arbitrum: 90s\n 10: 90_000, // Optimism: 90s\n 43114: 90_000, // Avalanche: 90s\n 42220: 90_000, // Celo: 90s\n 143: 90_000, // Monad: 90s\n};\n\n/** Default timeout when chain is not in ESCROW_TIMEOUT_MS */\nconst DEFAULT_ESCROW_TIMEOUT_MS = 30_000;\n\n/**\n * USDC EIP-712 domain name per chain.\n * Most chains use \"USD Coin\", but some (Celo, Monad, HyperEVM) use \"USDC\".\n * This must match the on-chain token's name() for EIP-712 signing to work.\n */\nexport const USDC_DOMAIN_NAME: Record<number, string> = {\n 8453: 'USD Coin', // Base Mainnet\n 84532: 'USD Coin', // Base Sepolia\n 1: 'USD Coin', // Ethereum Mainnet\n 11155111: 'USD Coin', // Ethereum Sepolia\n 137: 'USD Coin', // Polygon\n 42161: 'USD Coin', // Arbitrum\n 43114: 'USD Coin', // Avalanche\n 42220: 'USDC', // Celo\n 143: 'USDC', // Monad\n};\n\n/**\n * Multi-chain escrow contract addresses for the Advanced Escrow system.\n * Keyed by EVM chain ID. Source: x402r-sdk A1igator/multichain-config deployment.\n */\n/**\n * Per-chain escrow contract addresses.\n *\n * KNOWN GAP, measured 2026-09-05: the `operator` entries are\n * PaymentOperatorFactory addresses, not deployed PaymentOperator instances.\n * Verified on Base mainnet, Base Sepolia and Arbitrum — they answer\n * `ESCROW()` and `operators(bytes32)` and revert on `FEE_CALCULATOR()`,\n * `FEE_RECIPIENT()` and `release(...)` — and x402-rs\n * `docs/X402R_MULTICHAIN_DEPLOYMENT.md` labels the same addresses\n * \"PaymentOperatorFactory\". A factory has no `release`/`charge`, so the direct\n * on-chain paths below cannot execute against these addresses as written;\n * resolve the real operator from the marketplace's own escrow config\n * ({@link EscrowNetworkConfig}) and pass it via `options.contracts`.\n * See {@link OPERATOR_FEE_BPS} for the commands.\n */\nexport const ESCROW_CONTRACTS: Record<number, AdvancedEscrowContracts> = {\n // Base Sepolia (testnet, chain 84532)\n 84532: {\n operator: '0x97d53e63A9CB97556c00BeFd325AF810c9b267B2',\n escrow: '0x29025c0E9D4239d438e169570818dB9FE0A80873',\n tokenCollector: '0x5cA789000070DF15b4663DB64a50AeF5D49c5Ee0',\n protocolFeeConfig: '0x8F96C493bAC365E41f0315cf45830069EBbDCaCe',\n refundRequest: '0x1C2Ab244aC8bDdDB74d43389FF34B118aF2E90F4',\n usdc: '0x036CbD53842c5426634e7929541eC2318f3dCF7e',\n },\n // Base Mainnet (chain 8453)\n 8453: {\n operator: '0x3D0837fF8Ea36F417261577b9BA568400A840260',\n escrow: '0xb9488351E48b23D798f24e8174514F28B741Eb4f',\n tokenCollector: '0x48ADf6E37F9b31dC2AAD0462C5862B5422C736B8',\n protocolFeeConfig: '0x59314674BAbb1a24Eb2704468a9cCdD50668a1C6',\n refundRequest: '0x35fb2EFEfAc3Ee9f6E52A9AAE5C9655bC08dEc00',\n usdc: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\n },\n // Ethereum Sepolia (testnet, chain 11155111)\n 11155111: {\n operator: '0x32d6AC59BCe8DFB3026F10BcaDB8D00AB218f5b6',\n escrow: '0x320a3c35F131E5D2Fb36af56345726B298936037',\n tokenCollector: '0x230fd3A171750FA45db2976121376b7F47Cba308',\n protocolFeeConfig: '0xD979dBfBdA5f4b16AAF60Eaab32A44f352076838',\n refundRequest: '0xc1256Bb30bd0cdDa07D8C8Cf67a59105f2EA1b98',\n usdc: '0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238',\n },\n // Ethereum Mainnet (chain 1) - Updated from Ali's redeploy (commit e6cf29d)\n 1: {\n operator: '0x69B67962ffb7c5C7078ff348a87DF604dfA8001b',\n escrow: '0x9D4146EF898c8E60B3e865AE254ef438E7cEd2A0',\n tokenCollector: '0x206D4DbB6E7b876e4B5EFAAD2a04e7d7813FB6ba',\n protocolFeeConfig: '0x5b3e33791C1764cF7e2573Bf8116F1D361FD97Cd',\n refundRequest: '0xFa8C4Cb156053b867Ae7489220A29b5939E3Df70',\n usdc: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',\n },\n // Polygon (chain 137)\n 137: {\n operator: '0xb33D6502EdBbC47201cd1E53C49d703EC0a660b8',\n escrow: '0x32d6AC59BCe8DFB3026F10BcaDB8D00AB218f5b6',\n tokenCollector: '0xc1256Bb30bd0cdDa07D8C8Cf67a59105f2EA1b98',\n protocolFeeConfig: '0xE78648e7af7B1BaDE717FF6E410B922F92adE80f',\n refundRequest: '0xed02d3E5167BCc9582D851885A89b050AB816a56',\n usdc: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',\n },\n // Arbitrum (chain 42161)\n 42161: {\n operator: '0x32d6AC59BCe8DFB3026F10BcaDB8D00AB218f5b6',\n escrow: '0x320a3c35F131E5D2Fb36af56345726B298936037',\n tokenCollector: '0x230fd3A171750FA45db2976121376b7F47Cba308',\n protocolFeeConfig: '0xD979dBfBdA5f4b16AAF60Eaab32A44f352076838',\n refundRequest: '0xc1256Bb30bd0cdDa07D8C8Cf67a59105f2EA1b98',\n usdc: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',\n },\n // Celo (chain 42220)\n 42220: {\n operator: '0x32d6AC59BCe8DFB3026F10BcaDB8D00AB218f5b6',\n escrow: '0x320a3c35F131E5D2Fb36af56345726B298936037',\n tokenCollector: '0x230fd3A171750FA45db2976121376b7F47Cba308',\n protocolFeeConfig: '0xD979dBfBdA5f4b16AAF60Eaab32A44f352076838',\n refundRequest: '0xc1256Bb30bd0cdDa07D8C8Cf67a59105f2EA1b98',\n usdc: '0xcebA9300f2b948710d2653dD7B07f33A8B32118C',\n },\n // Monad (chain 143)\n 143: {\n operator: '0x32d6AC59BCe8DFB3026F10BcaDB8D00AB218f5b6',\n escrow: '0x320a3c35F131E5D2Fb36af56345726B298936037',\n tokenCollector: '0x230fd3A171750FA45db2976121376b7F47Cba308',\n protocolFeeConfig: '0xD979dBfBdA5f4b16AAF60Eaab32A44f352076838',\n refundRequest: '0xc1256Bb30bd0cdDa07D8C8Cf67a59105f2EA1b98',\n usdc: '0x754704Bc059F8C67012fEd69BC8a327a5aafb603',\n },\n // Avalanche (chain 43114)\n 43114: {\n operator: '0x32d6AC59BCe8DFB3026F10BcaDB8D00AB218f5b6',\n escrow: '0x320a3c35F131E5D2Fb36af56345726B298936037',\n tokenCollector: '0x230fd3A171750FA45db2976121376b7F47Cba308',\n protocolFeeConfig: '0xD979dBfBdA5f4b16AAF60Eaab32A44f352076838',\n refundRequest: '0xc1256Bb30bd0cdDa07D8C8Cf67a59105f2EA1b98',\n usdc: '0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E',\n },\n // Optimism (chain 10)\n 10: {\n operator: '0x32d6AC59BCe8DFB3026F10BcaDB8D00AB218f5b6',\n escrow: '0x320a3c35F131E5D2Fb36af56345726B298936037',\n tokenCollector: '0x230fd3A171750FA45db2976121376b7F47Cba308',\n protocolFeeConfig: '0xD979dBfBdA5f4b16AAF60Eaab32A44f352076838',\n refundRequest: '0xc1256Bb30bd0cdDa07D8C8Cf67a59105f2EA1b98',\n usdc: '0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85',\n },\n // SKALE Base (chain 1187947933) - CREATE3 deployment, operator via factory\n 1187947933: {\n operator: '0x28c23AE8f55aDe5Ea10a5353FC40418D0c1B3d33',\n escrow: '0xBC151792f80C0EB1973d56b0235e6bee2A60e245',\n tokenCollector: '0x9A12A116a44636F55c9e135189A1321Abcfe2f30',\n protocolFeeConfig: '0xf62788834C99B2E85a6891C0b46D1EB996f8f596',\n refundRequest: '0x69e9BF2b40Ed472b55E47e9D4205d93Ed673093F',\n usdc: '0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20',\n },\n};\n\n/**\n * Base Mainnet contract addresses for the Advanced Escrow system.\n * @deprecated Use ESCROW_CONTRACTS[8453] or getEscrowContractsByChainId(8453) instead.\n */\nexport const BASE_MAINNET_CONTRACTS: AdvancedEscrowContracts = ESCROW_CONTRACTS[8453];\n\n/**\n * Get escrow contract addresses for a given chain ID.\n *\n * @param chainId - EVM chain ID (e.g., 8453 for Base, 1 for Ethereum)\n * @returns Contract addresses or undefined if chain is not supported\n */\nexport function getEscrowContractsByChainId(chainId: number): AdvancedEscrowContracts | undefined {\n return ESCROW_CONTRACTS[chainId];\n}\n\n/**\n * Get all chain IDs that have escrow contracts deployed.\n *\n * @returns Array of chain IDs with escrow support\n */\nexport function getEscrowSupportedChainIds(): number[] {\n return Object.keys(ESCROW_CONTRACTS).map(Number);\n}\n\n/**\n * Check if escrow contracts are deployed on a given chain.\n *\n * @param chainId - EVM chain ID\n * @returns True if escrow is supported on this chain\n */\nexport function isEscrowSupportedOnChain(chainId: number): boolean {\n return chainId in ESCROW_CONTRACTS;\n}\n\n/**\n * Task tiers determine timing parameters for escrow operations.\n */\nexport type AdvancedEscrowTaskTier = 'micro' | 'standard' | 'premium' | 'enterprise';\n\n/**\n * Timing configuration per task tier (in seconds).\n */\nexport const TIER_TIMINGS: Record<AdvancedEscrowTaskTier, { pre: number; auth: number; refund: number }> = {\n micro: { pre: 3600, auth: 7200, refund: 86400 },\n standard: { pre: 7200, auth: 86400, refund: 604800 },\n premium: { pre: 14400, auth: 172800, refund: 1209600 },\n enterprise: { pre: 86400, auth: 604800, refund: 2592000 },\n};\n\n/**\n * PaymentInfo struct matching the on-chain PaymentOperator contract.\n */\nexport interface AdvancedPaymentInfo {\n operator: string;\n receiver: string;\n token: string;\n maxAmount: string;\n preApprovalExpiry: number;\n authorizationExpiry: number;\n refundExpiry: number;\n minFeeBps: number;\n maxFeeBps: number;\n feeReceiver: string;\n salt: string;\n}\n\n/**\n * Optional signed lifecycle order for `releaseViaFacilitator` /\n * `refundViaFacilitator`.\n *\n * Both actions move money that is ALREADY escrowed, so neither carries an\n * ERC-3009 signature and the entitlement question — who may ask for the move —\n * has no other answer. Supplying a `lifecycleSigner` answers it; omitting one\n * leaves the request byte-for-byte as it was, which is why every field here is\n * optional and the default is to send nothing.\n *\n * The accepted signers are the facilitator's, not this SDK's: `release` takes\n * the payer or the operator owner (`FEE_RECIPIENT()`); `refundInEscrow` takes\n * the receiver, the operator owner, or the payer once `authorizationExpiry`\n * has passed. Anything else is logged as `unauthorized_role`.\n */\nexport interface LifecycleAuthOptions {\n /**\n * Who signs the order. Any adapter with `getAddress()` + `signTypedData()`:\n * `EnvKeyAdapter` server-side, `OWSWalletAdapter`, or\n * `wagmiLifecycleSigner(walletClient)` when the PAYER signs in their own\n * browser and this backend only transports the block.\n */\n lifecycleSigner?: LifecycleSigner;\n /**\n * Unix seconds. Default: `now + 600`, which leaves 300 s of headroom under\n * the facilitator's 900 s ceiling. Only read alongside `lifecycleSigner` —\n * a `lifecycleAuth` already carries the deadline it was signed with.\n */\n lifecycleDeadline?: number;\n /**\n * An order that was ALREADY SIGNED somewhere else — the publisher's browser\n * — and that this backend only transports.\n *\n * The signing side builds the document with `buildLifecycleTypedData`, the\n * browser signs it, and `lifecycleAuthFromSignature` turns the signature\n * back into this block. Nothing is re-derived here: the `paymentInfo`, the\n * `payer` and the `amount` this call sends must be the ones the order\n * committed to, or the facilitator reads `bad_signature`.\n *\n * MUTUALLY EXCLUSIVE with `lifecycleSigner`. Passing both is not a\n * preference to resolve — it means the caller believes two different orders\n * are about to travel, and only one can. It throws.\n */\n lifecycleAuth?: LifecycleAuth;\n}\n\n/**\n * The order that rides on a lifecycle request, from whichever of the two\n * shapes the caller chose.\n *\n * Kept out of both methods so the exclusivity rule is written ONCE: duplicated,\n * the day one branch grows a condition the other silently keeps the old one.\n */\nasync function resolveLifecycleAuth(\n action: LifecycleAction,\n options: LifecycleAuthOptions | undefined,\n order: {\n paymentInfo: LifecyclePaymentInfo;\n payer: string;\n amount: string;\n chainId: number;\n }\n): Promise<LifecycleAuth | undefined> {\n if (options?.lifecycleSigner && options?.lifecycleAuth) {\n throw new X402Error(\n 'lifecycleSigner and lifecycleAuth are mutually exclusive: the first signs an order ' +\n 'here, the second was already signed elsewhere. Passing both means two different ' +\n 'orders exist and only one can travel.',\n 'INVALID_CONFIG'\n );\n }\n // Transported as-is. Re-signing or \"normalizing\" it would change the bytes\n // the browser committed to.\n if (options?.lifecycleAuth) return options.lifecycleAuth;\n if (!options?.lifecycleSigner) return undefined;\n return buildLifecycleAuth({\n action,\n paymentInfo: order.paymentInfo,\n payer: order.payer,\n amount: order.amount,\n chainId: order.chainId,\n wallet: options.lifecycleSigner,\n deadline: options.lifecycleDeadline,\n });\n}\n\n/**\n * Result of an AUTHORIZE operation.\n */\nexport interface AdvancedAuthorizationResult {\n success: boolean;\n transactionHash?: string;\n paymentInfo?: AdvancedPaymentInfo;\n salt?: string;\n error?: string;\n}\n\n/**\n * Result of an on-chain transaction (release, refund, charge).\n */\nexport interface AdvancedTransactionResult extends FacilitatorFailureFields {\n success: boolean;\n transactionHash?: string;\n gasUsed?: number;\n /**\n * Why it failed.\n *\n * On the gasless (`*ViaFacilitator`) paths, check `retryable` first: a\n * facilitator that could not hand the write to its lease holder rejected\n * nothing on-chain, and the escrow is exactly as it was. Reporting that as a\n * failed refund is how funds get written off while they are still sitting in\n * escrow, recoverable.\n */\n error?: string;\n}\n\n/**\n * Response from the facilitator's /escrow/state endpoint.\n * Represents the on-chain state of an escrow for a given paymentInfo + payer.\n */\nexport interface EscrowStateResponse {\n /** Whether the payment has already been collected (released) */\n hasCollectedPayment: boolean;\n /** Amount that can still be captured/released (in atomic units) */\n capturableAmount: string;\n /** Amount that can still be refunded to the payer (in atomic units) */\n refundableAmount: string;\n /** Keccak256 hash of the paymentInfo struct */\n paymentInfoHash: string;\n /** Network in CAIP-2 format (e.g., \"eip155:8453\") */\n network: string;\n}\n\n/**\n * Contract addresses configuration for AdvancedEscrowClient.\n *\n * Maps to the on-chain x402r escrow contracts:\n * - operator: PaymentOperatorFactory\n * - escrow: AuthCaptureEscrow\n * - tokenCollector: TokenCollector\n * - protocolFeeConfig: ProtocolFeeConfig\n * - refundRequest: RefundRequest\n * - usdc: USDC token contract\n */\nexport interface AdvancedEscrowContracts {\n /** PaymentOperatorFactory contract address */\n operator: string;\n /** AuthCaptureEscrow contract address */\n escrow: string;\n /** TokenCollector contract address */\n tokenCollector: string;\n /** ProtocolFeeConfig contract address */\n protocolFeeConfig: string;\n /** RefundRequest contract address */\n refundRequest: string;\n /** USDC token contract address */\n usdc: string;\n}\n\n/**\n * Configuration options for AdvancedEscrowClient.\n */\nexport interface AdvancedEscrowClientOptions {\n /** Facilitator URL for AUTHORIZE operations */\n facilitatorUrl?: string;\n /** JSON-RPC URL for on-chain operations (required when using SigningWalletAdapter) */\n rpcUrl?: string;\n /**\n * Chain ID (default: 8453 for Base Mainnet).\n * Supported chains: 8453 (Base), 84532 (Base Sepolia), 1 (Ethereum),\n * 11155111 (Ethereum Sepolia), 137 (Polygon), 42161 (Arbitrum),\n * 10 (Optimism), 42220 (Celo), 143 (Monad), 43114 (Avalanche).\n */\n chainId?: number;\n /** Contract addresses (auto-resolved from chainId if not provided) */\n contracts?: AdvancedEscrowContracts;\n /** Gas limit for transactions (default: 300000) */\n gasLimit?: number;\n /**\n * Request timeout in milliseconds for facilitator HTTP calls (authorize, gasless release/refund).\n * Default is per-network: 960s for Ethereum L1, 90s for L2s.\n * Ethereum L1 confirmations can take several minutes under congestion.\n */\n timeout?: number;\n /**\n * SigningWalletAdapter for OWS wallet signing (v2.36.0+).\n *\n * When provided, the client uses the adapter for all signing operations\n * instead of requiring a raw ethers.Signer. The first constructor argument\n * is ignored when `wallet` is set.\n *\n * Requires `rpcUrl` to be set for on-chain transaction building.\n *\n * @example\n * ```typescript\n * import { OWSWalletAdapter, AdvancedEscrowClient } from 'uvd-x402-sdk/backend';\n *\n * const wallet = new OWSWalletAdapter(owsWallet);\n * const client = new AdvancedEscrowClient(null, {\n * wallet,\n * rpcUrl: 'https://mainnet.base.org',\n * chainId: 8453,\n * });\n * ```\n */\n wallet?: import('../wallet').SigningWalletAdapter;\n /**\n * Extra attempts on the gasless facilitator paths when the facilitator proved\n * it executed nothing. Default 2; `0` disables.\n */\n retries?: number;\n}\n\n/**\n * Minimal PaymentOperator ABI for the 4 on-chain functions.\n * (AUTHORIZE goes through the facilitator, not directly on-chain)\n */\nexport const OPERATOR_ABI = [\n 'function release(tuple(address operator, address payer, address receiver, address token, uint120 maxAmount, uint48 preApprovalExpiry, uint48 authorizationExpiry, uint48 refundExpiry, uint16 minFeeBps, uint16 maxFeeBps, address feeReceiver, uint256 salt) paymentInfo, uint256 amount)',\n 'function refundInEscrow(tuple(address operator, address payer, address receiver, address token, uint120 maxAmount, uint48 preApprovalExpiry, uint48 authorizationExpiry, uint48 refundExpiry, uint16 minFeeBps, uint16 maxFeeBps, address feeReceiver, uint256 salt) paymentInfo, uint120 amount)',\n 'function charge(tuple(address operator, address payer, address receiver, address token, uint120 maxAmount, uint48 preApprovalExpiry, uint48 authorizationExpiry, uint48 refundExpiry, uint16 minFeeBps, uint16 maxFeeBps, address feeReceiver, uint256 salt) paymentInfo, uint256 amount, address tokenCollector, bytes collectorData)',\n 'function refundPostEscrow(tuple(address operator, address payer, address receiver, address token, uint120 maxAmount, uint48 preApprovalExpiry, uint48 authorizationExpiry, uint48 refundExpiry, uint16 minFeeBps, uint16 maxFeeBps, address feeReceiver, uint256 salt) paymentInfo, uint256 amount, address tokenCollector, bytes collectorData)',\n];\n\n/**\n * CREATE3-deployed operators (SKALE, future chains) use updated ABI with extra `bytes data` param\n * on release() and refundInEscrow(). Pass empty bytes (0x) for the data parameter.\n */\nexport const OPERATOR_ABI_CREATE3 = [\n 'function release(tuple(address operator, address payer, address receiver, address token, uint120 maxAmount, uint48 preApprovalExpiry, uint48 authorizationExpiry, uint48 refundExpiry, uint16 minFeeBps, uint16 maxFeeBps, address feeReceiver, uint256 salt) paymentInfo, uint256 amount, bytes data)',\n 'function refundInEscrow(tuple(address operator, address payer, address receiver, address token, uint120 maxAmount, uint48 preApprovalExpiry, uint48 authorizationExpiry, uint48 refundExpiry, uint16 minFeeBps, uint16 maxFeeBps, address feeReceiver, uint256 salt) paymentInfo, uint120 amount, bytes data)',\n 'function charge(tuple(address operator, address payer, address receiver, address token, uint120 maxAmount, uint48 preApprovalExpiry, uint48 authorizationExpiry, uint48 refundExpiry, uint16 minFeeBps, uint16 maxFeeBps, address feeReceiver, uint256 salt) paymentInfo, uint256 amount, address tokenCollector, bytes collectorData)',\n 'function refundPostEscrow(tuple(address operator, address payer, address receiver, address token, uint120 maxAmount, uint48 preApprovalExpiry, uint48 authorizationExpiry, uint48 refundExpiry, uint16 minFeeBps, uint16 maxFeeBps, address feeReceiver, uint256 salt) paymentInfo, uint256 amount, address tokenCollector, bytes collectorData)',\n];\n\n/** Chain IDs using CREATE3-deployed operators with updated ABI */\nconst CREATE3_CHAIN_IDS = new Set([1187947933]);\n\n/**\n * AdvancedEscrowClient provides the 5 Advanced Escrow flows via the\n * PaymentOperator contract on 9 supported EVM networks.\n *\n * Supported chains: Base (8453), Base Sepolia (84532), Ethereum (1),\n * Ethereum Sepolia (11155111), Polygon (137), Arbitrum (42161),\n * Optimism (10), Celo (42220), Monad (143), Avalanche (43114).\n *\n * Contract addresses are auto-resolved from the chain ID.\n * Pass custom contracts to override.\n *\n * Two signer modes (v2.36.0+):\n * - **Legacy**: Pass an ethers.Signer as the first argument.\n * - **OWS Wallet**: Pass a SigningWalletAdapter via `options.wallet`.\n * The adapter signs transactions offline (no raw private key needed).\n * Requires `rpcUrl` for transaction building and broadcast.\n *\n * @example Legacy mode (ethers.Signer)\n * ```typescript\n * import { ethers } from 'ethers';\n * import { AdvancedEscrowClient } from 'uvd-x402-sdk/backend';\n *\n * const provider = new ethers.JsonRpcProvider('https://mainnet.base.org');\n * const signer = new ethers.Wallet(process.env.KEY!, provider);\n * const client = new AdvancedEscrowClient(signer, { chainId: 8453 });\n * ```\n *\n * @example OWS Wallet mode (SigningWalletAdapter)\n * ```typescript\n * import { OWSWalletAdapter } from 'uvd-x402-sdk';\n * import { AdvancedEscrowClient } from 'uvd-x402-sdk/backend';\n *\n * const wallet = new OWSWalletAdapter(owsWallet);\n * const client = new AdvancedEscrowClient(null, {\n * wallet,\n * rpcUrl: 'https://mainnet.base.org',\n * chainId: 8453,\n * });\n * await client.init();\n *\n * const pi = client.buildPaymentInfo('0xWorker...', '5000000', 'standard');\n * const auth = await client.authorize(pi);\n * const release = await client.release(pi);\n * ```\n */\nexport class AdvancedEscrowClient {\n private facilitatorUrl: string;\n private chainId: number;\n private gasLimit: number;\n private readonly timeout: number;\n private readonly retries: number | undefined;\n private contracts: AdvancedEscrowContracts;\n private signer: any; // ethers.Signer (legacy mode)\n private walletAdapter: import('../wallet').SigningWalletAdapter | null; // OWS mode (v2.36.0+)\n private rpcUrl: string | undefined;\n private payerAddress: string = '';\n\n /**\n * Create an AdvancedEscrowClient.\n *\n * Two modes of operation:\n *\n * 1. **Legacy (ethers.Signer)**: Pass an ethers Signer as the first argument.\n * ```ts\n * const client = new AdvancedEscrowClient(signer, { rpcUrl, chainId });\n * ```\n *\n * 2. **OWS Wallet (SigningWalletAdapter)**: Pass `wallet` in options. The\n * first argument is ignored (pass `null`). Requires `rpcUrl` for on-chain\n * transaction building and broadcast.\n * ```ts\n * const wallet = new OWSWalletAdapter(owsWallet);\n * const client = new AdvancedEscrowClient(null, { wallet, rpcUrl, chainId });\n * ```\n *\n * @param signer - ethers.Signer instance (ignored when options.wallet is set)\n * @param options - Configuration options\n */\n constructor(signer: any, options: AdvancedEscrowClientOptions = {}) {\n this.walletAdapter = options.wallet || null;\n this.signer = this.walletAdapter ? null : signer;\n this.rpcUrl = options.rpcUrl;\n this.facilitatorUrl = (options.facilitatorUrl || 'https://facilitator.ultravioletadao.xyz').replace(/\\/$/, '');\n this.chainId = options.chainId || 8453;\n this.gasLimit = options.gasLimit || 300000;\n this.timeout = options.timeout || ESCROW_TIMEOUT_MS[this.chainId] || DEFAULT_ESCROW_TIMEOUT_MS;\n this.retries = options.retries;\n\n if (this.walletAdapter && !this.rpcUrl) {\n throw new Error(\n 'AdvancedEscrowClient: rpcUrl is required when using a SigningWalletAdapter. ' +\n 'The adapter signs transactions offline; an RPC provider is needed to build ' +\n 'and broadcast them.'\n );\n }\n\n if (options.contracts) {\n this.contracts = options.contracts;\n } else {\n const resolved = ESCROW_CONTRACTS[this.chainId];\n if (!resolved) {\n throw new Error(\n `No escrow contracts found for chain ID ${this.chainId}. ` +\n `Supported chains: ${getEscrowSupportedChainIds().join(', ')}. ` +\n `Pass custom contracts via options.contracts to use an unsupported chain.`\n );\n }\n this.contracts = resolved;\n }\n }\n\n /**\n * Initialize the client (resolves payer address).\n * Call this before using any methods.\n */\n async init(): Promise<void> {\n if (this.walletAdapter) {\n this.payerAddress = this.walletAdapter.getAddress();\n } else {\n this.payerAddress = await this.signer.getAddress();\n }\n }\n\n /**\n * Build a PaymentInfo struct with appropriate timing for the task tier.\n *\n * @param receiver - Worker's wallet address\n * @param amount - Amount in token atomic units (e.g., '5000000' for $5 USDC)\n * @param tier - Task tier determines timing parameters\n * @param salt - Random salt (auto-generated if not provided)\n */\n buildPaymentInfo(\n receiver: string,\n amount: string,\n tier: AdvancedEscrowTaskTier = 'standard',\n salt?: string,\n opts?: {\n deadline?: number;\n reviewWindowSec?: number;\n /**\n * Fee bounds to sign, in basis points. Default\n * {@link DEFAULT_MIN_FEE_BPS} / {@link DEFAULT_MAX_FEE_BPS}. Override\n * only against an operator whose fee you have actually read on-chain —\n * `maxFeeBps` is a CEILING, so a value under the operator's own fee does\n * not shave the fee, it reverts the deposit.\n */\n minFeeBps?: number;\n maxFeeBps?: number;\n },\n ): AdvancedPaymentInfo {\n const now = Math.floor(Date.now() / 1000);\n const t = TIER_TIMINGS[tier];\n // The release window must outlast the REVIEW, not just the tier. `micro`\n // alone gives two hours; a buyer approving later gets\n // `AfterAuthorizationExpiry` on-chain — the release reverts and the worker\n // is not paid. Measured in production 2026-08-19: a release attempted 26.2\n // HOURS past expiry, 8 escrows stuck on one network in 24h.\n //\n // This comment used to add \"and only the payer's `reclaim()` can move the\n // funds\". That is FALSE and it is why those escrows were treated as lost:\n // `AuthCaptureEscrow.partialVoid` is `onlySender(operator)` — the operator\n // is the facilitator — pays the PAYER, and does not look at\n // `authorizationExpiry`. `refundViaFacilitator` reaches it with no gas and\n // no payer. Widening the window still matters: it is what pays the WORKER,\n // and a refund does not.\n //\n // buildEscrowPreAuth — the other escrow path in this same SDK — already\n // floors both windows this way and says why. This path never got the memo,\n // and it is the one the marketplace documents as recommended.\n const reviewWindow = opts?.reviewWindowSec ?? REVIEW_WINDOW_SEC;\n const reviewBase = Math.max(now, opts?.deadline ?? now);\n const authorizationExpiry = Math.max(now + t.auth, reviewBase + reviewWindow);\n const refundExpiry = Math.max(now + t.refund, authorizationExpiry + REFUND_WINDOW_SEC);\n // Use crypto-safe randomness (Node.js crypto or Web Crypto API)\n let generatedSalt = salt;\n if (!generatedSalt) {\n const bytes = new Uint8Array(32);\n if (typeof globalThis.crypto !== 'undefined' && globalThis.crypto.getRandomValues) {\n globalThis.crypto.getRandomValues(bytes);\n } else {\n // Node.js fallback\n const nodeCrypto = require('crypto');\n const buf = nodeCrypto.randomBytes(32);\n bytes.set(new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength));\n }\n generatedSalt = '0x' + Array.from(bytes).map(b => b.toString(16).padStart(2, '0')).join('');\n }\n\n // Fee bounds come from ONE place — the same constants `buildEscrowPreAuth`\n // signs — because both build the same struct for the same contracts. This\n // path used to hardcode `maxFeeBps: 800`, below the SDK's own canonical\n // OPERATOR_FEE_BPS (1300). That is not a cheaper fee: `PaymentOperator`\n // compares protocolFee + operatorFee against this ceiling and reverts with\n // `FeeBoundsIncompatible` when it does not fit, so the deposit never opens\n // and nobody is paid.\n const minFeeBps = opts?.minFeeBps ?? DEFAULT_MIN_FEE_BPS;\n const maxFeeBps = opts?.maxFeeBps ?? DEFAULT_MAX_FEE_BPS;\n if (maxFeeBps < minFeeBps) {\n throw new Error(`maxFeeBps=${maxFeeBps} is below minFeeBps=${minFeeBps}`);\n }\n if (maxFeeBps < OPERATOR_FEE_BPS) {\n // Fail here, where the caller can still choose, rather than on-chain\n // after the payer has signed. Same guard buildEscrowPreAuth applies.\n throw new Error(\n `maxFeeBps=${maxFeeBps} cannot cover the operator's ${OPERATOR_FEE_BPS} ` +\n `bps fee — the on-chain authorize would revert with FeeBoundsIncompatible. ` +\n `Read the fee off your operator before overriding it.`,\n );\n }\n\n return {\n operator: this.contracts.operator,\n receiver,\n token: this.contracts.usdc,\n maxAmount: amount,\n preApprovalExpiry: now + t.pre,\n authorizationExpiry,\n refundExpiry,\n minFeeBps,\n maxFeeBps,\n feeReceiver: this.contracts.operator,\n salt: generatedSalt,\n };\n }\n\n /**\n * Compute the correct nonce (with PAYMENT_INFO_TYPEHASH).\n * Matches the on-chain AuthCaptureEscrow nonce derivation.\n */\n private async computeNonce(paymentInfo: AdvancedPaymentInfo): Promise<string> {\n // Dynamic import of ethers to avoid hard dependency at module level\n const { ethers } = await import('ethers');\n\n const piTuple = ethers.AbiCoder.defaultAbiCoder().encode(\n ['bytes32', 'tuple(address,address,address,address,uint120,uint48,uint48,uint48,uint16,uint16,address,uint256)'],\n [\n PAYMENT_INFO_TYPEHASH,\n [\n paymentInfo.operator,\n ZERO_ADDRESS, // payer = 0 for payer-agnostic hash\n paymentInfo.receiver,\n paymentInfo.token,\n paymentInfo.maxAmount,\n paymentInfo.preApprovalExpiry,\n paymentInfo.authorizationExpiry,\n paymentInfo.refundExpiry,\n paymentInfo.minFeeBps,\n paymentInfo.maxFeeBps,\n paymentInfo.feeReceiver,\n paymentInfo.salt,\n ],\n ],\n );\n const piHash = ethers.keccak256(piTuple);\n\n const finalEncoded = ethers.AbiCoder.defaultAbiCoder().encode(\n ['uint256', 'address', 'bytes32'],\n [this.chainId, this.contracts.escrow, piHash],\n );\n return ethers.keccak256(finalEncoded);\n }\n\n /**\n * Sign ReceiveWithAuthorization for ERC-3009.\n *\n * Uses SigningWalletAdapter.signTypedData() when in OWS mode,\n * or ethers Signer.signTypedData() in legacy mode.\n */\n private async signErc3009(auth: Record<string, string>): Promise<string> {\n const domain = {\n name: USDC_DOMAIN_NAME[this.chainId] || 'USD Coin',\n version: '2',\n chainId: this.chainId,\n verifyingContract: this.contracts.usdc,\n };\n\n const types = {\n ReceiveWithAuthorization: [\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 };\n\n const message = {\n from: auth.from,\n to: auth.to,\n value: auth.value,\n validAfter: auth.validAfter,\n validBefore: auth.validBefore,\n nonce: auth.nonce,\n };\n\n // OWS wallet adapter mode: serialize to JSON and use adapter.signTypedData()\n if (this.walletAdapter) {\n const typedData = JSON.stringify({\n domain,\n types,\n primaryType: 'ReceiveWithAuthorization',\n message,\n });\n const result = await this.walletAdapter.signTypedData(typedData);\n return result.signature;\n }\n\n // Legacy ethers.Signer mode\n return this.signer.signTypedData(domain, types, message);\n }\n\n /**\n * Build the on-chain PaymentInfo tuple for contract calls.\n */\n private buildTuple(pi: AdvancedPaymentInfo): any[] {\n return [\n pi.operator,\n this.payerAddress,\n pi.receiver,\n pi.token,\n pi.maxAmount,\n pi.preApprovalExpiry,\n pi.authorizationExpiry,\n pi.refundExpiry,\n pi.minFeeBps,\n pi.maxFeeBps,\n pi.feeReceiver,\n pi.salt,\n ];\n }\n\n /**\n * AUTHORIZE: Lock funds in escrow via the facilitator.\n *\n * Sends an ERC-3009 ReceiveWithAuthorization to the facilitator,\n * which calls PaymentOperator.authorize() on-chain.\n */\n async authorize(paymentInfo: AdvancedPaymentInfo): Promise<AdvancedAuthorizationResult> {\n if (!this.payerAddress) await this.init();\n\n try {\n const nonce = await this.computeNonce(paymentInfo);\n\n const auth = {\n from: this.payerAddress,\n to: this.contracts.tokenCollector,\n value: paymentInfo.maxAmount,\n validAfter: '0',\n validBefore: String(paymentInfo.preApprovalExpiry),\n nonce,\n };\n const signature = await this.signErc3009(auth);\n\n const payload = {\n x402Version: 2,\n scheme: 'escrow',\n payload: {\n authorization: auth,\n signature,\n paymentInfo: paymentInfo,\n },\n paymentRequirements: {\n scheme: 'escrow',\n network: `eip155:${this.chainId}`,\n maxAmountRequired: paymentInfo.maxAmount,\n asset: this.contracts.usdc,\n payTo: paymentInfo.receiver,\n extra: {\n escrowAddress: this.contracts.escrow,\n operatorAddress: this.contracts.operator,\n tokenCollector: this.contracts.tokenCollector,\n },\n },\n };\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(`${this.facilitatorUrl}/settle`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(payload),\n signal: controller.signal,\n });\n clearTimeout(timeoutId);\n const result = await response.json();\n\n if (result.success) {\n return {\n success: true,\n transactionHash: result.transaction,\n paymentInfo,\n salt: paymentInfo.salt,\n };\n }\n return { success: false, error: result.errorReason };\n } catch (fetchErr: any) {\n clearTimeout(timeoutId);\n\n // On timeout, check on-chain state as fallback\n if (fetchErr.name === 'AbortError') {\n try {\n const state = await this.queryEscrowState(paymentInfo);\n if (state.capturableAmount && BigInt(state.capturableAmount) > 0n) {\n return {\n success: true,\n paymentInfo,\n salt: paymentInfo.salt,\n };\n }\n } catch { /* fallback query failed, report original timeout */ }\n return { success: false, error: `Authorize timed out after ${this.timeout}ms. On-chain state could not confirm escrow lock.` };\n }\n throw fetchErr;\n }\n } catch (e: any) {\n return { success: false, error: e.message || String(e) };\n }\n }\n\n /**\n * RELEASE: Capture escrowed funds to receiver (worker gets paid).\n *\n * Calls PaymentOperator.release() -> escrow.capture()\n *\n * @param paymentInfo - PaymentInfo from the authorize step\n * @param amount - Amount to release (defaults to maxAmount)\n */\n async release(paymentInfo: AdvancedPaymentInfo, amount?: string): Promise<AdvancedTransactionResult> {\n if (!this.payerAddress) await this.init();\n\n try {\n const { ethers } = await import('ethers');\n const isCreate3 = CREATE3_CHAIN_IDS.has(this.chainId);\n const abi = isCreate3 ? OPERATOR_ABI_CREATE3 : OPERATOR_ABI;\n const amt = amount || paymentInfo.maxAmount;\n const tuple = this.buildTuple(paymentInfo);\n\n // OWS wallet adapter mode: build unsigned TX, sign via adapter, broadcast\n if (this.walletAdapter) {\n return this.sendViaAdapter(ethers, abi, (iface) => {\n return isCreate3\n ? iface.encodeFunctionData('release', [tuple, amt, '0x'])\n : iface.encodeFunctionData('release', [tuple, amt]);\n });\n }\n\n // Legacy ethers.Signer mode: contract sends directly\n const contract = new ethers.Contract(this.contracts.operator, abi, this.signer);\n const tx = isCreate3\n ? await contract.release(tuple, amt, '0x', { gasLimit: this.gasLimit })\n : await contract.release(tuple, amt, { gasLimit: this.gasLimit });\n const receipt = await tx.wait();\n\n return {\n success: receipt.status === 1,\n transactionHash: receipt.hash,\n gasUsed: Number(receipt.gasUsed),\n error: receipt.status !== 1 ? 'Transaction reverted' : undefined,\n };\n } catch (e: any) {\n return { success: false, error: e.message || String(e) };\n }\n }\n\n /**\n * REFUND IN ESCROW: Return escrowed funds to payer (cancel task).\n *\n * Calls PaymentOperator.refundInEscrow() -> escrow.partialVoid()\n *\n * @param paymentInfo - PaymentInfo from the authorize step\n * @param amount - Amount to refund (defaults to maxAmount)\n */\n async refundInEscrow(paymentInfo: AdvancedPaymentInfo, amount?: string): Promise<AdvancedTransactionResult> {\n if (!this.payerAddress) await this.init();\n\n try {\n const { ethers } = await import('ethers');\n const isCreate3 = CREATE3_CHAIN_IDS.has(this.chainId);\n const abi = isCreate3 ? OPERATOR_ABI_CREATE3 : OPERATOR_ABI;\n const amt = amount || paymentInfo.maxAmount;\n const tuple = this.buildTuple(paymentInfo);\n\n // OWS wallet adapter mode: build unsigned TX, sign via adapter, broadcast\n if (this.walletAdapter) {\n return this.sendViaAdapter(ethers, abi, (iface) => {\n return isCreate3\n ? iface.encodeFunctionData('refundInEscrow', [tuple, amt, '0x'])\n : iface.encodeFunctionData('refundInEscrow', [tuple, amt]);\n });\n }\n\n // Legacy ethers.Signer mode\n const contract = new ethers.Contract(this.contracts.operator, abi, this.signer);\n const tx = isCreate3\n ? await contract.refundInEscrow(tuple, amt, '0x', { gasLimit: this.gasLimit })\n : await contract.refundInEscrow(tuple, amt, { gasLimit: this.gasLimit });\n const receipt = await tx.wait();\n\n return {\n success: receipt.status === 1,\n transactionHash: receipt.hash,\n gasUsed: Number(receipt.gasUsed),\n error: receipt.status !== 1 ? 'Transaction reverted' : undefined,\n };\n } catch (e: any) {\n return { success: false, error: e.message || String(e) };\n }\n }\n\n // ==========================================================================\n // GASLESS FACILITATOR METHODS\n // ==========================================================================\n\n /**\n * GASLESS RELEASE: Release escrowed funds via the facilitator.\n *\n * Instead of calling the PaymentOperator contract directly (which requires\n * gas), this sends a release request to the facilitator, which submits\n * the transaction on your behalf.\n *\n * @param paymentInfo - PaymentInfo from the authorize step\n * @param amount - Amount to release in atomic units (defaults to maxAmount)\n * @returns Transaction result from the facilitator\n *\n * @example\n * ```typescript\n * const pi = client.buildPaymentInfo('0xWorker...', '5000000', 'standard');\n * await client.authorize(pi);\n * // Worker completes task...\n * const result = await client.releaseViaFacilitator(pi);\n * console.log(result.transactionHash);\n * ```\n *\n * @example Signed release (the payer proves the release is theirs to ask for)\n * ```typescript\n * await client.releaseViaFacilitator(pi, undefined, {\n * lifecycleSigner: payerWallet, // EnvKeyAdapter, OWS, wagmiLifecycleSigner(...)\n * });\n * ```\n *\n * @example Transporting an order the publisher signed in their browser\n * ```typescript\n * // The browser sent back a signature over a document THIS backend built.\n * const lifecycleAuth = lifecycleAuthFromSignature(typedData, signature, payer);\n * await client.releaseViaFacilitator(pi, amount, { lifecycleAuth });\n * ```\n */\n async releaseViaFacilitator(\n paymentInfo: AdvancedPaymentInfo,\n amount?: string,\n options?: LifecycleAuthOptions,\n ): Promise<AdvancedTransactionResult> {\n if (!this.payerAddress) await this.init();\n\n try {\n const wirePaymentInfo = {\n operator: paymentInfo.operator,\n receiver: paymentInfo.receiver,\n token: paymentInfo.token,\n maxAmount: paymentInfo.maxAmount,\n preApprovalExpiry: paymentInfo.preApprovalExpiry,\n authorizationExpiry: paymentInfo.authorizationExpiry,\n refundExpiry: paymentInfo.refundExpiry,\n minFeeBps: paymentInfo.minFeeBps,\n maxFeeBps: paymentInfo.maxFeeBps,\n feeReceiver: paymentInfo.feeReceiver,\n salt: paymentInfo.salt,\n };\n const releaseAmount = amount || paymentInfo.maxAmount;\n\n // The signed lifecycle order: signed here from a `lifecycleSigner`, or\n // handed over already signed as `lifecycleAuth`. With NEITHER the payload\n // goes out byte-for-byte as it did before — the facilitator's default\n // mode does not look at the field at all.\n const lifecycleAuth = await resolveLifecycleAuth('release', options, {\n paymentInfo: wirePaymentInfo,\n payer: this.payerAddress,\n amount: releaseAmount,\n chainId: this.chainId,\n });\n\n const payload = {\n x402Version: 2,\n scheme: 'escrow',\n action: 'release',\n payload: {\n paymentInfo: wirePaymentInfo,\n payer: this.payerAddress,\n amount: releaseAmount,\n ...(lifecycleAuth ? { lifecycleAuth } : {}),\n },\n paymentRequirements: {\n scheme: 'escrow',\n network: `eip155:${this.chainId}`,\n extra: {\n escrowAddress: this.contracts.escrow,\n operatorAddress: this.contracts.operator,\n tokenCollector: this.contracts.tokenCollector,\n },\n },\n };\n\n try {\n // A 503 from the writer lease is NOT a refused release. The facilitator\n // never reached the chain, so the escrow still holds every token and\n // the same request is the right thing to send again. Reading it as a\n // refusal is how a recoverable escrow gets written off.\n const { response, error } = await facilitatorFetch(\n `${this.facilitatorUrl}/settle`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(payload),\n },\n { timeoutMs: this.timeout, retries: this.retries },\n );\n if (error) {\n return { success: false, error: error.error, ...failureFields(error) };\n }\n const result = await response.json();\n\n if (result.success) {\n return {\n success: true,\n transactionHash: result.transaction || result.transactionHash || result.transaction_hash,\n };\n }\n // Parity with the Python SDK (2026-08-22): a last-resort message that\n // says only \"Release failed\" is the same dead end as an empty string —\n // name the status and what the body DID carry so the caller has a\n // thread to pull. Divergence between the two SDKs is exactly what let\n // the escrow-window bug live in one of them for weeks.\n return {\n success: false,\n error:\n result.errorReason ||\n result.error ||\n `Release refused with no reason (HTTP ${response.status}, body keys: ${Object.keys(result ?? {}).sort().join(', ') || 'none'})`,\n };\n } catch (fetchErr: any) {\n // On timeout, check on-chain state as fallback\n if (fetchErr.name === 'AbortError') {\n try {\n const state = await this.queryEscrowState(paymentInfo);\n if (state.capturableAmount === '0' && state.hasCollectedPayment) {\n return { success: true };\n }\n } catch { /* fallback query failed */ }\n return { success: false, error: `Gasless release timed out after ${this.timeout}ms. Check escrow state on-chain.` };\n }\n throw fetchErr;\n }\n } catch (e: any) {\n return { success: false, error: e.message || String(e) };\n }\n }\n\n /**\n * GASLESS REFUND: return escrowed funds to the payer via the facilitator.\n *\n * Sends `action: \"refundInEscrow\"` to `POST /settle`; the facilitator's\n * PaymentOperator calls `AuthCaptureEscrow.partialVoid`.\n *\n * # This is how an EXPIRED escrow is recovered\n *\n * A widely repeated claim — including in this SDK's own comments until now —\n * says that once `authorizationExpiry` passes, only the payer's `reclaim()`\n * can move the funds. **That is false, and believing it has left real money\n * stranded.**\n *\n * Read the contract (`AuthCaptureEscrow.sol`):\n *\n * - `partialVoid` is `onlySender(paymentInfo.operator)` — the operator is the\n * FACILITATOR, not the payer — it sends the tokens **to the payer**, and it\n * **does not check `authorizationExpiry` at all**. It works before expiry\n * and after it, and the payer never has to appear.\n * - `reclaim` is `onlySender(paymentInfo.payer)` and only after expiry. It is\n * a payer's self-service escape hatch, which is why this facilitator does\n * not expose it — **not** the only way out.\n *\n * So a release that reverted with `AfterAuthorizationExpiry` is recoverable\n * from here, with no gas and no cooperation from the payer. Get the amount\n * from {@link queryEscrowState}'s `capturableAmount`.\n *\n * # A refusal that is not a refusal\n *\n * Check `retryable` before writing an escrow off. A `503` means the\n * facilitator never reached the chain — the escrow is untouched and the same\n * request should be sent again.\n *\n * @param paymentInfo - PaymentInfo from the authorize step\n * @param amount - Amount to refund in atomic units (defaults to maxAmount).\n * For a stuck escrow pass `capturableAmount` from {@link queryEscrowState}.\n * @returns Transaction result from the facilitator\n *\n * @example Recovering an escrow whose release window already closed\n * ```typescript\n * const state = await client.queryEscrowState(pi);\n * if (state.capturableAmount !== '0') {\n * // No payer needed, no gas, and expiry is irrelevant to partialVoid.\n * const result = await client.refundViaFacilitator(pi, state.capturableAmount);\n * if (!result.success && result.retryable) {\n * // No verdict was reached. The funds are still there; send it again.\n * }\n * }\n * ```\n */\n async refundViaFacilitator(\n paymentInfo: AdvancedPaymentInfo,\n amount?: string,\n options?: LifecycleAuthOptions,\n ): Promise<AdvancedTransactionResult> {\n if (!this.payerAddress) await this.init();\n\n try {\n const wirePaymentInfo = {\n operator: paymentInfo.operator,\n receiver: paymentInfo.receiver,\n token: paymentInfo.token,\n maxAmount: paymentInfo.maxAmount,\n preApprovalExpiry: paymentInfo.preApprovalExpiry,\n authorizationExpiry: paymentInfo.authorizationExpiry,\n refundExpiry: paymentInfo.refundExpiry,\n minFeeBps: paymentInfo.minFeeBps,\n maxFeeBps: paymentInfo.maxFeeBps,\n feeReceiver: paymentInfo.feeReceiver,\n salt: paymentInfo.salt,\n };\n const refundAmount = amount || paymentInfo.maxAmount;\n\n // Same optional order as `releaseViaFacilitator`, with the caveat that\n // the accepted signers differ: the receiver, the operator owner, or the\n // payer once `authorizationExpiry` has passed.\n const lifecycleAuth = await resolveLifecycleAuth('refundInEscrow', options, {\n paymentInfo: wirePaymentInfo,\n payer: this.payerAddress,\n amount: refundAmount,\n chainId: this.chainId,\n });\n\n const payload = {\n x402Version: 2,\n scheme: 'escrow',\n action: 'refundInEscrow',\n payload: {\n paymentInfo: wirePaymentInfo,\n payer: this.payerAddress,\n amount: refundAmount,\n ...(lifecycleAuth ? { lifecycleAuth } : {}),\n },\n paymentRequirements: {\n scheme: 'escrow',\n network: `eip155:${this.chainId}`,\n extra: {\n escrowAddress: this.contracts.escrow,\n operatorAddress: this.contracts.operator,\n tokenCollector: this.contracts.tokenCollector,\n },\n },\n };\n\n try {\n // The non-2xx branch used to be missing entirely: `response.json()` on\n // a 503 body yields `{error, reason}`, `result.success` is undefined,\n // and the refund was reported as failed. That is a recoverable escrow\n // declared lost on a facilitator hiccup.\n const { response, error } = await facilitatorFetch(\n `${this.facilitatorUrl}/settle`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(payload),\n },\n { timeoutMs: this.timeout, retries: this.retries },\n );\n if (error) {\n return { success: false, error: error.error, ...failureFields(error) };\n }\n const result = await response.json();\n\n if (result.success) {\n return {\n success: true,\n transactionHash: result.transaction || result.transactionHash || result.transaction_hash,\n };\n }\n return {\n success: false,\n error:\n result.errorReason ||\n result.error ||\n `Refund refused with no reason (HTTP ${response.status}, body keys: ${Object.keys(result ?? {}).sort().join(', ') || 'none'})`,\n };\n } catch (fetchErr: any) {\n // On timeout, check on-chain state as fallback\n if (fetchErr.name === 'AbortError') {\n try {\n const state = await this.queryEscrowState(paymentInfo);\n if (state.refundableAmount === '0') {\n return { success: true };\n }\n } catch { /* fallback query failed */ }\n return { success: false, error: `Gasless refund timed out after ${this.timeout}ms. Check escrow state on-chain.` };\n }\n throw fetchErr;\n }\n } catch (e: any) {\n return { success: false, error: e.message || String(e) };\n }\n }\n\n /**\n * QUERY ESCROW STATE: Read on-chain escrow state via the facilitator.\n *\n * This is a read-only operation that queries the facilitator for the\n * current escrow state without requiring gas or a signer.\n *\n * @param paymentInfo - PaymentInfo to query state for\n * @returns Escrow state including capturable/refundable amounts\n *\n * @example\n * ```typescript\n * const pi = client.buildPaymentInfo('0xWorker...', '5000000', 'standard');\n * await client.authorize(pi);\n *\n * const state = await client.queryEscrowState(pi);\n * console.log(`Capturable: ${state.capturableAmount}`);\n * console.log(`Refundable: ${state.refundableAmount}`);\n * console.log(`Already collected: ${state.hasCollectedPayment}`);\n * ```\n */\n async queryEscrowState(paymentInfo: AdvancedPaymentInfo): Promise<EscrowStateResponse> {\n if (!this.payerAddress) await this.init();\n\n const payload = {\n paymentInfo: {\n operator: paymentInfo.operator,\n receiver: paymentInfo.receiver,\n token: paymentInfo.token,\n maxAmount: paymentInfo.maxAmount,\n preApprovalExpiry: paymentInfo.preApprovalExpiry,\n authorizationExpiry: paymentInfo.authorizationExpiry,\n refundExpiry: paymentInfo.refundExpiry,\n minFeeBps: paymentInfo.minFeeBps,\n maxFeeBps: paymentInfo.maxFeeBps,\n feeReceiver: paymentInfo.feeReceiver,\n salt: paymentInfo.salt,\n },\n payer: this.payerAddress,\n network: `eip155:${this.chainId}`,\n extra: {\n escrowAddress: this.contracts.escrow,\n operatorAddress: this.contracts.operator,\n tokenCollector: this.contracts.tokenCollector,\n },\n };\n\n const response = await fetch(`${this.facilitatorUrl}/escrow/state`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Escrow state query failed: ${response.status} - ${errorText}`);\n }\n\n return await response.json() as EscrowStateResponse;\n }\n\n /**\n * CHARGE: Direct instant payment (no escrow hold).\n *\n * Calls PaymentOperator.charge() -> escrow.charge()\n * Funds go directly from payer to receiver.\n *\n * @param paymentInfo - PaymentInfo with receiver and amount\n * @param amount - Amount to charge (defaults to maxAmount)\n */\n async charge(paymentInfo: AdvancedPaymentInfo, amount?: string): Promise<AdvancedTransactionResult> {\n if (!this.payerAddress) await this.init();\n\n try {\n const { ethers } = await import('ethers');\n const nonce = await this.computeNonce(paymentInfo);\n const amt = amount || paymentInfo.maxAmount;\n\n const auth = {\n from: this.payerAddress,\n to: this.contracts.tokenCollector,\n value: String(amt),\n validAfter: '0',\n validBefore: String(paymentInfo.preApprovalExpiry),\n nonce,\n };\n const signature = await this.signErc3009(auth);\n // Pass raw signature bytes as collectorData (ethers handles hex -> bytes)\n const collectorData = ethers.getBytes(signature);\n\n const tuple = this.buildTuple(paymentInfo);\n\n // OWS wallet adapter mode\n if (this.walletAdapter) {\n return this.sendViaAdapter(ethers, OPERATOR_ABI, (iface) => {\n return iface.encodeFunctionData('charge', [\n tuple, amt, this.contracts.tokenCollector, collectorData,\n ]);\n });\n }\n\n // Legacy ethers.Signer mode\n const contract = new ethers.Contract(this.contracts.operator, OPERATOR_ABI, this.signer);\n const tx = await contract.charge(\n tuple,\n amt,\n this.contracts.tokenCollector,\n collectorData,\n { gasLimit: this.gasLimit },\n );\n const receipt = await tx.wait();\n\n return {\n success: receipt.status === 1,\n transactionHash: receipt.hash,\n gasUsed: Number(receipt.gasUsed),\n error: receipt.status !== 1 ? 'Transaction reverted' : undefined,\n };\n } catch (e: any) {\n return { success: false, error: e.message || String(e) };\n }\n }\n\n /**\n * REFUND POST ESCROW: Dispute refund after funds were released.\n *\n * Calls PaymentOperator.refundPostEscrow() -> escrow.refund()\n *\n * WARNING: NOT FUNCTIONAL IN PRODUCTION (as of 2026-02-03).\n * The protocol team has not implemented the required tokenCollector\n * contract. This call will fail on-chain.\n *\n * For dispute resolution, use refundInEscrow() instead: keep funds\n * in escrow and refund before releasing. This guarantees funds are\n * available and under arbiter control.\n *\n * Kept for future use when tokenCollector is implemented.\n *\n * @param paymentInfo - PaymentInfo from the original authorization\n * @param amount - Amount to refund (defaults to maxAmount)\n * @param tokenCollector - Address of token collector for refund sourcing\n * @param collectorData - Data for the token collector\n */\n async refundPostEscrow(\n paymentInfo: AdvancedPaymentInfo,\n amount?: string,\n tokenCollector?: string,\n collectorData?: string,\n ): Promise<AdvancedTransactionResult> {\n if (!this.payerAddress) await this.init();\n\n try {\n const { ethers } = await import('ethers');\n const amt = amount || paymentInfo.maxAmount;\n const tuple = this.buildTuple(paymentInfo);\n\n // OWS wallet adapter mode\n if (this.walletAdapter) {\n return this.sendViaAdapter(ethers, OPERATOR_ABI, (iface) => {\n return iface.encodeFunctionData('refundPostEscrow', [\n tuple, amt, tokenCollector || ZERO_ADDRESS, collectorData || '0x',\n ]);\n });\n }\n\n // Legacy ethers.Signer mode\n const contract = new ethers.Contract(this.contracts.operator, OPERATOR_ABI, this.signer);\n const tx = await contract.refundPostEscrow(\n tuple,\n amt,\n tokenCollector || ZERO_ADDRESS,\n collectorData || '0x',\n { gasLimit: this.gasLimit },\n );\n const receipt = await tx.wait();\n\n return {\n success: receipt.status === 1,\n transactionHash: receipt.hash,\n gasUsed: Number(receipt.gasUsed),\n error: receipt.status !== 1 ? 'Transaction reverted' : undefined,\n };\n } catch (e: any) {\n return { success: false, error: e.message || String(e) };\n }\n }\n\n // ==========================================================================\n // INTERNAL: Adapter-based transaction signing and broadcast\n // ==========================================================================\n\n /**\n * Build an unsigned transaction, sign via SigningWalletAdapter, and broadcast.\n *\n * Used by release(), refundInEscrow(), charge(), refundPostEscrow() when\n * operating in OWS wallet adapter mode. The adapter signs the serialized\n * transaction offline; the RPC provider broadcasts the signed raw TX.\n *\n * @param ethersModule - ethers namespace (from `const { ethers } = await import('ethers')`)\n * @param abi - Contract ABI (OPERATOR_ABI or OPERATOR_ABI_CREATE3)\n * @param encodeCalldata - Function that encodes the calldata using the interface\n * @returns Transaction result\n */\n private async sendViaAdapter(\n ethersModule: any,\n abi: string[],\n encodeCalldata: (iface: any) => string,\n ): Promise<AdvancedTransactionResult> {\n const provider = new ethersModule.JsonRpcProvider(this.rpcUrl);\n const iface = new ethersModule.Interface(abi);\n const data = encodeCalldata(iface);\n\n // Build unsigned transaction\n const nonce = await provider.getTransactionCount(this.payerAddress);\n const feeData = await provider.getFeeData();\n\n const unsignedTx = ethersModule.Transaction.from({\n to: this.contracts.operator,\n data,\n gasLimit: this.gasLimit,\n nonce,\n chainId: this.chainId,\n maxFeePerGas: feeData.maxFeePerGas,\n maxPriorityFeePerGas: feeData.maxPriorityFeePerGas,\n type: 2, // EIP-1559\n });\n\n // Sign via adapter\n const signedTxHex = await this.walletAdapter!.signTransaction(unsignedTx.unsignedSerialized);\n\n // Broadcast\n const txResponse = await provider.broadcastTransaction(signedTxHex);\n const receipt = await txResponse.wait();\n\n return {\n success: receipt !== null && receipt.status === 1,\n transactionHash: txResponse.hash,\n gasUsed: receipt ? Number(receipt.gasUsed) : undefined,\n error: receipt && receipt.status !== 1 ? 'Transaction reverted' : undefined,\n };\n }\n}\n","/**\n * Reading a facilitator refusal as DATA instead of prose.\n *\n * # Why this file exists\n *\n * `402` and `503` say opposite things and the SDK used to collapse both into\n * `success: false` plus an English sentence.\n *\n * - **402** means the payment was REJECTED. The credential is spent; sign a new\n * authorization.\n * - **503** means NO VERDICT WAS REACHED. Nothing was rejected and nothing was\n * executed; retry the SAME credential.\n *\n * Turning a 503 into a 402 makes the buyer sign and send a second payment for a\n * money movement that was never refused — they pay twice. That is the most\n * expensive mistake this SDK can make, so every facilitator edge now reports the\n * status, the facilitator's own `reason`, and whether the request may be\n * replayed.\n *\n * # The writer lease\n *\n * The facilitator serialises every EVM write through the one process that holds\n * the EVM writer lease, because they all spend gas from the same EOA and the\n * nonce for it is allocated in memory. A task that does not hold the lease\n * forwards the request to the one that does; when it cannot, it answers\n * `503` + `Retry-After: 5` + `{\"error\": \"...\", \"reason\": \"<why>\"}`.\n *\n * The five reasons do NOT share retry semantics, which is the whole point of\n * surfacing them:\n *\n * | reason | did the write run? | replay? |\n * |----------------------------|--------------------|---------|\n * | `holder_unknown` | no | yes |\n * | `forwarding_disabled` | no | yes |\n * | `forwarded_but_not_writer` | no | yes |\n * | `body_unreadable` | no | yes |\n * | `forward_failed` | **maybe** | **no** |\n *\n * `forward_failed` is emitted after the forward was attempted: the holder may\n * have executed the write and the response been lost on the way back. It is a\n * timeout wearing a status code. Replaying a `/register` on it is exactly the\n * sequence that once minted five duplicate agents — reconcile with\n * `GET /identity/{network}/owner/{recipient}` or `getRegisterStatus` instead.\n *\n * # The two `502`s of `/settle`, which mean opposite things\n *\n * | body `error` | `Retry-After` | did the money move? | retry? |\n * |----------------------------|---------------|---------------------|-----------|\n * | `upstream_rpc_unavailable` | `30` | no, never broadcast | **yes** |\n * | `settlement_unconfirmed` | **absent** | **maybe — mined?** | **NEVER** |\n *\n * `settlement_unconfirmed` is answered after the transaction was broadcast and\n * no receipt ever arrived, so it MAY be mined. Retrying re-signs a new\n * authorization with a fresh nonce, which the chain accepts as a second,\n * perfectly valid payment for the same purchase — the buyer pays twice, in\n * exactly the case the facilitator emits it to prevent. The `transaction` hash\n * and `paymentId` travel in the body so the caller can LOOK AT THE CHAIN; they\n * are not an invitation to send it again.\n *\n * The status cannot tell the two apart, which is why this file used to get it\n * wrong: every `502` was retryable, and until `settlement_unconfirmed` existed\n * that was correct. **Branch on the body.**\n *\n * The general form of that rule — **a 5xx whose body carries a transaction hash\n * was broadcast, whatever the error is called** — is adopted from the Python\n * SDK, which has carried it as its anti-double-settle guard\n * (`uvd_x402_sdk/client.py`, `_is_retryable_settle_error`) while this one had\n * only the status to go on.\n *\n * # The `409`s of an authorization the facilitator already admitted\n *\n * On networks with durable receipts the facilitator answers a resend of an\n * admitted authorization with its ORIGINAL answer only when the resend carries\n * the purchase binding that admitted it: the same `Idempotency-Key`, or the\n * same `X-UVD-Purchase` capability. That answer is marked\n * `Idempotent-Replayed: true`. Possession of the signed payment alone is not a\n * binding, so a resend without one is refused:\n *\n * | code (`/settle` 409 `error`, `/verify` `invalidReason`) | payment state | serve it? | retry? |\n * |-----------------------------------|--------------------|-----------|------------------------------------------|\n * | `authorization_already_settled` | confirmed | **no** | no — this X-PAYMENT was already used |\n * | `authorization_in_flight` | pending / unknown | **no** | yes, the SAME request, to learn the verdict; only the admitting binding gets the original answer |\n * | `receipt_request_conflict` | another purchase | **no** | no |\n *\n * None of them is a rejection of the signature, so none may be answered `402`\n * (the buyer would sign a second payment for a purchase whose first payment\n * settled or is settling), and none is a server fault, so none is a `500`.\n * The facilitator never admits a replacement payment for any of them.\n *\n * Read from x402-rs `src/receipts/mod.rs` (`replay`, `verify`,\n * `admitted_reason`) and `docs/facilitator-receipts.md`, \"Replays of an\n * admitted authorization\" (facilitator 2.39.0).\n *\n * Source of the other shapes: x402-rs `src/handlers.rs` `writer_lease_unavailable()`\n * and `require_writer_lease()`; `SettlementUnconfirmedResponse` in\n * `src/types.rs`, built in the `IntoResponse` of `FacilitatorLocalError`.\n */\n\n/**\n * A `reason` the facilitator attaches to a writer-lease 503.\n *\n * Typed as a union for discrimination but never used to VALIDATE: the fields\n * that carry it are plain `string`, so a reason added on the server does not\n * break compilation here.\n */\nexport type WriterLeaseReason =\n | 'holder_unknown'\n | 'forwarding_disabled'\n | 'forwarded_but_not_writer'\n | 'body_unreadable'\n | 'forward_failed';\n\n/** Every writer-lease reason the facilitator emits today. */\nexport const WRITER_LEASE_REASONS: readonly WriterLeaseReason[] = [\n 'holder_unknown',\n 'forwarding_disabled',\n 'forwarded_but_not_writer',\n 'body_unreadable',\n 'forward_failed',\n];\n\n/**\n * The reasons returned BEFORE the write is handed to anyone.\n *\n * The facilitator refuses these in its router, so the request provably did not\n * execute and re-sending the identical body is safe — including a mint.\n */\nexport const REPLAYABLE_LEASE_REASONS: readonly WriterLeaseReason[] = [\n 'holder_unknown',\n 'forwarding_disabled',\n 'forwarded_but_not_writer',\n 'body_unreadable',\n];\n\n/**\n * The reason that is ambiguous: the write may already have happened.\n *\n * Still `retryable` — the credential was not rejected — but never replayed\n * automatically. Resolve it by reading state, not by re-POSTing.\n */\nexport const AMBIGUOUS_LEASE_REASONS: readonly WriterLeaseReason[] = ['forward_failed'];\n\n/**\n * The facilitator's `error` code for a settle it broadcast and could not confirm.\n *\n * The transaction may be mined. This is the one upstream failure that must\n * never be retried; reconcile with `transaction` / `paymentId` instead.\n */\nexport const SETTLEMENT_UNCONFIRMED = 'settlement_unconfirmed';\n\n/**\n * The authorization was already admitted and its payment is confirmed; this\n * request does not carry the binding that admitted it. This X-PAYMENT was\n * used: do not serve the purchase again and do not ask for a new signature.\n */\nexport const AUTHORIZATION_ALREADY_SETTLED = 'authorization_already_settled';\n\n/**\n * The authorization was already admitted and its payment is still pending or\n * unknown; this request does not carry the binding that admitted it. Resend\n * the SAME request later to learn the verdict, never a new signature. Only the\n * admitting `Idempotency-Key` or `X-UVD-Purchase` gets the original answer.\n */\nexport const AUTHORIZATION_IN_FLIGHT = 'authorization_in_flight';\n\n/**\n * The authorization, purchase capability or idempotency key already belongs\n * to a different request. Nothing was admitted and nothing will be.\n */\nexport const RECEIPT_REQUEST_CONFLICT = 'receipt_request_conflict';\n\n/** The codes of an authorization the facilitator admitted for another request. */\nexport type AdmittedAuthorizationCode =\n | typeof AUTHORIZATION_ALREADY_SETTLED\n | typeof AUTHORIZATION_IN_FLIGHT\n | typeof RECEIPT_REQUEST_CONFLICT;\n\n/**\n * Ceiling, in seconds, on how long an automatic retry will wait.\n *\n * `Retry-After` is a hint from a server that may be misconfigured. Honouring a\n * literal `Retry-After: 3600` would hang the caller's request for an hour\n * inside a function documented as returning promptly, so the header is honoured\n * only up to this bound.\n */\nexport const MAX_RETRY_AFTER_SECONDS = 15;\n\n/** Wait used when a 503 carries no usable `Retry-After`. */\nexport const DEFAULT_RETRY_AFTER_SECONDS = 5;\n\n/** How many EXTRA attempts a retryable facilitator refusal gets by default. */\nexport const DEFAULT_FACILITATOR_RETRIES = 2;\n\n/**\n * A non-2xx answer from the facilitator, kept structured.\n *\n * `error` is byte-identical to the string this SDK has always produced, so\n * callers matching on it keep working; everything else is new and optional.\n */\nexport interface FacilitatorErrorInfo {\n /** Legacy flattened message: `Facilitator error: <status> - <body>`. */\n error: string;\n /** HTTP status the facilitator answered with. */\n status: number;\n /** The facilitator's own `reason`, when the body carried one. */\n reason?: string;\n /**\n * The facilitator's machine-readable `error` code, verbatim.\n *\n * Some codes carry a `(ref: <uuid>)` suffix, so compare with care —\n * {@link SETTLEMENT_UNCONFIRMED} is emitted bare. Branch on this rather than\n * on the status: `/settle` has two `502`s that mean opposite things.\n */\n errorCode?: string;\n /**\n * The hash of a transaction that WAS broadcast, in that chain's own encoding.\n *\n * Present on {@link SETTLEMENT_UNCONFIRMED}. Not always `0x`-prefixed:\n * Algorand prints base32 and Solana base58, and reformatting it makes it\n * unpasteable in an explorer — which is the entire remedy on offer.\n */\n transaction?: string;\n /** `keccak256(caip2 ‖ txHash)`, the same id a successful settle would print. */\n paymentId?: string;\n /**\n * Seconds to wait before retrying, already clamped to\n * {@link MAX_RETRY_AFTER_SECONDS}. Absent when the answer is not retryable.\n */\n retryAfterSeconds?: number;\n /**\n * The request reached no verdict; the credential is untouched and the SAME\n * request may be sent again. Never surface this as a payment rejection.\n */\n retryable: boolean;\n /**\n * The facilitator NAMED a reason that proves it executed nothing, so an\n * automatic replay cannot double-write.\n *\n * False for `forward_failed`, whose write may already have landed, and false\n * for an unattributed 5xx from a proxy — \"something in front answered\" is not\n * evidence that nothing ran.\n */\n safeToReplay: boolean;\n /** Raw response body, for logs. */\n body: string;\n}\n\n/** Fields every facilitator response type gained so a 503 stops looking terminal. */\nexport interface FacilitatorFailureFields {\n /** HTTP status, when the failure was transport-level rather than a verdict. */\n status?: number;\n /** The facilitator's `reason` for the refusal (see {@link WriterLeaseReason}). */\n reason?: string;\n /** The facilitator's machine-readable `error` code (see {@link FacilitatorErrorInfo.errorCode}). */\n errorCode?: string;\n /**\n * A transaction that WAS broadcast and could not be confirmed. Look it up on\n * chain; do NOT send the payment again. See {@link SETTLEMENT_UNCONFIRMED}.\n */\n transaction?: string;\n /** The payment id for that transaction, identical to the one a settle prints. */\n paymentId?: string;\n /** True when the same request may be sent again without re-signing anything. */\n retryable?: boolean;\n /** Seconds to wait before retrying, clamped to {@link MAX_RETRY_AFTER_SECONDS}. */\n retryAfterSeconds?: number;\n /** True when the facilitator provably executed nothing. */\n safeToReplay?: boolean;\n}\n\n/** A 503/429 that carries a reason known to be pre-execution. */\nexport function isReplayableLeaseReason(reason?: string): boolean {\n return REPLAYABLE_LEASE_REASONS.includes(reason as WriterLeaseReason);\n}\n\n/** A 503 whose write may already have run. Reconcile, do not re-POST. */\nexport function isAmbiguousLeaseReason(reason?: string): boolean {\n return AMBIGUOUS_LEASE_REASONS.includes(reason as WriterLeaseReason);\n}\n\n/**\n * Read `Retry-After` and clamp it.\n *\n * Tolerates a `Response`-shaped object with no `headers` at all: test doubles\n * and non-standard fetch polyfills routinely omit it, and throwing there would\n * turn a readable refusal into an unreadable crash.\n */\nexport function parseRetryAfterSeconds(response: {\n headers?: { get?: (name: string) => string | null };\n}): number | undefined {\n let raw: string | null | undefined;\n try {\n raw = response?.headers?.get?.('retry-after');\n } catch {\n return undefined;\n }\n if (raw === null || raw === undefined || raw === '') return undefined;\n const seconds = Number(raw);\n if (!Number.isFinite(seconds) || seconds < 0) return undefined;\n return Math.min(seconds, MAX_RETRY_AFTER_SECONDS);\n}\n\n/** Everything this SDK reads out of a facilitator error body. */\nexport interface ParsedFacilitatorErrorBody {\n /** The `error` code, verbatim. */\n errorCode?: string;\n /** The writer-lease `reason`. */\n reason?: string;\n /** A broadcast transaction hash, in its own chain's encoding. */\n transaction?: string;\n /** The payment id for that hash. */\n paymentId?: string;\n /**\n * The facilitator's OWN retry verdict, when it stated one.\n *\n * `undefined` on every body that does not carry the field — which is most of\n * them, so absence means \"the facilitator did not say\", never \"no\".\n */\n retryable?: boolean;\n}\n\n/** A body field is only usable when it is a non-empty string. */\nfunction stringField(source: Record<string, unknown>, key: string): string | undefined {\n const value = source[key];\n return typeof value === 'string' && value !== '' ? value : undefined;\n}\n\n/**\n * Find a broadcast transaction hash anywhere the facilitator spells one.\n *\n * All five spellings, because the endpoint and the error path disagree:\n * `{\"transaction\": \"0x…\"}`, `{\"transaction\": {\"hash\": \"0x…\"}}`, `txHash`,\n * `tx_hash`, `transaction_hash`. `settle()` already read three of them on the\n * SUCCESS path — after a consumer failed closed on an unreadable receipt and\n * revoked access to a payment that had settled — and the error path reading\n * fewer is the same defect with the stakes reversed.\n *\n * Ported from the Python SDK's `_extract_tx_hash_from_body`\n * (`uvd_x402_sdk/client.py`), which had the wider read first.\n */\nfunction transactionHashIn(source: Record<string, unknown>): string | undefined {\n const tx = source.transaction;\n if (tx && typeof tx === 'object') {\n const hash = (tx as Record<string, unknown>).hash;\n if (typeof hash === 'string' && hash !== '') return hash;\n }\n if (typeof tx === 'string' && tx !== '') return tx;\n for (const key of ['txHash', 'tx_hash', 'transaction_hash']) {\n const value = stringField(source, key);\n if (value !== undefined) return value;\n }\n return undefined;\n}\n\n/**\n * Read a JSON error body, tolerating anything that is not one.\n *\n * Exported so {@link FacilitatorErrorInfo} and `Erc8004LookupError` read the\n * SAME fields the same way. Two subtly different parses of the same body is how\n * one code path stops honouring a `retryable: false` the other one honours.\n */\nexport function parseFacilitatorErrorBody(body: string): ParsedFacilitatorErrorBody {\n let parsed: Record<string, unknown>;\n try {\n parsed = JSON.parse(body) as Record<string, unknown>;\n } catch {\n /* an HTML 503 from a load balancer is still a 503 */\n return {};\n }\n if (!parsed || typeof parsed !== 'object') return {};\n return {\n errorCode: stringField(parsed, 'error'),\n reason: stringField(parsed, 'reason'),\n transaction: transactionHashIn(parsed),\n paymentId: stringField(parsed, 'paymentId'),\n retryable: typeof parsed.retryable === 'boolean' ? parsed.retryable : undefined,\n };\n}\n\n/**\n * The facilitator said, or showed, that this refusal must not be retried.\n *\n * THREE independent signals, because the cost of missing one is a second\n * payment for the same purchase:\n *\n * 1. an explicit `retryable: false` — the facilitator answering the question;\n * 2. the named code {@link SETTLEMENT_UNCONFIRMED};\n * 3. **any 5xx body that carries a transaction hash at all.** A hash in a\n * failure means the facilitator got as far as BROADCASTING before it failed,\n * whatever it decided to call the error. This one is the general rule and it\n * holds for codes that do not exist yet.\n *\n * Signal 3 is adopted from the Python SDK, whose `_is_retryable_settle_error`\n * has carried it as the anti-double-settle guard while this SDK had only the\n * status to go on (`uvd_x402_sdk/client.py`). It is deliberately kept ALONGSIDE\n * the first two rather than replacing them: a facilitator that answers\n * `retryable: false` with no hash must still be obeyed.\n */\nfunction isDeclaredUnretryable(parsed: ParsedFacilitatorErrorBody): boolean {\n return (\n parsed.retryable === false ||\n parsed.errorCode === SETTLEMENT_UNCONFIRMED ||\n parsed.transaction !== undefined\n );\n}\n\n/**\n * This refusal reports a transaction that may already be mined.\n *\n * The caller's move is to look up `transaction` / `paymentId` on chain. Sending\n * the payment again is the double-charge.\n */\nexport function isSettlementUnconfirmed(failure: {\n errorCode?: string;\n}): boolean {\n return failure.errorCode === SETTLEMENT_UNCONFIRMED;\n}\n\n/**\n * This payment authorization was already used for another request.\n *\n * True for {@link AUTHORIZATION_ALREADY_SETTLED} and\n * {@link RECEIPT_REQUEST_CONFLICT}, on `/settle` and on `/verify` alike. Do not\n * serve the purchase again, and do not answer `402`: the buyer's payment was\n * not refused, and a new signature would pay a second time.\n */\nexport function isAuthorizationAlreadyUsed(failure: { errorCode?: string }): boolean {\n return (\n failure.errorCode === AUTHORIZATION_ALREADY_SETTLED ||\n failure.errorCode === RECEIPT_REQUEST_CONFLICT\n );\n}\n\n/**\n * This payment authorization is being settled for another request.\n *\n * `retryable` is true: the same request may be resent to learn the verdict.\n * The purchase is served only to the binding that admitted it.\n */\nexport function isAuthorizationInFlight(failure: { errorCode?: string }): boolean {\n return failure.errorCode === AUTHORIZATION_IN_FLIGHT;\n}\n\n/**\n * Turn a non-2xx facilitator response into {@link FacilitatorErrorInfo}.\n *\n * Reads the body exactly once. The `error` string keeps the historical format\n * verbatim; reformatting it would break callers that match on it.\n */\nexport async function readFacilitatorError(response: {\n status: number;\n text: () => Promise<string>;\n headers?: { get?: (name: string) => string | null };\n}): Promise<FacilitatorErrorInfo> {\n let body = '';\n try {\n body = await response.text();\n } catch {\n body = '';\n }\n const status = response.status;\n const parsed = parseFacilitatorErrorBody(body);\n const reason = parsed.reason;\n // 429 is admission control and 502/503/504 are \"no verdict\". None of them is\n // a rejection of the payment, so none of them may be reported as one.\n const transportRetryable =\n status === 429 || status === 502 || status === 503 || status === 504;\n // ...unless the facilitator SAID otherwise in the body. `settlement_unconfirmed`\n // is a 502 whose transaction was already broadcast and may be mined: retrying\n // signs a second authorization, with a fresh nonce, that the chain will\n // happily accept as another payment for the same purchase.\n //\n // Only ever DOWNGRADES. A body claiming `retryable: true` on a 402 must not\n // make this SDK resend a credential the facilitator genuinely refused, so the\n // status stays the ceiling and the body is only allowed to lower it.\n //\n // The one exception is NAMED, not read from a flag: `409\n // authorization_in_flight`. Its body says `retryable: false` because this\n // request will never get the original answer, but the verdict is still\n // coming, and resending the SAME request is how a caller without the\n // admitting binding learns it: the facilitator admits no replacement\n // payment for an admitted authorization, so the resend can only come back\n // as `authorization_already_settled` or as the original rejection.\n const inFlight = status === 409 && parsed.errorCode === AUTHORIZATION_IN_FLIGHT;\n const retryable = inFlight || (transportRetryable && !isDeclaredUnretryable(parsed));\n const retryAfterSeconds = retryable\n ? (parseRetryAfterSeconds(response) ?? DEFAULT_RETRY_AFTER_SECONDS)\n : undefined;\n // Replay only what the facilitator SAID it did not execute.\n //\n // A 429 is admission control: the request was counted, never handled. A 503\n // that names one of the pre-execution writer-lease reasons is refused in the\n // router before any signing. Everything else — an unattributed 503 from a\n // load balancer, a 502, a 504, `forward_failed` — is merely retryable: the\n // caller may resend after reconciling, but this SDK will not do it for them,\n // because \"a proxy answered\" is not evidence that nothing ran.\n //\n // Gated on `retryable` so the two can never disagree: a refusal this SDK will\n // not even retry must never be described as safe to replay automatically.\n const safeToReplay =\n retryable && (status === 429 || (status === 503 && isReplayableLeaseReason(reason)));\n\n return {\n error: `Facilitator error: ${status} - ${body}`,\n status,\n reason,\n errorCode: parsed.errorCode,\n transaction: parsed.transaction,\n paymentId: parsed.paymentId,\n retryAfterSeconds,\n retryable,\n safeToReplay,\n body,\n };\n}\n\n/** The subset of {@link FacilitatorErrorInfo} that is copied onto a response. */\nexport function failureFields(info: FacilitatorErrorInfo): Required<\n Pick<FacilitatorFailureFields, 'status' | 'retryable' | 'safeToReplay'>\n> &\n FacilitatorFailureFields {\n return {\n status: info.status,\n retryable: info.retryable,\n safeToReplay: info.safeToReplay,\n ...(info.reason !== undefined ? { reason: info.reason } : {}),\n ...(info.errorCode !== undefined ? { errorCode: info.errorCode } : {}),\n // Without these the caller is told \"do not retry\" and given nothing to do\n // instead — an error that swallows the hash is the same defect one layer up.\n ...(info.transaction !== undefined ? { transaction: info.transaction } : {}),\n ...(info.paymentId !== undefined ? { paymentId: info.paymentId } : {}),\n ...(info.retryAfterSeconds !== undefined\n ? { retryAfterSeconds: info.retryAfterSeconds }\n : {}),\n };\n}\n\n/**\n * Copy the failure fields off one response onto another.\n *\n * Used where a wrapper returns its own shape: without this the wrapper flattens\n * a `503` back into a bare failure and reintroduces, one level up, exactly the\n * ambiguity the fields exist to remove.\n */\nexport function carryFailureFields(\n source: FacilitatorFailureFields,\n): FacilitatorFailureFields {\n return {\n ...(source.status !== undefined ? { status: source.status } : {}),\n ...(source.reason !== undefined ? { reason: source.reason } : {}),\n ...(source.errorCode !== undefined ? { errorCode: source.errorCode } : {}),\n ...(source.transaction !== undefined ? { transaction: source.transaction } : {}),\n ...(source.paymentId !== undefined ? { paymentId: source.paymentId } : {}),\n ...(source.retryable !== undefined ? { retryable: source.retryable } : {}),\n ...(source.retryAfterSeconds !== undefined\n ? { retryAfterSeconds: source.retryAfterSeconds }\n : {}),\n ...(source.safeToReplay !== undefined ? { safeToReplay: source.safeToReplay } : {}),\n };\n}\n\n/** Options for {@link facilitatorFetch}. */\nexport interface FacilitatorFetchOptions {\n /** Abort the request after this many milliseconds. */\n timeoutMs: number;\n /** Extra attempts after the first. Default {@link DEFAULT_FACILITATOR_RETRIES}. */\n retries?: number;\n /**\n * Whether this particular refusal may be replayed.\n *\n * Default: only when the facilitator proved it executed nothing\n * (`info.safeToReplay`). Pass a stricter predicate on paths where even a\n * proven-safe replay is unwanted.\n */\n canReplay?: (info: FacilitatorErrorInfo) => boolean;\n /** Injected for tests. */\n fetchImpl?: typeof fetch;\n /** Injected for tests, so a retry does not really sleep. */\n sleepImpl?: (ms: number) => Promise<void>;\n}\n\nconst defaultSleep = (ms: number): Promise<void> =>\n new Promise((resolve) => setTimeout(resolve, ms));\n\n/**\n * POST/GET the facilitator, replaying a refusal that provably executed nothing.\n *\n * Returns the response plus, when it was not ok, the structured refusal — the\n * body has already been consumed to build it, so callers must not read it\n * again.\n *\n * Network errors and timeouts still THROW, exactly as before: callers already\n * have `catch` blocks that turn them into `{ success: false }`, and an\n * `AbortError` on the escrow paths triggers an on-chain reconciliation that\n * must keep firing.\n */\nexport async function facilitatorFetch(\n url: string,\n init: RequestInit,\n options: FacilitatorFetchOptions,\n): Promise<{ response: Response; error?: FacilitatorErrorInfo }> {\n const retries = options.retries ?? DEFAULT_FACILITATOR_RETRIES;\n const canReplay = options.canReplay ?? ((info: FacilitatorErrorInfo) => info.safeToReplay);\n const doFetch = options.fetchImpl ?? fetch;\n const sleep = options.sleepImpl ?? defaultSleep;\n\n let attempt = 0;\n for (;;) {\n // A fresh controller per attempt: an aborted signal stays aborted, so\n // reusing one would make every retry fail instantly.\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), options.timeoutMs);\n let response: Response;\n try {\n response = await doFetch(url, { ...init, signal: controller.signal });\n } finally {\n clearTimeout(timeoutId);\n }\n\n if (response.ok) return { response };\n\n const error = await readFacilitatorError(response);\n if (attempt >= retries || !error.retryable || !canReplay(error)) {\n return { response, error };\n }\n\n attempt += 1;\n await sleep((error.retryAfterSeconds ?? DEFAULT_RETRY_AFTER_SECONDS) * 1000);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/chains/index.ts","../src/types/index.ts","../src/utils/base64.ts","../src/utils/x402.ts","../src/utils/token-metadata.ts","../src/utils/validation.ts","../src/utils/personal-sign.ts","../src/utils/validity.ts","../src/utils/index.ts","../src/providers/solana/index.ts","../src/dx402.ts","../src/receipts.ts","../src/client/X402Client.ts","../src/policy.ts","../src/index.ts","../src/adapters/env-key.ts","../src/adapters/ows.ts","../src/facilitator.ts","../src/events.ts","../src/erc8128.ts","../src/escrow-preauth.ts","../src/erc7702.ts","../src/lifecycle-auth.ts","../src/providers/hedera/index.ts","../src/backend/index.ts","../src/backend/facilitator-error.ts"],"names":["SUPPORTED_CHAINS","DEFAULT_FACILITATOR_URL","DEFAULT_CHAIN","CAIP2_IDENTIFIERS","CAIP2_TO_CHAIN","DEFAULT_CONFIG","X402Error","DEFAULT_PAYMENT_HEADER","PAYMENT_HEADER_NAMES","DEFAULT_VALIDITY_SECONDS","MAX_VALIDITY_SECONDS","publicKeyString","nobleHexToBytes","bytesToHex","keccak_256","secp256k1","sha512","x25519","hkdf","sha256","gcm","edwardsToMontgomeryPub","digest","randomBytes","paymentId","contentHash","ed25519","ethers","SVMProvider","account","decoder","ZERO_ADDRESS","parseUnits","formatUnits","requirements","reqOptions"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * uvd-x402-sdk - Chain Registry\n *\n * Complete configuration for all 29 supported blockchain networks.\n * EVM chains (17): Use ERC-3009 TransferWithAuthorization (includes Scroll, SKALE Base, Robinhood Chain mainnet + testnet, Arc mainnet + testnet)\n * BSC is registered but disabled (Binance-Peg USDC has no ERC-3009), so it is not in those counts.\n * SVM chains (2): Solana and Fogo - Use SPL tokens with partially-signed transactions\n * Stellar (1): Uses Soroban authorization entries\n * NEAR (1): Uses NEP-366 meta-transactions\n * Algorand (2): Uses ASA transfers with atomic transaction groups\n * Sui (2): Uses sponsored transactions (facilitator pays gas)\n * XRPL (2): Native XRP via pre-signed Payment transaction blobs (facilitator pays fee)\n */\n\nimport type { ChainConfig, NetworkType, TokenType, TokenConfig } from '../types';\n\n/**\n * Default facilitator URL for x402 payments\n */\nexport const DEFAULT_FACILITATOR_URL = 'https://facilitator.ultravioletadao.xyz';\n\n/**\n * All supported chains configuration\n *\n * To add a new chain:\n * 1. Add chain config below with all required fields\n * 2. Verify USDC contract supports ERC-3009 (transferWithAuthorization) for EVM chains\n * 3. Test on testnet first before enabling\n */\nexport const SUPPORTED_CHAINS: Record<string, ChainConfig> = {\n 'hedera:mainnet': {\n chainId: 0, chainIdHex: '0x0', name: 'hedera:mainnet',\n displayName: 'Hedera', networkType: 'hedera',\n rpcUrl: 'https://mainnet-public.mirrornode.hedera.com', explorerUrl: 'https://hashscan.io/mainnet',\n nativeCurrency: { name: 'HBAR', symbol: 'HBAR', decimals: 8 },\n usdc: { address: '0.0.456858', decimals: 6, name: 'USDC', version: '' },\n tokens: {\n usdc: { address: '0.0.456858', decimals: 6, name: 'USDC', version: '' },\n },\n x402: { facilitatorUrl: DEFAULT_FACILITATOR_URL, enabled: true },\n },\n 'hedera:testnet': {\n chainId: 0, chainIdHex: '0x0', name: 'hedera:testnet',\n displayName: 'Hedera Testnet', networkType: 'hedera',\n rpcUrl: 'https://testnet.mirrornode.hedera.com', explorerUrl: 'https://hashscan.io/testnet',\n nativeCurrency: { name: 'HBAR', symbol: 'HBAR', decimals: 8 },\n usdc: { address: '0.0.429274', decimals: 6, name: 'USDC', version: '' },\n tokens: {\n usdc: { address: '0.0.429274', decimals: 6, name: 'USDC', version: '' },\n },\n x402: { facilitatorUrl: DEFAULT_FACILITATOR_URL, enabled: true },\n },\n\n // ============================================================================\n // EVM CHAINS (16 enabled + BSC, disabled)\n // ============================================================================\n\n base: {\n chainId: 8453,\n chainIdHex: '0x2105',\n name: 'base',\n displayName: 'Base',\n networkType: 'evm',\n rpcUrl: 'https://mainnet.base.org',\n explorerUrl: 'https://basescan.org',\n nativeCurrency: {\n name: 'Ethereum',\n symbol: 'ETH',\n decimals: 18,\n },\n usdc: {\n address: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\n decimals: 6,\n name: 'USD Coin',\n version: '2',\n },\n tokens: {\n usdc: {\n address: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\n decimals: 6,\n name: 'USD Coin',\n version: '2',\n },\n eurc: {\n address: '0x60a3E35Cc302bFA44Cb288Bc5a4F316Fdb1adb42',\n decimals: 6,\n name: 'EURC',\n version: '2',\n usdPegged: false,\n },\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true,\n },\n },\n\n avalanche: {\n chainId: 43114,\n chainIdHex: '0xa86a',\n name: 'avalanche',\n displayName: 'Avalanche C-Chain',\n networkType: 'evm',\n rpcUrl: 'https://avalanche-c-chain-rpc.publicnode.com',\n explorerUrl: 'https://snowtrace.io',\n nativeCurrency: {\n name: 'Avalanche',\n symbol: 'AVAX',\n decimals: 18,\n },\n usdc: {\n address: '0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E',\n decimals: 6,\n name: 'USD Coin',\n version: '2',\n },\n tokens: {\n usdc: {\n address: '0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E',\n decimals: 6,\n name: 'USD Coin',\n version: '2',\n },\n eurc: {\n address: '0xC891EB4cbdEFf6e073e859e987815Ed1505c2ACD',\n decimals: 6,\n name: 'EURC',\n version: '2',\n usdPegged: false,\n },\n ausd: {\n address: '0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a',\n decimals: 6,\n name: 'Agora Dollar',\n version: '1',\n },\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true,\n },\n },\n\n ethereum: {\n chainId: 1,\n chainIdHex: '0x1',\n name: 'ethereum',\n displayName: 'Ethereum',\n networkType: 'evm',\n rpcUrl: 'https://eth.llamarpc.com',\n explorerUrl: 'https://etherscan.io',\n nativeCurrency: {\n name: 'Ethereum',\n symbol: 'ETH',\n decimals: 18,\n },\n usdc: {\n address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',\n decimals: 6,\n name: 'USD Coin',\n version: '2',\n },\n tokens: {\n usdc: {\n address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',\n decimals: 6,\n name: 'USD Coin',\n version: '2',\n },\n eurc: {\n address: '0x1aBaEA1f7C830bD89Acc67eC4af516284b1bC33c',\n decimals: 6,\n name: 'Euro Coin',\n version: '2',\n usdPegged: false,\n },\n ausd: {\n address: '0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a',\n decimals: 6,\n name: 'Agora Dollar',\n version: '1',\n },\n pyusd: {\n address: '0x6c3ea9036406852006290770BEdFcAbA0e23A0e8',\n decimals: 6,\n name: 'PayPal USD',\n version: '1',\n },\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true,\n },\n },\n\n polygon: {\n chainId: 137,\n chainIdHex: '0x89',\n name: 'polygon',\n displayName: 'Polygon',\n networkType: 'evm',\n rpcUrl: 'https://polygon-rpc.com',\n explorerUrl: 'https://polygonscan.com',\n nativeCurrency: {\n name: 'Polygon',\n symbol: 'POL',\n decimals: 18,\n },\n usdc: {\n address: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',\n decimals: 6,\n name: 'USD Coin',\n version: '2',\n },\n tokens: {\n usdc: {\n address: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',\n decimals: 6,\n name: 'USD Coin',\n version: '2',\n },\n ausd: {\n address: '0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a',\n decimals: 6,\n name: 'Agora Dollar',\n version: '1',\n },\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true,\n },\n },\n\n arbitrum: {\n chainId: 42161,\n chainIdHex: '0xa4b1',\n name: 'arbitrum',\n displayName: 'Arbitrum One',\n networkType: 'evm',\n rpcUrl: 'https://arb1.arbitrum.io/rpc',\n explorerUrl: 'https://arbiscan.io',\n nativeCurrency: {\n name: 'Ethereum',\n symbol: 'ETH',\n decimals: 18,\n },\n usdc: {\n address: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',\n decimals: 6,\n name: 'USD Coin',\n version: '2',\n },\n tokens: {\n usdc: {\n address: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',\n decimals: 6,\n name: 'USD Coin',\n version: '2',\n },\n ausd: {\n address: '0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a',\n decimals: 6,\n name: 'Agora Dollar',\n version: '1',\n },\n usdt: {\n address: '0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9',\n decimals: 6,\n name: 'USD₮0',\n version: '1',\n },\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true,\n },\n },\n\n optimism: {\n chainId: 10,\n chainIdHex: '0xa',\n name: 'optimism',\n displayName: 'Optimism',\n networkType: 'evm',\n rpcUrl: 'https://mainnet.optimism.io',\n explorerUrl: 'https://optimistic.etherscan.io',\n nativeCurrency: {\n name: 'Ethereum',\n symbol: 'ETH',\n decimals: 18,\n },\n usdc: {\n address: '0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85',\n decimals: 6,\n name: 'USD Coin',\n version: '2',\n },\n tokens: {\n usdc: {\n address: '0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85',\n decimals: 6,\n name: 'USD Coin',\n version: '2',\n },\n usdt: {\n address: '0x01bff41798a0bcf287b996046ca68b395dbc1071',\n decimals: 6,\n name: 'USD₮0',\n version: '1',\n },\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true,\n },\n },\n\n celo: {\n chainId: 42220,\n chainIdHex: '0xa4ec',\n name: 'celo',\n displayName: 'Celo',\n networkType: 'evm',\n rpcUrl: 'https://forno.celo.org',\n explorerUrl: 'https://celoscan.io',\n nativeCurrency: {\n name: 'Celo',\n symbol: 'CELO',\n decimals: 18,\n },\n usdc: {\n address: '0xcebA9300f2b948710d2653dD7B07f33A8B32118C',\n decimals: 6,\n name: 'USDC', // Celo uses \"USDC\" not \"USD Coin\" for EIP-712\n version: '2',\n },\n tokens: {\n usdc: {\n address: '0xcebA9300f2b948710d2653dD7B07f33A8B32118C',\n decimals: 6,\n name: 'USDC', // Celo uses \"USDC\" not \"USD Coin\" for EIP-712\n version: '2',\n },\n usdt: {\n address: '0x48065fbBE25f71C9282ddf5e1cD6D6A887483D5e',\n decimals: 6,\n name: 'Tether USD', // Celo USDT uses \"Tether USD\" for EIP-712\n version: '1',\n },\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true,\n },\n },\n\n hyperevm: {\n chainId: 999,\n chainIdHex: '0x3e7',\n name: 'hyperevm',\n displayName: 'HyperEVM',\n networkType: 'evm',\n rpcUrl: 'https://rpc.hyperliquid.xyz/evm',\n explorerUrl: 'https://hyperevmscan.io',\n nativeCurrency: {\n name: 'Ethereum',\n symbol: 'ETH',\n decimals: 18,\n },\n usdc: {\n address: '0xb88339CB7199b77E23DB6E890353E22632Ba630f',\n decimals: 6,\n name: 'USDC', // HyperEVM uses \"USDC\" not \"USD Coin\"\n version: '2',\n },\n tokens: {\n usdc: {\n address: '0xb88339CB7199b77E23DB6E890353E22632Ba630f',\n decimals: 6,\n name: 'USDC', // HyperEVM uses \"USDC\" not \"USD Coin\"\n version: '2',\n },\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true,\n },\n },\n\n unichain: {\n chainId: 130,\n chainIdHex: '0x82',\n name: 'unichain',\n displayName: 'Unichain',\n networkType: 'evm',\n rpcUrl: 'https://unichain-rpc.publicnode.com',\n explorerUrl: 'https://uniscan.xyz',\n nativeCurrency: {\n name: 'Ethereum',\n symbol: 'ETH',\n decimals: 18,\n },\n usdc: {\n address: '0x078d782b760474a361dda0af3839290b0ef57ad6',\n decimals: 6,\n name: 'USDC', // Unichain uses \"USDC\" not \"USD Coin\"\n version: '2',\n },\n tokens: {\n usdc: {\n address: '0x078d782b760474a361dda0af3839290b0ef57ad6',\n decimals: 6,\n name: 'USDC', // Unichain uses \"USDC\" not \"USD Coin\"\n version: '2',\n },\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true,\n },\n },\n\n monad: {\n chainId: 143,\n chainIdHex: '0x8f',\n name: 'monad',\n displayName: 'Monad',\n networkType: 'evm',\n rpcUrl: 'https://rpc.monad.xyz',\n explorerUrl: 'https://monad.socialscan.io',\n nativeCurrency: {\n name: 'Monad',\n symbol: 'MON',\n decimals: 18,\n },\n usdc: {\n address: '0x754704bc059f8c67012fed69bc8a327a5aafb603',\n decimals: 6,\n name: 'USDC', // Monad uses \"USDC\" not \"USD Coin\"\n version: '2',\n },\n tokens: {\n usdc: {\n address: '0x754704bc059f8c67012fed69bc8a327a5aafb603',\n decimals: 6,\n name: 'USDC', // Monad uses \"USDC\" not \"USD Coin\"\n version: '2',\n },\n ausd: {\n address: '0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a',\n decimals: 6,\n name: 'Agora Dollar',\n version: '1',\n },\n usdt: {\n address: '0xe7cd86e13AC4309349F30B3435a9d337750fC82D',\n decimals: 6,\n name: 'USD\\u20AE0', // USD₮0 (USDT0 omnichain via LayerZero)\n version: '1',\n },\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true,\n },\n },\n\n bsc: {\n chainId: 56,\n chainIdHex: '0x38',\n name: 'bsc',\n displayName: 'BNB Smart Chain',\n networkType: 'evm',\n rpcUrl: 'https://binance.llamarpc.com',\n explorerUrl: 'https://bscscan.com',\n nativeCurrency: {\n name: 'Binance Coin',\n symbol: 'BNB',\n decimals: 18,\n },\n usdc: {\n // Binance-Peg USDC — 18 decimals, NOT the 6 every other chain uses.\n address: '0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d',\n decimals: 18,\n name: 'USD Coin',\n version: '2',\n },\n tokens: {\n usdc: {\n address: '0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d',\n decimals: 18,\n name: 'USD Coin',\n version: '2',\n },\n ausd: {\n address: '0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a',\n decimals: 6,\n name: 'Agora Dollar',\n version: '1',\n },\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n // Disabled on purpose: Binance-Peg USDC does not implement ERC-3009\n // `transferWithAuthorization`, so the exact scheme cannot settle it. The\n // entry exists so the 18-decimal figure is on record — assuming the usual\n // 6 here mis-prices a payment by 12 orders of magnitude.\n enabled: false,\n },\n },\n\n scroll: {\n chainId: 534352,\n chainIdHex: '0x82750',\n name: 'scroll',\n displayName: 'Scroll',\n networkType: 'evm',\n rpcUrl: 'https://rpc.scroll.io',\n explorerUrl: 'https://scrollscan.com',\n nativeCurrency: {\n name: 'Ethereum',\n symbol: 'ETH',\n decimals: 18,\n },\n usdc: {\n address: '0x06eFdBFf2a14a7c8E15944D1F4A48F9F95F663A4',\n decimals: 6,\n name: 'USD Coin',\n version: '2',\n },\n tokens: {\n usdc: {\n address: '0x06eFdBFf2a14a7c8E15944D1F4A48F9F95F663A4',\n decimals: 6,\n name: 'USD Coin',\n version: '2',\n },\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true,\n },\n },\n\n 'skale-base': {\n chainId: 1187947933,\n chainIdHex: '0x46cea59d',\n name: 'skale-base',\n displayName: 'SKALE Base',\n networkType: 'evm',\n rpcUrl: 'https://skale-base.skalenodes.com/v1/base',\n explorerUrl: 'https://skale-base-explorer.skalenodes.com',\n nativeCurrency: {\n name: 'CREDIT',\n symbol: 'CREDIT',\n decimals: 18,\n },\n usdc: {\n address: '0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20',\n decimals: 6,\n name: 'Bridged USDC (SKALE Bridge)', // Must match on-chain EIP-712 domain exactly\n version: '2',\n },\n tokens: {\n usdc: {\n address: '0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20',\n decimals: 6,\n name: 'Bridged USDC (SKALE Bridge)', // Must match on-chain EIP-712 domain exactly\n version: '2',\n },\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true,\n },\n },\n\n 'skale-base-sepolia': {\n chainId: 324705682,\n chainIdHex: '0x135a9d92',\n name: 'skale-base-sepolia',\n displayName: 'SKALE Base Sepolia',\n networkType: 'evm',\n rpcUrl: 'https://base-sepolia-testnet.skalenodes.com/v1/jubilant-horrible-ancha',\n explorerUrl: 'https://base-sepolia-testnet-explorer.skalenodes.com',\n nativeCurrency: {\n name: 'CREDIT',\n symbol: 'CREDIT',\n decimals: 18,\n },\n usdc: {\n address: '0x2e08028E3C4c2356572E096d8EF835cD5C6030bD',\n decimals: 6,\n name: 'Bridged USDC (SKALE Bridge)', // Must match on-chain EIP-712 domain exactly\n version: '2',\n },\n tokens: {\n usdc: {\n address: '0x2e08028E3C4c2356572E096d8EF835cD5C6030bD',\n decimals: 6,\n name: 'Bridged USDC (SKALE Bridge)', // Must match on-chain EIP-712 domain exactly\n version: '2',\n },\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true,\n },\n },\n\n // Robinhood Chain (Arbitrum Orbit L2). NOTE: there is NO USDC on this chain -\n // the settlement stablecoin is Paxos USDG (Global Dollar). The `usdc` field\n // below carries USDG for interface compatibility (same pattern as XRPL's native\n // asset), and `tokens.usdg` is the canonical entry.\n // CRITICAL: USDG's on-chain version() getter REVERTS, so the EIP-712 domain\n // { name: 'Global Dollar', version: '1' } can NEVER be resolved on-chain and\n // MUST come from this config (mirrored into PaymentRequirements.extra by callers).\n robinhood: {\n chainId: 4663,\n chainIdHex: '0x1237',\n name: 'robinhood',\n displayName: 'Robinhood Chain',\n networkType: 'evm',\n rpcUrl: 'https://rpc.mainnet.chain.robinhood.com',\n explorerUrl: 'https://robinhoodchain.blockscout.com',\n nativeCurrency: {\n name: 'Ethereum',\n symbol: 'ETH',\n decimals: 18,\n },\n usdc: {\n address: '0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168', // Paxos USDG (no USDC on this chain)\n decimals: 6,\n name: 'Global Dollar', // on-chain version() reverts; domain must be supplied off-chain\n version: '1',\n },\n tokens: {\n usdg: {\n address: '0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168',\n decimals: 6,\n name: 'Global Dollar', // on-chain version() reverts; domain must be supplied off-chain\n version: '1',\n },\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true,\n },\n },\n\n 'robinhood-testnet': {\n chainId: 46630,\n chainIdHex: '0xb626',\n name: 'robinhood-testnet',\n displayName: 'Robinhood Chain Testnet',\n networkType: 'evm',\n rpcUrl: 'https://rpc.testnet.chain.robinhood.com',\n explorerUrl: 'https://explorer.testnet.chain.robinhood.com',\n nativeCurrency: {\n name: 'Ethereum',\n symbol: 'ETH',\n decimals: 18,\n },\n usdc: {\n address: '0x7E955252E15c84f5768B83c41a71F9eba181802F', // Paxos USDG testnet (no USDC on this chain)\n decimals: 6,\n name: 'Global Dollar', // on-chain version() reverts; domain must be supplied off-chain\n version: '1',\n },\n tokens: {\n usdg: {\n address: '0x7E955252E15c84f5768B83c41a71F9eba181802F',\n decimals: 6,\n name: 'Global Dollar', // on-chain version() reverts; domain must be supplied off-chain\n version: '1',\n },\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true,\n },\n },\n\n // Arc testnet (Circle). The stablecoin IS the chain's native asset, so the SAME\n // balance is readable at TWO precisions:\n // - native / gas, via eth_getBalance and EIP-1559 fees: 18 decimals\n // - ERC-20 interface, via balanceOf and transferWithAuthorization: 6 decimals\n // (the ERC-20 view is floor(native / 10^12))\n // An x402 payment is an EIP-3009 authorization against the ERC-20 interface, so\n // its `value` is ALWAYS in the 6 of `tokens.usdc.decimals`. Scaling a price with\n // `nativeCurrency.decimals` instead charges 10^12 times the amount: $0.01 would\n // be signed as 10000000000000000 units, i.e. 10 billion USDC. `nativeCurrency`\n // below is correct where it is actually used -- the wallet_addEthereumChain\n // params -- and must never reach `parseUnits` for a payment.\n // Pinned by src/arc-testnet.test.ts.\n //\n // Mainnet (5042) and testnet (5042002) were verified independently against\n // their official RPCs on 2026-09-16. EURC domains checked on 2026-09-17; funded EURC payments settled on Arc mainnet on\n // 2026-09-22 (x402 v1/v2, docs/networks/arc.md); testnet pending.\n arc: {\n chainId: 5042,\n chainIdHex: '0x13b2',\n name: 'arc',\n displayName: 'Arc',\n networkType: 'evm',\n rpcUrl: 'https://rpc.mainnet.arc.io',\n explorerUrl: 'https://explorer.arc.io',\n nativeCurrency: {\n name: 'USD Coin',\n symbol: 'USDC',\n decimals: 18, // gas precision ONLY -- never the scale of a payment\n },\n usdc: {\n address: '0x3600000000000000000000000000000000000000',\n decimals: 6, // ERC-20 interface, which is what an EIP-3009 value is denominated in\n name: 'USDC', // on-chain name(); must match the EIP-712 domain exactly\n version: '2',\n },\n tokens: {\n usdc: {\n address: '0x3600000000000000000000000000000000000000',\n decimals: 6,\n name: 'USDC',\n version: '2',\n },\n eurc: {\n address: '0xbEf5f6d51CB62b58e6A8f77868681825C6fe21c1',\n decimals: 6,\n name: 'EURC',\n version: '2',\n usdPegged: false,\n },\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true,\n },\n },\n\n 'arc-testnet': {\n chainId: 5042002,\n chainIdHex: '0x4cef52',\n name: 'arc-testnet',\n displayName: 'Arc Testnet',\n networkType: 'evm',\n rpcUrl: 'https://rpc.testnet.arc.io',\n explorerUrl: 'https://explorer.testnet.arc.io',\n nativeCurrency: {\n name: 'USD Coin',\n symbol: 'USDC',\n decimals: 18, // gas precision ONLY -- never the scale of a payment\n },\n usdc: {\n address: '0x3600000000000000000000000000000000000000',\n decimals: 6, // ERC-20 interface, which is what an EIP-3009 value is denominated in\n name: 'USDC', // on-chain name(); must match the EIP-712 domain exactly\n version: '2',\n },\n tokens: {\n usdc: {\n address: '0x3600000000000000000000000000000000000000',\n decimals: 6,\n name: 'USDC',\n version: '2',\n },\n eurc: {\n address: '0x89B50855Aa3bE2F677cD6303Cec089B5F319D72a',\n decimals: 6,\n name: 'EURC',\n version: '2',\n usdPegged: false,\n },\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true,\n },\n },\n\n // ============================================================================\n // SVM CHAINS (2 networks) - Solana Virtual Machine\n // ============================================================================\n\n solana: {\n chainId: 0, // Non-EVM\n chainIdHex: '0x0',\n name: 'solana',\n displayName: 'Solana',\n networkType: 'svm',\n rpcUrl: 'https://api.mainnet-beta.solana.com',\n explorerUrl: 'https://solscan.io',\n nativeCurrency: {\n name: 'Solana',\n symbol: 'SOL',\n decimals: 9,\n },\n usdc: {\n address: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', // USDC SPL token mint\n decimals: 6,\n name: 'USD Coin',\n version: '1',\n },\n tokens: {\n usdc: {\n address: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', // USDC SPL token mint\n decimals: 6,\n name: 'USD Coin',\n version: '1',\n },\n ausd: {\n address: 'AUSD1jCcCyPLybk1YnvPWsHQSrZ46dxwoMniN4N2UEB9', // AUSD Token2022 mint\n decimals: 6,\n name: 'Agora Dollar',\n version: '1',\n },\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true,\n },\n },\n\n fogo: {\n chainId: 0, // Non-EVM (SVM)\n chainIdHex: '0x0',\n name: 'fogo',\n displayName: 'Fogo',\n networkType: 'svm',\n rpcUrl: 'https://rpc.fogo.nightly.app/',\n explorerUrl: 'https://explorer.fogo.nightly.app',\n nativeCurrency: {\n name: 'Fogo',\n symbol: 'FOGO',\n decimals: 9,\n },\n usdc: {\n address: 'uSd2czE61Evaf76RNbq4KPpXnkiL3irdzgLFUMe3NoG', // Fogo USDC mint\n decimals: 6,\n name: 'USDC',\n version: '1',\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true,\n },\n },\n\n // ============================================================================\n // STELLAR (1 network)\n // ============================================================================\n\n stellar: {\n chainId: 0, // Non-EVM\n chainIdHex: '0x0',\n name: 'stellar',\n displayName: 'Stellar',\n networkType: 'stellar',\n rpcUrl: 'https://horizon.stellar.org',\n explorerUrl: 'https://stellar.expert/explorer/public',\n nativeCurrency: {\n name: 'Lumens',\n symbol: 'XLM',\n decimals: 7, // Stellar uses 7 decimals (stroops)\n },\n usdc: {\n address: 'CCW67TSZV3SSS2HXMBQ5JFGCKJNXKZM7UQUWUZPUTHXSTZLEO7SJMI75', // Soroban Asset Contract\n decimals: 7, // Stellar USDC uses 7 decimals\n name: 'USDC',\n version: '1',\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true,\n },\n },\n\n // ============================================================================\n // NEAR (1 network) - Uses NEP-366 meta-transactions\n // ============================================================================\n\n near: {\n chainId: 0, // Non-EVM\n chainIdHex: '0x0',\n name: 'near',\n displayName: 'NEAR Protocol',\n networkType: 'near',\n rpcUrl: 'https://rpc.mainnet.near.org',\n explorerUrl: 'https://nearblocks.io',\n nativeCurrency: {\n name: 'NEAR',\n symbol: 'NEAR',\n decimals: 24, // NEAR uses 24 decimals (yoctoNEAR)\n },\n usdc: {\n address: '17208628f84f5d6ad33f0da3bbbeb27ffcb398eac501a31bd6ad2011e36133a1', // Native Circle USDC\n decimals: 6,\n name: 'USDC',\n version: '1',\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true, // NEP-366 meta-transactions supported\n },\n },\n\n // ============================================================================\n // ALGORAND (2 networks) - Uses ASA transfers with atomic transaction groups\n // ============================================================================\n\n algorand: {\n chainId: 0, // Non-EVM (Algorand uses genesis hash for network identification)\n chainIdHex: '0x0',\n name: 'algorand',\n displayName: 'Algorand',\n networkType: 'algorand',\n rpcUrl: 'https://mainnet-api.algonode.cloud',\n explorerUrl: 'https://allo.info',\n nativeCurrency: {\n name: 'Algo',\n symbol: 'ALGO',\n decimals: 6, // Algorand uses 6 decimals (microAlgos)\n },\n usdc: {\n address: '31566704', // USDC ASA ID on Algorand mainnet\n decimals: 6,\n name: 'USDC',\n version: '1',\n },\n tokens: {\n usdc: {\n address: '31566704', // USDC ASA ID on Algorand mainnet\n decimals: 6,\n name: 'USDC',\n version: '1',\n },\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true,\n },\n },\n\n 'algorand-testnet': {\n chainId: 0, // Non-EVM\n chainIdHex: '0x0',\n name: 'algorand-testnet',\n displayName: 'Algorand Testnet',\n networkType: 'algorand',\n rpcUrl: 'https://testnet-api.algonode.cloud',\n explorerUrl: 'https://testnet.allo.info',\n nativeCurrency: {\n name: 'Algo',\n symbol: 'ALGO',\n decimals: 6,\n },\n usdc: {\n address: '10458941', // USDC ASA ID on Algorand testnet\n decimals: 6,\n name: 'USDC',\n version: '1',\n },\n tokens: {\n usdc: {\n address: '10458941', // USDC ASA ID on Algorand testnet\n decimals: 6,\n name: 'USDC',\n version: '1',\n },\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true,\n },\n },\n\n // ============================================================================\n // SUI (2 networks) - Uses sponsored transactions (facilitator pays gas)\n // ============================================================================\n\n sui: {\n chainId: 0, // Non-EVM\n chainIdHex: '0x0',\n name: 'sui',\n displayName: 'Sui',\n networkType: 'sui',\n rpcUrl: 'https://fullnode.mainnet.sui.io:443',\n explorerUrl: 'https://suiscan.xyz/mainnet',\n nativeCurrency: {\n name: 'Sui',\n symbol: 'SUI',\n decimals: 9,\n },\n usdc: {\n // USDC coin type on Sui mainnet\n address: '0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC',\n decimals: 6,\n name: 'USDC',\n version: '1',\n },\n tokens: {\n usdc: {\n address: '0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC',\n decimals: 6,\n name: 'USDC',\n version: '1',\n },\n ausd: {\n // AUSD (Agora USD) coin type on Sui mainnet\n address: '0x2053d08c1e2bd02791056171aab0fd12bd7cd7efad2ab8f6b9c8902f14df2ff2::ausd::AUSD',\n decimals: 6,\n name: 'AUSD',\n version: '1',\n },\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true,\n },\n },\n\n 'sui-testnet': {\n chainId: 0, // Non-EVM\n chainIdHex: '0x0',\n name: 'sui-testnet',\n displayName: 'Sui Testnet',\n networkType: 'sui',\n rpcUrl: 'https://fullnode.testnet.sui.io:443',\n explorerUrl: 'https://suiscan.xyz/testnet',\n nativeCurrency: {\n name: 'Sui',\n symbol: 'SUI',\n decimals: 9,\n },\n usdc: {\n // USDC coin type on Sui testnet\n address: '0xa1ec7fc00a6f40db9693ad1415d0c193ad3906494428cf252621037bd7117e29::usdc::USDC',\n decimals: 6,\n name: 'USDC',\n version: '1',\n },\n tokens: {\n usdc: {\n address: '0xa1ec7fc00a6f40db9693ad1415d0c193ad3906494428cf252621037bd7117e29::usdc::USDC',\n decimals: 6,\n name: 'USDC',\n version: '1',\n },\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true,\n },\n },\n\n // ============================================================================\n // XRPL (2 networks) - XRP Ledger, native XRP via pre-signed Payment blobs\n // ============================================================================\n\n // Named `xrpl`, which is the only spelling the facilitator puts on the wire\n // (x402-rs/src/network.rs:189). `xrpl-mainnet` still resolves, as an alias.\n xrpl: {\n chainId: 0, // Non-EVM (XRPL uses network id strings, no numeric chain ID)\n chainIdHex: '0x0',\n name: 'xrpl',\n displayName: 'XRP Ledger',\n networkType: 'xrpl',\n rpcUrl: 'https://xrplcluster.com',\n explorerUrl: 'https://livenet.xrpl.org',\n nativeCurrency: {\n name: 'XRP',\n symbol: 'XRP',\n decimals: 6, // XRPL uses 6 decimals (drops); 1 XRP = 1,000,000 drops\n },\n // XRPL settles in native XRP - there is no USDC/token contract.\n // The `usdc` field describes the native asset for interface compatibility.\n // `usdPegged: false` is what stops that compatibility shim from being read\n // as a price: the key says usdc, the value is XRP, and a caller who writes\n // \"10.00\" means ten dollars. See TokenConfig.usdPegged.\n usdc: {\n address: 'XRP', // Native asset - no token contract\n decimals: 6,\n name: 'XRP',\n version: '1',\n usdPegged: false,\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true,\n },\n },\n\n 'xrpl-testnet': {\n chainId: 0, // Non-EVM\n chainIdHex: '0x0',\n name: 'xrpl-testnet',\n displayName: 'XRP Ledger Testnet',\n networkType: 'xrpl',\n rpcUrl: 'https://s.altnet.rippletest.net:51234',\n explorerUrl: 'https://testnet.xrpl.org',\n nativeCurrency: {\n name: 'XRP',\n symbol: 'XRP',\n decimals: 6,\n },\n // XRPL settles in native XRP - there is no USDC/token contract.\n usdc: {\n address: 'XRP', // Native asset - no token contract\n decimals: 6,\n name: 'XRP',\n version: '1',\n usdPegged: false,\n },\n x402: {\n facilitatorUrl: DEFAULT_FACILITATOR_URL,\n enabled: true,\n },\n },\n};\n\n/**\n * Alternate spellings that resolve to a registry entry without becoming one.\n *\n * A caller may WRITE these; the SDK never puts one on the wire, and they are\n * not separate networks, so counts and listings stay honest. The facilitator\n * keeps exactly this distinction: its `FromStr` takes `xrpl-mainnet` while\n * everything it publishes says `xrpl`, and the comment there calls that\n * spelling \"right for a lookup and wrong for a wire format\"\n * (`x402-rs/src/network.rs:251,189,719`).\n *\n * Mirrors `_NETWORK_ALIASES` in the Python SDK (`networks/base.py:199`).\n */\nexport const CHAIN_ALIASES: Record<string, string> = {\n hedera: 'hedera:mainnet',\n 'hedera-testnet': 'hedera:testnet',\n // Renamed in 2.85.0: the facilitator advertises the mainnet as `xrpl`.\n 'xrpl-mainnet': 'xrpl',\n};\n\n/**\n * Default chain for new users\n */\nexport const DEFAULT_CHAIN = 'base';\n\n/**\n * Get chain config by chain ID\n */\nexport function getChainById(chainId: number): ChainConfig | undefined {\n return Object.values(SUPPORTED_CHAINS).find(chain => chain.chainId === chainId);\n}\n\n/**\n * Get chain config by name (case-insensitive)\n */\nexport function getChainByName(name: string): ChainConfig | undefined {\n const key = name.toLowerCase();\n return SUPPORTED_CHAINS[key] ?? SUPPORTED_CHAINS[CHAIN_ALIASES[key] ?? ''];\n}\n\n/**\n * Check if a chain is supported\n */\nexport function isChainSupported(chainIdOrName: number | string): boolean {\n if (typeof chainIdOrName === 'number') {\n return Object.values(SUPPORTED_CHAINS).some(chain => chain.chainId === chainIdOrName);\n }\n return getChainByName(chainIdOrName) !== undefined;\n}\n\n/**\n * Get list of enabled chains\n */\nexport function getEnabledChains(): ChainConfig[] {\n return Object.values(SUPPORTED_CHAINS).filter(chain => chain.x402.enabled);\n}\n\n/**\n * Get list of chains by network type\n */\nexport function getChainsByNetworkType(networkType: NetworkType): ChainConfig[] {\n return Object.values(SUPPORTED_CHAINS).filter(\n chain => chain.networkType === networkType && chain.x402.enabled\n );\n}\n\n/**\n * Get all EVM chain IDs (for wallet_switchEthereumChain)\n */\nexport function getEVMChainIds(): number[] {\n return getChainsByNetworkType('evm').map(chain => chain.chainId);\n}\n\n/**\n * Get list of SVM chains (Solana, Fogo)\n */\nexport function getSVMChains(): ChainConfig[] {\n return Object.values(SUPPORTED_CHAINS).filter(\n chain => chain.networkType === 'svm' && chain.x402.enabled\n );\n}\n\n/**\n * Check if a chain is SVM-based (Solana Virtual Machine)\n */\nexport function isSVMChain(chainName: string): boolean {\n const chain = getChainByName(chainName);\n return chain?.networkType === 'svm';\n}\n\n/**\n * Get list of Sui chains\n */\nexport function getSuiChains(): ChainConfig[] {\n return Object.values(SUPPORTED_CHAINS).filter(\n chain => chain.networkType === 'sui' && chain.x402.enabled\n );\n}\n\n/**\n * Check if a chain is Sui-based\n */\nexport function isSuiChain(chainName: string): boolean {\n const chain = getChainByName(chainName);\n return chain?.networkType === 'sui';\n}\n\n/**\n * Get network type from chain name\n */\nexport function getNetworkType(chainName: string): NetworkType | undefined {\n const chain = getChainByName(chainName);\n return chain?.networkType;\n}\n\n/**\n * Format transaction URL for block explorer\n */\nexport function getExplorerTxUrl(chainName: string, txHash: string): string | null {\n const chain = getChainByName(chainName);\n if (!chain) return null;\n\n switch (chain.networkType) {\n case 'evm':\n return `${chain.explorerUrl}/tx/${txHash}`;\n case 'svm':\n case 'solana': // @deprecated\n return `${chain.explorerUrl}/tx/${txHash}`;\n case 'stellar':\n return `${chain.explorerUrl}/tx/${txHash}`;\n case 'near':\n return `${chain.explorerUrl}/txns/${txHash}`;\n case 'algorand':\n return `${chain.explorerUrl}/tx/${txHash}`;\n case 'sui':\n return `${chain.explorerUrl}/tx/${txHash}`;\n case 'hedera':\n return `${chain.explorerUrl}/transaction/${txHash.replace(/^(0\\.0\\.\\d+)@(\\d+)\\.(\\d+)$/, '$1-$2-$3')}`;\n case 'xrpl':\n return `${chain.explorerUrl}/transactions/${txHash}`;\n default:\n return null;\n }\n}\n\n/**\n * Format address URL for block explorer\n */\nexport function getExplorerAddressUrl(chainName: string, address: string): string | null {\n const chain = getChainByName(chainName);\n if (!chain) return null;\n\n switch (chain.networkType) {\n case 'evm':\n return `${chain.explorerUrl}/address/${address}`;\n case 'svm':\n case 'solana': // @deprecated\n return `${chain.explorerUrl}/account/${address}`;\n case 'stellar':\n return `${chain.explorerUrl}/account/${address}`;\n case 'near':\n return `${chain.explorerUrl}/address/${address}`;\n case 'algorand':\n return `${chain.explorerUrl}/account/${address}`;\n case 'sui':\n return `${chain.explorerUrl}/account/${address}`;\n case 'hedera':\n return `${chain.explorerUrl}/account/${address}`;\n case 'xrpl':\n return `${chain.explorerUrl}/accounts/${address}`;\n default:\n return null;\n }\n}\n\n/**\n * Get list of Algorand chains\n */\nexport function getAlgorandChains(): ChainConfig[] {\n return Object.values(SUPPORTED_CHAINS).filter(\n chain => chain.networkType === 'algorand' && chain.x402.enabled\n );\n}\n\n/**\n * Check if a chain is Algorand-based\n */\nexport function isAlgorandChain(chainName: string): boolean {\n const chain = getChainByName(chainName);\n return chain?.networkType === 'algorand';\n}\n\n/**\n * Get list of XRPL chains (XRP Ledger mainnet/testnet)\n */\nexport function getXRPLChains(): ChainConfig[] {\n return Object.values(SUPPORTED_CHAINS).filter(\n chain => chain.networkType === 'xrpl' && chain.x402.enabled\n );\n}\n\n/**\n * Check if a chain is XRPL-based (XRP Ledger)\n */\nexport function isXRPLChain(chainName: string): boolean {\n const chain = getChainByName(chainName);\n return chain?.networkType === 'xrpl';\n}\n\n// ============================================================================\n// MULTI-TOKEN SUPPORT FUNCTIONS\n// ============================================================================\n\n/**\n * Get token configuration for a specific chain and token type\n * Falls back to USDC config if token not found (for backward compatibility)\n *\n * @param chainName - Chain name (e.g., 'ethereum', 'base')\n * @param tokenType - Token type (e.g., 'usdc', 'eurc', 'pyusd')\n * @returns Token configuration or undefined if chain not found\n */\nexport function getTokenConfig(\n chainName: string,\n tokenType: TokenType = 'usdc'\n): TokenConfig | undefined {\n const chain = getChainByName(chainName);\n if (!chain) return undefined;\n\n // Try to get from tokens map first (new multi-token support)\n if (chain.tokens && chain.tokens[tokenType]) {\n return chain.tokens[tokenType];\n }\n\n // Fall back to usdc config for backward compatibility\n if (tokenType === 'usdc') {\n return chain.usdc;\n }\n\n return undefined;\n}\n\n/**\n * Whether a price written in dollars can be scaled into this token's base\n * units. Absent `usdPegged` means yes, so every stablecoin keeps its behaviour.\n *\n * @param token - Token configuration, or undefined\n * @returns True when one whole unit of the token is one dollar\n */\nexport function isUsdPegged(token: TokenConfig | undefined): boolean {\n return token?.usdPegged !== false;\n}\n\n/**\n * The sentence for refusing to price a network in dollars.\n *\n * Refusing without saying where to look only moves the dead end one layer up,\n * so this names the asset, states what the old code would have charged, and\n * points at the one place that lists the alternatives. Same shape as the Python\n * SDK's `NetworkConfig.usd_conversion_error()` (`networks/base.py:158`, 0.77.0)\n * so a team hitting this in either language reads the same explanation.\n *\n * @param chainName - Chain the price was written for\n * @param token - The settlement token that carries no dollar peg\n * @returns Message naming the asset and the way out\n */\nexport function usdConversionError(chainName: string, token: TokenConfig): string {\n const symbol = token.name || token.address;\n return (\n `${chainName} settles in ${symbol}, which is not pegged to the dollar, so an ` +\n `amount written in USD cannot be converted with its ${token.decimals} decimals: ` +\n `$1.00 would be charged as 1 ${symbol}. Name a dollar-pegged token this ` +\n `network's facilitator settles (GET /supported lists them; on XRPL that is the ` +\n `Circle USDC issued by rGm7WCVp9gb4jZHWTEtGUr4dd74z2XuWhE) and register it under ` +\n `the chain's \\`tokens\\`, or price the call in ${symbol} units yourself.`\n );\n}\n\n/**\n * Find which token of a chain a contract address belongs to.\n *\n * The signed payload carries the token *address*, but a server that accepts\n * several stablecoins on the same chain needs the symbol, the decimals and the\n * EIP-712 domain to rebuild the payment requirements. This resolves the address\n * back to the registry entry so that metadata can travel with the payment.\n *\n * @param chainName - Chain name (e.g., 'optimism')\n * @param address - Token contract address (case-insensitive on EVM)\n * @returns The token type and its config, or undefined if the address is not in the registry\n */\nexport function getTokenByAddress(\n chainName: string,\n address: string\n): { tokenType: TokenType; config: TokenConfig } | undefined {\n const chain = getChainByName(chainName);\n if (!chain || !address) return undefined;\n\n const wanted = address.startsWith('0x') ? address.toLowerCase() : address;\n const matches = (candidate: string): boolean =>\n (candidate.startsWith('0x') ? candidate.toLowerCase() : candidate) === wanted;\n\n if (chain.tokens) {\n for (const [tokenType, config] of Object.entries(chain.tokens)) {\n if (config && matches(config.address)) {\n return { tokenType: tokenType as TokenType, config };\n }\n }\n }\n\n if (chain.usdc && matches(chain.usdc.address)) {\n return { tokenType: 'usdc', config: chain.usdc };\n }\n\n return undefined;\n}\n\n/**\n * Get list of supported tokens for a chain\n *\n * @param chainName - Chain name (e.g., 'ethereum', 'base')\n * @returns Array of supported token types, or empty array if chain not found\n */\nexport function getSupportedTokens(chainName: string): TokenType[] {\n const chain = getChainByName(chainName);\n if (!chain) return [];\n\n // If tokens map exists, return its keys\n if (chain.tokens) {\n return Object.keys(chain.tokens) as TokenType[];\n }\n\n // Default to just USDC for chains without explicit tokens map\n return ['usdc'];\n}\n\n/**\n * Check if a token is supported on a specific chain\n *\n * @param chainName - Chain name (e.g., 'ethereum', 'base')\n * @param tokenType - Token type (e.g., 'usdc', 'eurc', 'pyusd')\n * @returns true if token is supported on the chain\n */\nexport function isTokenSupported(chainName: string, tokenType: TokenType): boolean {\n const chain = getChainByName(chainName);\n if (!chain) return false;\n\n // Check tokens map\n if (chain.tokens && chain.tokens[tokenType]) {\n return true;\n }\n\n // USDC is always supported (backward compatibility)\n if (tokenType === 'usdc') {\n return true;\n }\n\n return false;\n}\n\n/**\n * Get all chains that support a specific token\n *\n * @param tokenType - Token type (e.g., 'usdc', 'eurc', 'pyusd')\n * @returns Array of chain configs that support the token\n */\nexport function getChainsByToken(tokenType: TokenType): ChainConfig[] {\n return Object.values(SUPPORTED_CHAINS).filter(chain => {\n if (!chain.x402.enabled) return false;\n if (chain.tokens && chain.tokens[tokenType]) return true;\n if (tokenType === 'usdc') return true; // USDC is universal\n return false;\n });\n}\n","/**\n * uvd-x402-sdk - Type Definitions\n *\n * Core TypeScript interfaces for the x402 payment SDK.\n * These types define the contract between the SDK and consuming applications.\n */\n\n// Type-only, so it is erased at compile time and no runtime cycle exists between\n// this module and `policy.ts` (which imports `X402Error` from here as a value).\nimport type { AdvertisedQuote, PolicyApproval, PurchasePolicy } from '../policy';\n\n// ============================================================================\n// CHAIN CONFIGURATION TYPES\n// ============================================================================\n\n/**\n * Network type categorization\n * - 'evm': Ethereum Virtual Machine compatible chains (use EIP-712)\n * - 'svm': Solana Virtual Machine chains (Solana, Fogo) (use SPL tokens)\n * - 'stellar': Stellar network (use Soroban)\n * - 'near': NEAR Protocol (use NEP-366)\n * - 'algorand': Algorand network (use ASA transfers with atomic transactions)\n * - 'sui': Sui blockchain (use sponsored transactions)\n * - 'xrpl': XRP Ledger (use pre-signed Payment transaction blobs)\n *\n * @deprecated 'solana' type is deprecated, use 'svm' instead\n */\nexport type NetworkType = 'evm' | 'svm' | 'solana' | 'stellar' | 'near' | 'algorand' | 'sui' | 'xrpl' | 'hedera';\n\n/**\n * Supported x402 payment schemes\n * - 'exact': Standard one-shot payment (default)\n * - 'escrow': Escrow-based payment with verify/settle/refund\n * - 'commerce': Commerce alias for escrow (marketplace integrations)\n */\nexport type X402Scheme = 'exact' | 'escrow' | 'commerce';\n\n/**\n * Supported stablecoin token types\n * - usdc: USD Coin (Circle) - 6 decimals\n * - eurc: Euro Coin (Circle) - 6 decimals\n * - ausd: Agora USD (Agora Finance) - 6 decimals\n * - pyusd: PayPal USD (PayPal/Paxos) - 6 decimals\n * - usdt: Tether USD (USDT0 omnichain via LayerZero) - 6 decimals\n * - usdg: Global Dollar (Paxos) - 6 decimals; settlement stablecoin on Robinhood Chain\n */\nexport type TokenType = 'usdc' | 'eurc' | 'ausd' | 'pyusd' | 'usdt' | 'usdg' | 'hbar';\n\n/**\n * Token configuration for EIP-712 signing and transfers\n */\nexport interface TokenConfig {\n /** Contract/mint address */\n address: string;\n /** Token decimals (6 for all supported stablecoins) */\n decimals: number;\n /** Token name for EIP-712 domain (e.g., \"USD Coin\" or \"USDC\") */\n name: string;\n /** Token version for EIP-712 domain */\n version: string;\n /**\n * Whether one whole unit of this token IS one dollar.\n *\n * Absent means yes, so every stablecoin entry in the registry keeps the\n * behaviour it had. It is `false` for EURC (euros), native XRP and HBAR.\n *\n * **The distinction is unit, not scale.** `decimals` already handles scale --\n * BSC USDC has 18 of them and prices correctly. But scaling a price by the\n * decimals only turns dollars into base units when one whole unit is one\n * dollar. XRP has six real decimals and is still not a dollar, so\n * `$1.00 -> 10**6` charges **1 XRP**, which is whatever XRP happens to cost.\n * Six decimals of XRP are still XRP.\n *\n * The SDK refuses to price in USD against a token carrying `false` rather\n * than converting at a rate nobody agreed to. Mirrors `NetworkConfig\n * .usd_pegged` in the Python SDK (`networks/base.py:129`, 0.77.0).\n */\n usdPegged?: boolean;\n}\n\n/**\n * USDC token configuration for a specific chain\n * @deprecated Use TokenConfig instead. This is kept for backward compatibility.\n */\nexport interface USDCConfig {\n /** Contract/mint address */\n address: string;\n /** Token decimals (6 for most chains, 7 for Stellar) */\n decimals: number;\n /** Token name for EIP-712 domain (e.g., \"USD Coin\" or \"USDC\") */\n name: string;\n /** Token version for EIP-712 domain */\n version: string;\n /**\n * Whether one whole unit of this token IS one dollar. Absent means yes.\n *\n * See {@link TokenConfig.usdPegged}. It matters here because this field is\n * also where a chain that settles in its own native asset describes that\n * asset -- XRPL keeps native XRP under the key `usdc`, so the key promises a\n * dollar the value does not deliver.\n */\n usdPegged?: boolean;\n}\n\n/**\n * Native currency configuration\n */\nexport interface NativeCurrency {\n name: string;\n symbol: string;\n decimals: number;\n}\n\n/**\n * Complete chain configuration\n */\nexport interface ChainConfig {\n /** Numeric chain ID (0 for non-EVM chains) */\n chainId: number;\n /** Hex-encoded chain ID for wallet_switchEthereumChain */\n chainIdHex: string;\n /** Internal chain identifier (e.g., 'base', 'solana') */\n name: string;\n /** Human-readable display name */\n displayName: string;\n /** Network type for routing */\n networkType: NetworkType;\n /** Primary RPC endpoint URL */\n rpcUrl: string;\n /** Block explorer base URL */\n explorerUrl: string;\n /** Native currency info */\n nativeCurrency: NativeCurrency;\n /** USDC token configuration */\n usdc: USDCConfig;\n /**\n * Multi-token configurations (EVM chains only)\n * Maps token type to its configuration for this chain.\n * Not all tokens are available on all chains.\n */\n tokens?: Partial<Record<TokenType, TokenConfig>>;\n /** x402 facilitator configuration */\n x402: {\n facilitatorUrl: string;\n enabled: boolean;\n };\n}\n\n// ============================================================================\n// WALLET TYPES\n// ============================================================================\n\n/**\n * Current wallet connection state\n */\nexport interface WalletState {\n /** Whether a wallet is currently connected */\n connected: boolean;\n /** Connected wallet address (null if not connected) */\n address: string | null;\n /** Current chain ID (null for non-EVM or disconnected) */\n chainId: number | null;\n /** Current network name */\n network: string | null;\n /** Network type of connected wallet */\n networkType: NetworkType | null;\n /** USDC balance on current chain (null if unknown) */\n balance: string | null;\n}\n\n/**\n * Wallet adapter interface for different wallet types\n */\nexport interface WalletAdapter {\n /** Unique identifier for this wallet type */\n readonly id: string;\n /** Display name */\n readonly name: string;\n /** Network type this adapter supports */\n readonly networkType: NetworkType;\n\n /** Check if this wallet is available/installed */\n isAvailable(): boolean;\n\n /** Connect to the wallet */\n connect(chainName?: string): Promise<string>;\n\n /** Disconnect from the wallet */\n disconnect(): Promise<void>;\n\n /** Switch to a different chain (EVM only) */\n switchChain?(chainName: string): Promise<void>;\n\n /**\n * Sign a payment payload\n * For EVM chains, supports multi-token via paymentInfo.tokenType\n */\n signPayment(paymentInfo: PaymentInfo, chainConfig: ChainConfig): Promise<string>;\n\n /**\n * Check token balance (defaults to USDC for backward compatibility)\n * EVM providers may accept optional tokenType parameter\n */\n getBalance(chainConfig: ChainConfig, tokenType?: TokenType): Promise<string>;\n\n /** Get current address */\n getAddress(): string | null;\n\n /** Get current chain ID (EVM only) */\n getChainId?(): number | null;\n}\n\n/**\n * EIP-712 domain for typed data signing\n */\nexport interface EIP712Domain {\n name: string;\n version: string;\n chainId: number;\n verifyingContract: string;\n}\n\n/**\n * EIP-712 type definitions\n */\nexport interface EIP712Types {\n [typeName: string]: Array<{ name: string; type: string }>;\n}\n\n// ============================================================================\n// PAYMENT TYPES\n// ============================================================================\n\n/**\n * Payment information returned by backend on 402 response\n */\nexport interface PaymentInfo {\n /** Exact v2 offer/resource, required by native Hedera. */\n accepted?: Record<string, unknown>;\n resource?: { url: string; description?: string; mimeType?: string };\n extensions?: Record<string, unknown>;\n /** Default recipient address */\n recipient: string;\n /** Network-specific recipient addresses */\n recipients?: {\n evm?: string;\n solana?: string;\n near?: string;\n stellar?: string;\n algorand?: string;\n sui?: string;\n xrpl?: string;\n hedera?: string;\n };\n /** Facilitator address (for Solana fee payer) */\n facilitator?: string;\n /**\n * Amount in whole units of the settlement asset (e.g., \"10.00\").\n *\n * For dollar-pegged tokens that is dollars; for EURC it is **euros**.\n * On XRPL it is **XRP**, because XRPL settles in its own native asset:\n * the provider spends this through `xrpToDrops` and bills whole XRP\n * (`src/providers/xrpl/index.ts`). This used to be documented as USD, which\n * made the type and its only XRPL consumer disagree about the unit -- and the\n * consumer won, so a \"10.00\" written as ten dollars left as ten XRP. The SDK\n * now refuses to build a dollar price for an asset with no dollar peg rather\n * than let the two readings meet on the wire; see\n * {@link TokenConfig.usdPegged}.\n */\n amount: string;\n /** Token symbol (usually \"USDC\") */\n token?: string;\n /**\n * Token type for multi-token support\n * Defaults to 'usdc' if not specified for backward compatibility\n */\n tokenType?: TokenType;\n /** Network hint from backend */\n network?: string;\n /** Supported chain IDs */\n supportedChains?: number[];\n /**\n * Envelope version the resource asked for, as read off its own 402.\n *\n * This is what makes the client's `x402Version: 'auto'` mean something: the\n * buyer loop reads the version out of the challenge and hands it down here,\n * so the header is built in the shape the server said it accepts. Left\n * undefined by callers who build a payment by hand -- then the client config\n * decides, exactly as before.\n */\n x402Version?: X402Version;\n /**\n * Seconds this EIP-3009 authorization stays settleable\n * (`validBefore = now + validitySeconds`).\n *\n * Set it when the seller settles **async** -- verify, hand over the resource,\n * settle afterwards -- and needs the authorization alive for longer than the\n * default. Left undefined, `X402ClientConfig.validitySeconds` decides, and\n * failing that `DEFAULT_VALIDITY_SECONDS` (300 s, the timeout this SDK's own\n * seller side announces by default). `X402Client.fetch()` fills it from the\n * seller's `maxTimeoutSeconds` when the 402 declares one.\n *\n * Must be a whole number of seconds between 1 and `MAX_VALIDITY_SECONDS`\n * (3600); anything else is refused with `INVALID_CONFIG` before anything is\n * signed. The ceiling is here because this type is shaped like a parsed 402:\n * a caller that hands a seller's response straight to `createPayment` would\n * otherwise let the SELLER decide how long the payer's authorization stays\n * claimable. The facilitator also keeps a 6 s clock-skew grace, so the payer\n * really has `validitySeconds - 6` to sign.\n */\n validitySeconds?: number;\n}\n\n/**\n * One payment option read off a resource's `402`, normalised.\n *\n * The 402 body speaks two dialects -- v1 spells the price `maxAmountRequired`\n * and names the chain `base`, v2 spells it `amount` and names it `eip155:8453`\n * -- and a buyer that only learned one of them silently ignores half the\n * offers. This is the shape after both have been read.\n */\nexport interface X402PaymentOffer {\n /** Network exactly as the 402 wrote it (plain name or CAIP-2). */\n network: string;\n /** SDK chain name the network resolved to, or null when unknown. */\n chainName: string | null;\n /** Token contract address the resource wants paid, when it named one. */\n asset?: string;\n /** Price in the token's own atomic units. */\n amount: string;\n /** Decimals used to read `amount`. */\n decimals: number;\n /** Recipient of the payment. */\n payTo: string;\n /**\n * The seller's `maxTimeoutSeconds`, when its 402 entry declared a finite number.\n *\n * `X402Client.fetch()` signs this window -- clamped to `1..MAX_VALIDITY_SECONDS`\n * -- instead of the client's own, because the seller is the one party that\n * knows how long its settlement takes. Undefined when the entry declared none,\n * or declared something that is not a number.\n */\n maxTimeoutSeconds?: number;\n /** The accept object verbatim -- echoed back for v2. */\n raw: Record<string, unknown>;\n}\n\n/**\n * Options for {@link X402Client.fetch} -- the buyer loop.\n */\nexport interface X402FetchOptions {\n /** HTTP method for both the probe and the paid retry (default `GET`). */\n method?: string;\n /**\n * Hard ceiling in token units (e.g. `'0.05'`). A 402 that asks for more\n * throws instead of signing. Undefined = no ceiling, which means paying\n * whatever an untrusted resource asks: discouraged.\n */\n maxAmount?: string;\n /** Token to pay with (default `usdc`). */\n tokenType?: TokenType;\n /** Override the default cheapest-offer selection. */\n select?: (offers: X402PaymentOffer[]) => X402PaymentOffer | null | undefined;\n /** Passed through to both requests (`headers`, `body`, `signal`, ...). */\n init?: RequestInit;\n /** Injectable `fetch` (tests, or a runtime without a global one). */\n fetchImpl?: typeof globalThis.fetch;\n /**\n * What a catalog listing advertised, when the caller read one.\n *\n * The comparison NEVER decides anything -- a seller repricing inside a policy\n * the operator already authorised is ordinary commerce -- but handing it over\n * gets the divergence reported on the approval instead of having to diff the\n * two by hand. See `PolicyApproval.versusQuote`.\n */\n advertised?: AdvertisedQuote;\n /**\n * Called once the paid retry came back with something other than a 402, i.e.\n * the seller accepted the payment.\n *\n * This is where a caller calls `client.policy.recordSpend(...)`. Evaluating\n * deliberately does not spend: signing can fail and a settlement can be\n * refused, and a cumulative limit that counted attempts would lock a caller\n * out of money it never spent. Nothing here is automatic, so a caller that\n * wants a cumulative limit to mean something has to say so.\n */\n onPaid?: (approval: PolicyApproval) => void;\n}\n\n/**\n * Simple payment request from application\n */\nexport interface PaymentRequest {\n /** Amount in USDC (e.g., \"10.00\") */\n amount: string;\n /** Override recipient address (optional) */\n recipient?: string;\n /** Application-specific metadata */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * x402 payment header names\n *\n * - 'X-PAYMENT': v1 header name (default, most compatible)\n * - 'PAYMENT-SIGNATURE': v2 header name (newer standard)\n *\n * Both headers use the same base64-encoded JSON payload format.\n * The facilitator accepts both headers.\n */\nexport type X402HeaderName = 'X-PAYMENT' | 'PAYMENT-SIGNATURE';\n\n/**\n * Payment headers object containing both v1 and v2 header formats\n */\nexport interface PaymentHeaders {\n /** v1 header: X-PAYMENT */\n 'X-PAYMENT': string;\n /** v2 header: PAYMENT-SIGNATURE (same value, different header name) */\n 'PAYMENT-SIGNATURE': string;\n}\n\n/**\n * Result of a payment operation\n */\nexport interface PaymentResult {\n /** Whether payment was successful */\n success: boolean;\n /** Base64-encoded X-PAYMENT header value */\n paymentHeader: string;\n /**\n * Payment headers object for easy use with fetch/axios\n *\n * @example\n * ```ts\n * // Use v1 header\n * fetch(url, { headers: { 'X-PAYMENT': result.headers['X-PAYMENT'] } });\n *\n * // Use v2 header\n * fetch(url, { headers: { 'PAYMENT-SIGNATURE': result.headers['PAYMENT-SIGNATURE'] } });\n * ```\n */\n headers: PaymentHeaders;\n /** Transaction hash (if available) */\n transactionHash?: string;\n /** Network where payment was made */\n network: string;\n /** Payer address */\n payer?: string;\n /** Error message (if success is false) */\n error?: string;\n}\n\n// ============================================================================\n// PAYLOAD TYPES (Internal)\n// ============================================================================\n\n/**\n * EVM payment payload (ERC-3009 TransferWithAuthorization)\n */\nexport interface EVMPaymentPayload {\n from: string;\n to: string;\n value: string;\n validAfter: number;\n validBefore: number;\n nonce: string;\n v: number;\n r: string;\n s: string;\n chainId: number;\n token: string;\n}\n\n/**\n * Token info for non-USDC stablecoins (e.g., Token2022 like AUSD)\n * Required in payload for facilitator to verify Token2022 transfers correctly.\n */\nexport interface TokenInfo {\n /** Token mint address */\n address: string;\n /** Token symbol (e.g., 'AUSD') */\n symbol: string;\n /** Token decimals (e.g., 6) */\n decimals: number;\n}\n\n/**\n * Solana payment payload (partially-signed transaction)\n */\nexport interface SolanaPaymentPayload {\n /** Base64-encoded serialized transaction */\n transaction: string;\n /**\n * Token info for non-USDC tokens (e.g., Token2022 like AUSD)\n * CRITICAL: Must be included for Token2022 tokens for facilitator verification\n */\n token?: TokenInfo;\n}\n\n/**\n * Stellar payment payload (Soroban authorization)\n */\nexport interface StellarPaymentPayload {\n /** Sender G... public key */\n from: string;\n /** Recipient G... public key */\n to: string;\n /** Amount in stroops (7 decimals) */\n amount: string;\n /** USDC SAC contract address */\n tokenContract: string;\n /** Base64 XDR-encoded SorobanAuthorizationEntry */\n authorizationEntryXdr: string;\n /** Random 64-bit nonce */\n nonce: number;\n /** Ledger when authorization expires */\n signatureExpirationLedger: number;\n}\n\n/**\n * NEAR payment payload (NEP-366 meta-transaction)\n */\nexport interface NEARPaymentPayload {\n /** Base64 Borsh-encoded SignedDelegateAction */\n signedDelegateAction: string;\n network: 'near';\n}\n\n/**\n * Algorand payment payload (atomic transaction group)\n *\n * Follows the GoPlausible x402-avm spec for atomic groups:\n * - Transaction 0: Fee payment (UNSIGNED) - facilitator -> facilitator, covers all fees\n * - Transaction 1: ASA transfer (SIGNED) - client -> merchant\n *\n * The facilitator signs transaction 0 and submits the complete atomic group.\n */\nexport interface AlgorandPaymentPayload {\n /** Index of the payment transaction in the group (always 1) */\n paymentIndex: number;\n /**\n * Array of base64-encoded msgpack transactions forming the atomic group:\n * - [0]: Unsigned fee transaction (facilitator signs)\n * - [1]: Signed ASA transfer (client signed)\n */\n paymentGroup: string[];\n}\n\n/**\n * Sui payment payload (sponsored transaction)\n *\n * Uses Sui sponsored transactions where:\n * - User creates a programmable transaction for USDC transfer\n * - User signs the transaction\n * - Facilitator sponsors (pays gas in SUI) and submits\n *\n * User pays: ZERO SUI\n */\nexport interface SuiPaymentPayload {\n /** Base64-encoded BCS serialized TransactionData */\n transactionBytes: string;\n /** Base64-encoded user signature */\n senderSignature: string;\n /** Sender address (0x + 64 hex chars) */\n from: string;\n /** Recipient address (0x + 64 hex chars) */\n to: string;\n /** Amount in base units (string to handle large numbers) */\n amount: string;\n /** Coin object ID used for the transfer (REQUIRED by facilitator) */\n coinObjectId: string;\n}\n\n/**\n * XRPL payment payload (pre-signed Payment transaction blob)\n *\n * Uses the t54 \"pre-signed Payment blob\" scheme on the XRP Ledger:\n * - The client builds and FULLY signs a Payment transaction off-chain,\n * paying its own XRP network fee.\n * - The single `signedTxBlob` field (hex-encoded fully-signed XRPL tx blob)\n * is sent to the facilitator, which decodes it to re-derive payer/amount/\n * destination and submits it.\n *\n * All payment-level fields (destination, amount, InvoiceID, SourceTag, etc.)\n * come from PaymentRequirements/extra, NOT from this payload.\n *\n * XRP is the native asset (6 decimals / drops). There is no token contract.\n *\n * The JSON field name is EXACTLY `signedTxBlob` (camelCase).\n */\nexport interface XRPLPaymentPayload {\n /** Hex-encoded fully-signed XRPL Payment transaction blob (tx_blob) */\n signedTxBlob: string;\n}\n\n/**\n * Union type for all payment payloads\n */\nexport type PaymentPayload =\n | EVMPaymentPayload\n | SolanaPaymentPayload\n | StellarPaymentPayload\n | NEARPaymentPayload\n | AlgorandPaymentPayload\n | SuiPaymentPayload\n | XRPLPaymentPayload;\n\n// ============================================================================\n// X402 HEADER TYPES (v1 and v2)\n// ============================================================================\n\n/**\n * x402 protocol version\n */\nexport type X402Version = 1 | 2;\n\n/**\n * CAIP-2 chain identifiers for x402 v2\n * @see https://github.com/ChainAgnostic/CAIPs/blob/master/CAIPs/caip-2.md\n */\nexport const CAIP2_IDENTIFIERS: Record<string, string> = {\n 'hedera:mainnet': 'hedera:mainnet',\n 'hedera:testnet': 'hedera:testnet',\n // EVM chains\n base: 'eip155:8453',\n ethereum: 'eip155:1',\n polygon: 'eip155:137',\n arbitrum: 'eip155:42161',\n optimism: 'eip155:10',\n avalanche: 'eip155:43114',\n celo: 'eip155:42220',\n hyperevm: 'eip155:999',\n unichain: 'eip155:130',\n monad: 'eip155:143',\n bsc: 'eip155:56',\n scroll: 'eip155:534352',\n 'skale-base': 'eip155:1187947933',\n 'skale-base-sepolia': 'eip155:324705682',\n robinhood: 'eip155:4663',\n 'robinhood-testnet': 'eip155:46630',\n arc: 'eip155:5042',\n 'arc-testnet': 'eip155:5042002',\n // SVM chains\n solana: 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp',\n fogo: 'svm:fogo',\n // Stellar\n stellar: 'stellar:pubnet',\n // NEAR\n near: 'near:mainnet',\n // Algorand\n algorand: 'algorand:mainnet',\n 'algorand-testnet': 'algorand:testnet',\n // Sui\n sui: 'sui:mainnet',\n 'sui-testnet': 'sui:testnet',\n // XRPL (XRP Ledger)\n xrpl: 'xrpl',\n 'xrpl-testnet': 'xrpl-testnet',\n};\n\n/**\n * Reverse mapping from CAIP-2 to chain name\n */\nexport const CAIP2_TO_CHAIN: Record<string, string> = Object.fromEntries(\n Object.entries(CAIP2_IDENTIFIERS).map(([k, v]) => [v, k])\n);\n\n/**\n * x402 v1 header structure (network as string)\n */\nexport interface X402HeaderV1 {\n x402Version: 1;\n scheme: X402Scheme;\n network: string;\n payload: X402PayloadData;\n}\n\n/**\n * x402 v2 payment option\n */\nexport interface X402PaymentOption {\n network: string; // CAIP-2 format\n asset: string;\n amount: string;\n facilitator?: string;\n}\n\n/**\n * x402 v2 header structure (CAIP-2 network, accepts array)\n */\nexport interface X402HeaderV2 {\n x402Version: 2;\n scheme: X402Scheme;\n network: string; // CAIP-2 format\n payload: X402PayloadData;\n accepts?: X402PaymentOption[];\n}\n\n/**\n * Union type for both v1 and v2 headers\n */\nexport type X402Header = X402HeaderV1 | X402HeaderV2;\n\n/**\n * EVM-specific payload in x402 header\n */\nexport interface X402EVMPayload {\n signature: string;\n authorization: {\n from: string;\n to: string;\n value: string;\n validAfter: string;\n validBefore: string;\n nonce: string;\n };\n /**\n * Which token was actually paid.\n *\n * Only present when the payment is created with `includeTokenMetadata`. The\n * signature alone does not say which stablecoin it authorizes — a server that\n * accepts several tokens on the same chain cannot rebuild the payment\n * requirements without this. Omitted by default so existing v1 wire formats\n * stay byte-identical.\n */\n token?: PaymentTokenMetadata;\n}\n\n/**\n * Token identification carried inside an x402 payload.\n *\n * Mirrors what a resource server needs to build `paymentRequirements`: the\n * `asset` it must charge and the `extra` EIP-712 domain the facilitator needs\n * to recover the signature.\n */\nexport interface PaymentTokenMetadata {\n /** Token contract address (the `asset` of the payment requirements) */\n address: string;\n /** Uppercase token symbol, e.g. `USDC`, `EURC`, `USDT` */\n symbol: string;\n /** Token decimals — the amount in the authorization is in these units */\n decimals: number;\n /** EIP-712 domain of the token contract (the `extra` of the requirements) */\n eip712: {\n name: string;\n version: string;\n };\n}\n\n/**\n * Solana-specific payload in x402 header\n */\nexport interface X402SolanaPayload {\n transaction: string;\n}\n\n/**\n * Settlement account payload for Crossmint and other custodial wallets\n * that can only sendTransaction (not signTransaction).\n *\n * In this mode, the client already submitted the transaction on-chain.\n * The facilitator verifies the on-chain tx, then sweeps USDC from the\n * settlement account to the payTo address.\n *\n * Used by: Crossmint smart wallets via @faremeter/wallet-crossmint\n */\nexport interface X402SettlementAccountPayload {\n /** On-chain transaction signature (already submitted) */\n transactionSignature: string;\n /** Base58 secret key for sweeping settlement account (optional) */\n settleSecretKey?: string;\n /** Address to receive rent from closed settlement ATA (optional) */\n settlementRentDestination?: string;\n}\n\n/**\n * Stellar-specific payload in x402 header\n */\nexport interface X402StellarPayload {\n from: string;\n to: string;\n amount: string;\n tokenContract: string;\n authorizationEntryXdr: string;\n nonce: number;\n signatureExpirationLedger: number;\n}\n\n/**\n * NEAR-specific payload in x402 header\n */\nexport interface X402NEARPayload {\n signedDelegateAction: string;\n}\n\n/**\n * Algorand-specific payload in x402 header (atomic group format)\n */\nexport interface X402AlgorandPayload {\n /** Index of the payment transaction in the group (always 1) */\n paymentIndex: number;\n /** Array of base64-encoded msgpack transactions */\n paymentGroup: string[];\n}\n\n/**\n * Sui-specific payload in x402 header (sponsored transaction)\n */\nexport interface X402SuiPayload {\n /** BCS-encoded transaction bytes (base64) */\n transactionBytes: string;\n /** User's signature on the transaction (base64) */\n senderSignature: string;\n /** Sender's Sui address (0x...) */\n from: string;\n /** Recipient's Sui address (0x...) */\n to: string;\n /** Amount in smallest unit (string to avoid precision issues) */\n amount: string;\n /** Coin object ID used for the transfer (REQUIRED by facilitator) */\n coinObjectId: string;\n}\n\n/**\n * XRPL-specific payload in x402 header (t54 pre-signed Payment blob)\n *\n * The JSON field name is EXACTLY `signedTxBlob` (camelCase). The facilitator\n * decodes the blob to re-derive payer/amount/destination; no other fields are\n * carried in the payload.\n */\nexport interface X402XRPLPayload {\n /** Hex-encoded fully-signed XRPL Payment transaction blob (tx_blob) */\n signedTxBlob: string;\n}\n\n/**\n * Union of all x402 payload types\n */\nexport type X402PayloadData =\n | X402EVMPayload\n | X402SolanaPayload\n | X402SettlementAccountPayload\n | X402StellarPayload\n | X402NEARPayload\n | X402AlgorandPayload\n | X402SuiPayload\n | X402XRPLPayload;\n\n// ============================================================================\n// CLIENT CONFIGURATION\n// ============================================================================\n\n/**\n * Multi-payment configuration for supporting multiple networks\n */\nexport interface MultiPaymentConfig {\n /** Networks to support (e.g., ['base', 'solana', 'stellar', 'near']) */\n networks: string[];\n /** Default network if user hasn't selected one */\n defaultNetwork?: string;\n /** Whether to auto-detect user's preferred network based on wallet */\n autoDetect?: boolean;\n}\n\n/**\n * SDK client configuration options\n */\nexport interface X402ClientConfig {\n /** Facilitator URL (default: https://facilitator.ultravioletadao.xyz) */\n facilitatorUrl?: string;\n /** Default chain to connect to */\n defaultChain?: string;\n /** Auto-connect on initialization */\n autoConnect?: boolean;\n /** Enable debug logging */\n debug?: boolean;\n /** Custom chain configurations (override defaults) */\n customChains?: Record<string, Partial<ChainConfig>>;\n /** Wallet preference order */\n walletPreference?: string[];\n /** Custom RPC URLs (override defaults) */\n rpcOverrides?: Record<string, string>;\n /**\n * x402 protocol version to use\n * - 1: Classic format with network as string (e.g., \"base\")\n * - 2: CAIP-2 format with accepts array (e.g., \"eip155:8453\")\n * - 'auto': Auto-detect from 402 response (default)\n */\n x402Version?: X402Version | 'auto';\n /** Multi-payment configuration for supporting multiple networks */\n multiPayment?: MultiPaymentConfig;\n /**\n * What this buyer is allowed to sign, decided before it signs.\n *\n * Left undefined, the client holds `PurchasePolicy.permissive()`: this SDK had\n * no budget before 2.89.0 and turning one on silently would refuse payments\n * callers are making today. A policy built with `PurchasePolicy.create()`\n * denies any asset it was not given a ceiling for.\n *\n * @see {@link PurchasePolicy}\n */\n policy?: PurchasePolicy;\n /**\n * Include a `token` block in the payload naming the asset, its decimals and\n * its EIP-712 domain.\n *\n * Needed when the resource accepts more than one stablecoin on the same\n * chain: the signature alone does not say which one was paid, so the server\n * cannot rebuild `paymentRequirements`. Off by default — the emitted header\n * stays byte-identical to previous versions.\n */\n includeTokenMetadata?: boolean;\n /**\n * Seconds every EIP-3009 authorization this client signs stays settleable\n * (`validBefore = now + validitySeconds`).\n *\n * The per-payment {@link PaymentInfo.validitySeconds} overrides it; with\n * neither, `DEFAULT_VALIDITY_SECONDS` (300 s) applies, and `MAX_VALIDITY_SECONDS`\n * (3600 s) is the ceiling for both. Until 2.91.0 this\n * was not configurable at all: the window was 300 s on Base and 60 s on every\n * other EVM network, decided by the payer's SDK, which is exactly the party\n * that does not know how long the seller's settlement takes.\n */\n validitySeconds?: number;\n}\n\n/**\n * Default configuration values\n */\nexport const DEFAULT_CONFIG: Required<Pick<X402ClientConfig, 'facilitatorUrl' | 'defaultChain' | 'autoConnect' | 'debug' | 'x402Version'>> = {\n facilitatorUrl: 'https://facilitator.ultravioletadao.xyz',\n defaultChain: 'base',\n autoConnect: false,\n debug: false,\n x402Version: 'auto',\n};\n\n// ============================================================================\n// BALANCE TYPES\n// ============================================================================\n\n/**\n * Balance information for a single network\n */\nexport interface NetworkBalance {\n /** Chain name */\n chainName: string;\n /** Human-readable display name */\n displayName: string;\n /** Formatted balance (e.g., \"15.50\") or null if loading/error */\n balance: string | null;\n /** Whether balance is currently being fetched */\n isLoading: boolean;\n /** Error message if fetch failed */\n error: string | null;\n}\n\n// ============================================================================\n// EVENT TYPES\n// ============================================================================\n\n/**\n * Events emitted by the SDK client\n */\nexport type X402Event =\n | 'connect'\n | 'disconnect'\n | 'chainChanged'\n | 'accountChanged'\n | 'balanceChanged'\n | 'paymentStarted'\n | 'paymentSigned'\n | 'paymentCompleted'\n | 'paymentFailed';\n\n/**\n * Event data types\n */\nexport interface X402EventData {\n connect: WalletState;\n disconnect: void;\n chainChanged: { chainId: number; chainName: string };\n accountChanged: { address: string };\n balanceChanged: { balance: string };\n paymentStarted: { amount: string; network: string };\n paymentSigned: { paymentHeader: string };\n paymentCompleted: PaymentResult;\n paymentFailed: { error: string; code: X402ErrorCode };\n}\n\n/**\n * Event handler type\n */\nexport type X402EventHandler<E extends X402Event> = (data: X402EventData[E]) => void;\n\n// ============================================================================\n// ERROR TYPES\n// ============================================================================\n\n/**\n * Error codes for categorizing errors\n */\nexport type X402ErrorCode =\n | 'WALLET_NOT_FOUND'\n | 'WALLET_NOT_CONNECTED'\n | 'WALLET_NOT_SUPPORTED'\n | 'WALLET_CONNECTION_FAILED'\n | 'WALLET_CONNECTION_REJECTED'\n | 'WALLET_CONNECTION_TIMEOUT'\n | 'CHAIN_NOT_SUPPORTED'\n | 'CHAIN_SWITCH_REJECTED'\n | 'INSUFFICIENT_BALANCE'\n | 'SIGNATURE_REJECTED'\n | 'PAYMENT_FAILED'\n | 'PAYMENT_TIMEOUT'\n | 'NETWORK_ERROR'\n | 'INVALID_CONFIG'\n | 'INVALID_AMOUNT'\n | 'INVALID_RECIPIENT'\n | 'PAYMENT_EXCEEDS_MAX'\n | 'NO_ACCEPTABLE_PAYMENT'\n /**\n * The buyer's own policy refused the offer before anything was signed. The\n * concrete cause is on `PolicyRefusedError.refusal.code` -- see\n * {@link PurchasePolicy}.\n */\n | 'POLICY_REFUSED'\n | 'UNKNOWN_ERROR';\n\n/**\n * SDK-specific error class\n */\nexport class X402Error extends Error {\n public readonly code: X402ErrorCode;\n public readonly details?: unknown;\n\n constructor(message: string, code: X402ErrorCode, details?: unknown) {\n super(message);\n this.name = 'X402Error';\n this.code = code;\n this.details = details;\n\n // Maintains proper stack trace for where error was thrown (V8 engines)\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, X402Error);\n }\n }\n}\n","/**\n * uvd-x402-sdk - UTF-8 safe base64\n *\n * `btoa()` only accepts code points 0-255. Any character above that throws\n * `InvalidCharacterError`, and the X-PAYMENT payload is not guaranteed to be\n * ASCII: the EIP-712 domain name of USDT on Optimism and Arbitrum is literally\n * `USD₮0` (U+20AE). A header carrying that name crashes a plain `btoa()`.\n *\n * So the JSON is UTF-8 encoded to bytes first, and only then base64'd. Decoding\n * reverses it. For ASCII-only input the output is byte-identical to\n * `btoa(json)`, which is why swapping this in cannot change any existing header.\n *\n * `TextEncoder`/`TextDecoder` are available in every browser the SDK targets and\n * in Node 11+; `btoa`/`atob` are used for the byte<->base64 step because they\n * exist in both environments without pulling in `Buffer`.\n */\n\n/**\n * Encode a string as base64, handling non-ASCII characters correctly.\n *\n * @param value - Any UTF-8 string\n * @returns Base64-encoded value\n */\nexport function encodeBase64Utf8(value: string): string {\n const bytes = new TextEncoder().encode(value);\n let binary = '';\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary);\n}\n\n/**\n * Decode a base64 string produced by {@link encodeBase64Utf8}.\n *\n * @param encoded - Base64-encoded value\n * @returns The original UTF-8 string\n */\nexport function decodeBase64Utf8(encoded: string): string {\n const binary = atob(encoded);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return new TextDecoder().decode(bytes);\n}\n\n/**\n * JSON-serialize a value and encode it as UTF-8 safe base64.\n *\n * This is the encoder for every X-PAYMENT header the SDK emits.\n *\n * @param value - Value to serialize\n * @returns Base64-encoded JSON\n */\nexport function encodeBase64Json(value: unknown): string {\n return encodeBase64Utf8(JSON.stringify(value));\n}\n","/**\n * uvd-x402-sdk - x402 Protocol Utilities\n *\n * Utilities for working with x402 v1 and v2 protocols.\n * Handles version detection, payload encoding, and CAIP-2 conversions.\n */\n\nimport type {\n X402Header,\n X402HeaderV1,\n X402HeaderV2,\n X402PayloadData,\n X402PaymentOption,\n X402Version,\n ChainConfig,\n TokenType,\n} from '../types';\nimport { CAIP2_IDENTIFIERS, CAIP2_TO_CHAIN } from '../types';\nimport { getChainByName, getTokenConfig, isUsdPegged } from '../chains';\nimport { decodeBase64Utf8, encodeBase64Json } from './base64';\n\n/**\n * Detect x402 version from a response header or body\n *\n * @param data - The 402 response data (parsed JSON or header value)\n * @returns The detected version (1 or 2)\n */\nexport function detectX402Version(data: unknown): X402Version {\n if (typeof data === 'string') {\n // A `PAYMENT-REQUIRED` header value is base64 JSON, and the doc above\n // invites one. Returning 1 without decoding misread every v2 challenge as\n // v1 — silently, as a plausible value rather than an error, and the two\n // wire forms are structurally incompatible.\n //\n // This is not hypothetical: measured 2026-08-20, 36 of 36 live Bazaar\n // resources answering 402 carry the challenge in the header, and several\n // put a free content preview in the body, so the header is the only place\n // the version signal exists.\n const trimmed = data.trim();\n if (!trimmed) return 1;\n for (const decode of [\n () => JSON.parse(decodeBase64Utf8(trimmed)),\n () => JSON.parse(trimmed),\n ]) {\n try {\n const parsed = decode();\n if (typeof parsed === 'object' && parsed !== null) {\n return detectX402Version(parsed);\n }\n } catch {\n // not this encoding; try the next\n }\n }\n return 1; // undecodable: fall back to v1, as before\n }\n\n if (typeof data !== 'object' || data === null) {\n return 1; // Default to v1\n }\n\n const obj = data as Record<string, unknown>;\n\n // Check explicit version field\n if (obj.x402Version === 2) {\n return 2;\n }\n\n // Check for v2 indicators\n if (obj.accepts && Array.isArray(obj.accepts)) {\n return 2;\n }\n\n // `paymentRequirements` is the v1 spelling, so its presence points at v1 --\n // but only when there is no v2 signal, which the checks above already ruled\n // out. Recognised so the value is not treated as an unknown shape.\n if (Array.isArray(obj.paymentRequirements)) {\n return 1;\n }\n\n // Check if network is in CAIP-2 format\n if (typeof obj.network === 'string') {\n if (obj.network.includes(':')) {\n return 2;\n }\n }\n\n return 1;\n}\n\n/**\n * Convert chain name to CAIP-2 identifier\n *\n * @param chainName - Chain name (e.g., 'base', 'solana')\n * @returns CAIP-2 identifier (e.g., 'eip155:8453', 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp')\n */\nexport function chainToCAIP2(chainName: string): string {\n // Resolve through the registry FIRST, so an alias answers with the canonical\n // chain's id rather than one built out of the alias. Without this, asking\n // with `xrpl-mainnet` fell past the lookup into the fallback below and\n // manufactured `xrpl:xrpl-mainnet` -- a well-formed CAIP-2 string that no\n // facilitator has ever accepted, and one that PASSES the colon test every v2\n // guard in this SDK uses. A fabricated id is worse than a missing one: the\n // missing one is refused loudly, the fabricated one ships.\n const chain = getChainByName(chainName);\n const caip2 = CAIP2_IDENTIFIERS[(chain?.name ?? chainName).toLowerCase()];\n if (caip2) {\n return caip2;\n }\n\n // Try to construct from chain config\n if (chain) {\n if (chain.networkType === 'evm') {\n return `eip155:${chain.chainId}`;\n }\n // For non-EVM, return the canonical name with the network prefix\n return `${chain.networkType}:${chain.name}`;\n }\n\n return chainName; // Return as-is if unknown\n}\n\n/**\n * Convert CAIP-2 identifier to chain name\n *\n * @param caip2 - CAIP-2 identifier\n * @returns Chain name or null if unknown\n */\nexport function caip2ToChain(caip2: string): string | null {\n // Check direct mapping\n if (CAIP2_TO_CHAIN[caip2]) {\n return CAIP2_TO_CHAIN[caip2];\n }\n\n // Try to extract from EIP-155 format\n const match = caip2.match(/^eip155:(\\d+)$/);\n if (match) {\n const chainId = parseInt(match[1], 10);\n // Find chain by ID\n for (const [name, _config] of Object.entries(CAIP2_IDENTIFIERS)) {\n const chain = getChainByName(name);\n if (chain?.chainId === chainId) {\n return name;\n }\n }\n }\n\n // Try to extract from network:name format\n const parts = caip2.split(':');\n if (parts.length === 2) {\n const networkName = parts[1];\n if (getChainByName(networkName)) {\n return networkName;\n }\n }\n\n return null;\n}\n\n/**\n * Parse network identifier from either v1 or v2 format\n *\n * @param network - Network identifier (v1 string or v2 CAIP-2)\n * @returns Normalized chain name\n */\nexport function parseNetworkIdentifier(network: string): string {\n // If it contains a colon, it's likely CAIP-2\n if (network.includes(':')) {\n return caip2ToChain(network) || network;\n }\n return network.toLowerCase();\n}\n\n/**\n * Encode x402 payload as base64 header value\n *\n * @param header - The x402 header object\n * @returns Base64-encoded string\n */\nexport function encodeX402Header(header: X402Header): string {\n return encodeBase64Json(header);\n}\n\n/**\n * Decode x402 header from base64 string\n *\n * @param encoded - Base64-encoded header value\n * @returns Parsed x402 header\n */\nexport function decodeX402Header(encoded: string): X402Header {\n const json = decodeBase64Utf8(encoded);\n return JSON.parse(json) as X402Header;\n}\n\n/**\n * Create x402 v1 header\n *\n * @param network - Chain name (e.g., 'base')\n * @param payload - Network-specific payload\n * @returns x402 v1 header object\n */\nexport function createX402V1Header(\n network: string,\n payload: X402PayloadData\n): X402HeaderV1 {\n if (getChainByName(network)?.networkType === 'hedera') throw new Error('Native Hedera supports only x402 v2');\n return {\n x402Version: 1,\n scheme: 'exact',\n network,\n payload,\n };\n}\n\n/**\n * Create x402 v2 header\n *\n * @param network - CAIP-2 network identifier\n * @param payload - Network-specific payload\n * @param accepts - Optional array of payment options\n * @returns x402 v2 header object\n */\nexport function createX402V2Header(\n network: string,\n payload: X402PayloadData,\n accepts?: X402PaymentOption[]\n): X402HeaderV2 {\n const header: X402HeaderV2 = {\n x402Version: 2,\n scheme: 'exact',\n network: network.includes(':') ? network : chainToCAIP2(network),\n payload,\n };\n\n if (accepts && accepts.length > 0) {\n header.accepts = accepts;\n }\n\n return header;\n}\n\n/**\n * Create x402 header with automatic version selection\n *\n * @param chainConfig - Chain configuration\n * @param payload - Network-specific payload\n * @param version - Version to use (1, 2, or 'auto')\n * @returns x402 header object\n */\nexport function createX402Header(\n chainConfig: ChainConfig,\n payload: X402PayloadData,\n version: X402Version | 'auto' = 'auto'\n): X402Header {\n // Default to v1 for maximum compatibility\n const effectiveVersion = version === 'auto' ? 1 : version;\n\n if (effectiveVersion === 2) {\n return createX402V2Header(chainConfig.name, payload);\n }\n\n return createX402V1Header(chainConfig.name, payload);\n}\n\n/**\n * Generate payment options array for multi-network support\n *\n * One entry per (chain, token) pair. By default the token is USDC on every\n * chain, which is exactly what this emitted before `tokens` existed.\n *\n * **`tokens` is opt-in on purpose, and the reason is money.** The chain\n * registry knows more stablecoins than USDC (Base also has EURC), and it is\n * tempting to just emit all of them. But this array becomes the `accepts` of a\n * `402`, so every entry is a currency the seller has publicly agreed to be paid\n * in -- at `amount` units of it. Emitting EURC for a seller who priced in\n * dollars would quietly sell at a 1:1 EUR/USD rate nobody agreed to. So the\n * caller names the tokens it actually accepts, and `amount` is read as units of\n * each named token, NOT converted between them.\n *\n * A token a chain does not have is skipped: an option is only emitted for pairs\n * the registry can actually price.\n *\n * @param chainConfigs - Array of chain configurations\n * @param amount - Amount in units of each token (e.g., \"10.00\")\n * @param facilitator - Optional facilitator URL override\n * @param tokens - Tokens to offer per chain (default: `['usdc']`)\n * @returns Array of x402 v2 payment options\n *\n * @example\n * ```ts\n * // Dollars only -- the default, and what every existing caller gets.\n * generatePaymentOptions([base], '5.00');\n *\n * // Dollars or euros, priced separately and both genuinely accepted.\n * generatePaymentOptions([base], '5.00', undefined, ['usdc', 'eurc']);\n * ```\n */\nexport function generatePaymentOptions(\n chainConfigs: ChainConfig[],\n amount: string,\n facilitator?: string,\n tokens: TokenType[] = ['usdc']\n): X402PaymentOption[] {\n const options: X402PaymentOption[] = [];\n\n for (const chain of chainConfigs) {\n if (!chain.x402.enabled) continue;\n\n for (const tokenType of tokens) {\n const token = getTokenConfig(chain.name, tokenType);\n if (!token) continue;\n\n // A token with no dollar peg is skipped for the same reason a missing one\n // is: this array can only carry pairs the registry can actually price.\n // XRPL reaches here because it files native XRP under the key `usdc`, so\n // the loop would otherwise emit \"5 XRP\" for a seller who wrote `'5.00'`\n // and asked for dollars.\n //\n // SKIP, not throw, and that is deliberate. This builds the `accepts` of\n // ONE 402 covering MANY chains -- the usual call is every enabled chain\n // at once -- so throwing would take the whole response down over a single\n // unpriceable pair and cost the seller the chains that were fine.\n // `buildPaymentRequirements` names one chain and therefore throws there.\n // EURC is available only through an explicitly named token: the caller\n // has chosen euros here. The default USDC path still excludes native XRP.\n if (!isUsdPegged(token) && tokenType !== 'eurc') continue;\n\n // Atomic units in THIS token's decimals -- BSC USDC has 18, not 6.\n const atomicAmount = Math.floor(\n parseFloat(amount) * Math.pow(10, token.decimals)\n ).toString();\n\n options.push({\n network: chainToCAIP2(chain.name),\n asset: token.address,\n amount: atomicAmount,\n facilitator: facilitator || chain.x402.facilitatorUrl,\n });\n }\n }\n\n return options;\n}\n\n/**\n * Check if a network string is in CAIP-2 format\n *\n * @param network - Network identifier\n * @returns True if CAIP-2 format\n */\nexport function isCAIP2Format(network: string): boolean {\n return network.includes(':');\n}\n\n/**\n * Convert between x402 v1 and v2 header formats\n *\n * @param header - Source header\n * @param targetVersion - Target version\n * @returns Converted header\n */\nexport function convertX402Header(\n header: X402Header,\n targetVersion: X402Version\n): X402Header {\n if (header.x402Version === targetVersion) {\n return header;\n }\n\n if (targetVersion === 2) {\n // v1 -> v2\n return {\n x402Version: 2,\n scheme: 'exact',\n network: chainToCAIP2(header.network),\n payload: header.payload,\n };\n } else {\n // v2 -> v1\n const chainName = isCAIP2Format(header.network)\n ? caip2ToChain(header.network) || header.network\n : header.network;\n\n return {\n x402Version: 1,\n scheme: 'exact',\n network: chainName,\n payload: header.payload,\n };\n }\n}\n\n/**\n * Read a 402 payment challenge from wherever the seller put it.\n *\n * x402 allows BOTH transports and sellers pick freely:\n *\n * - base64 JSON in the `PAYMENT-REQUIRED` (or `X-PAYMENT-REQUIRED`) header\n * - JSON in the response body\n *\n * Measured against production on 2026-08-20: of 40 live Bazaar resources,\n * **36 of 36 that answered 402 carried the challenge in the header, and none in\n * the body**. Worse, sellers like Tenjin use the 402 body for a free preview of\n * the paid content — so the body is valid JSON that simply has no `accepts`, and\n * a body-only reader parses it happily and finds nothing.\n *\n * Reads the header first because that is where live sellers put it, and falls\n * back to the body so the sellers who use it keep working.\n *\n * Returns `null` when neither transport carries a challenge — a real \"no terms\n * here\", distinct from a challenge we failed to decode.\n */\nexport function paymentChallengeFrom(\n headers: { get(name: string): string | null } | Record<string, string>,\n body?: unknown,\n): Record<string, unknown> | null {\n const read = (name: string): string | null => {\n if (typeof (headers as { get?: unknown }).get === 'function') {\n return (headers as { get(n: string): string | null }).get(name);\n }\n const rec = headers as Record<string, string>;\n return rec[name] ?? rec[name.toLowerCase()] ?? rec[name.toUpperCase()] ?? null;\n };\n\n const raw = read('payment-required') ?? read('x-payment-required');\n if (raw) {\n const trimmed = raw.trim();\n for (const decode of [\n () => JSON.parse(decodeBase64Utf8(trimmed)),\n () => JSON.parse(trimmed),\n ]) {\n try {\n const parsed = decode();\n if (isChallenge(parsed)) return parsed as Record<string, unknown>;\n } catch {\n // not this encoding; try the next\n }\n }\n }\n\n const parsedBody = typeof body === 'string' ? tryJson(body) : body;\n return isChallenge(parsedBody) ? (parsedBody as Record<string, unknown>) : null;\n}\n\n/**\n * Whether a value actually looks like an x402 challenge.\n *\n * Deliberately stricter than \"is an object\": a 402 body carrying a free preview\n * is valid JSON with no payment terms in it, and treating that as a challenge is\n * how a body-only reader concludes it looked and found nothing wrong.\n */\nfunction isChallenge(v: unknown): boolean {\n if (typeof v !== 'object' || v === null) return false;\n const o = v as Record<string, unknown>;\n // `paymentRequirements` is the v1 spelling of `accepts`. Missing it made a\n // seller using it look like \"no terms here\" — the exact false negative this\n // function exists to prevent. Found in the Python SDK by KarmaKadabra's\n // buyer, which matched both keys in production, 2026-08-20.\n return (\n Array.isArray(o.accepts) ||\n Array.isArray(o.paymentRequirements) ||\n typeof o.payTo === 'string'\n );\n}\n\nfunction tryJson(s: string): unknown {\n try {\n return JSON.parse(s);\n } catch {\n return null;\n }\n}\n","/**\n * uvd-x402-sdk - Token metadata for payment payloads\n *\n * An EIP-3009 authorization is signed against a token contract, but the encoded\n * payload only carries the signature and the transfer fields. The token itself\n * is implicit — the server is expected to already know which asset it asked\n * for.\n *\n * That holds when a resource accepts exactly one token per chain. It breaks as\n * soon as it accepts several: a EURC payment and a USDC payment on Base produce\n * indistinguishable payloads, and the server cannot build the\n * `paymentRequirements` (`asset` + `extra`) the facilitator needs to settle.\n *\n * So the payment can opt into carrying the token with it.\n */\n\nimport { getTokenByAddress } from '../chains';\nimport type { PaymentTokenMetadata } from '../types';\n\n/**\n * Build the token metadata block for a payload, resolving the address against\n * the chain registry.\n *\n * @param chainName - Chain the payment was signed for\n * @param address - Token contract address from the signed payload\n * @returns Metadata block, or undefined if the address is not in the registry\n */\nexport function buildTokenMetadata(\n chainName: string,\n address: string\n): PaymentTokenMetadata | undefined {\n const match = getTokenByAddress(chainName, address);\n if (!match) return undefined;\n\n return {\n address: match.config.address,\n symbol: match.tokenType.toUpperCase(),\n decimals: match.config.decimals,\n eip712: {\n name: match.config.name,\n version: match.config.version,\n },\n };\n}\n","/**\n * uvd-x402-sdk - Validation and Payment Header Utilities\n *\n * Functions for validating payment parameters and creating\n * payment headers for HTTP requests.\n */\n\nimport type { X402HeaderName, PaymentHeaders } from '../types';\nimport { X402Error } from '../types';\n\n/**\n * Regular expression for validating Ethereum addresses\n */\nconst ETH_ADDRESS_REGEX = /^0x[a-fA-F0-9]{40}$/;\n\n/**\n * Regular expression for validating Solana addresses (base58, 32-44 chars)\n */\nconst SOLANA_ADDRESS_REGEX = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/;\n\n/**\n * Regular expression for validating Stellar addresses (G... format)\n */\nconst STELLAR_ADDRESS_REGEX = /^G[A-Z2-7]{55}$/;\n\n/**\n * Regular expression for validating NEAR addresses\n */\nconst NEAR_ADDRESS_REGEX = /^[a-z0-9._-]+$/;\n\n/**\n * Regular expression for validating XRPL classic addresses (r... base58, Ripple alphabet)\n */\nconst XRPL_ADDRESS_REGEX = /^r[1-9A-HJ-NP-Za-km-z]{24,34}$/;\n\n/**\n * Validate that a recipient address is present and valid\n *\n * This function ensures that:\n * 1. The recipient is not null, undefined, or empty\n * 2. The recipient is not just whitespace\n * 3. For EVM, it's a valid checksummed or lowercase 0x address\n *\n * @param recipient - The recipient address to validate\n * @param networkType - Optional network type for format validation\n * @throws X402Error with code 'INVALID_RECIPIENT' if validation fails\n */\nexport function validateRecipient(\n recipient: string | undefined | null,\n networkType?: 'evm' | 'svm' | 'solana' | 'stellar' | 'near' | 'xrpl' | 'hedera'\n): asserts recipient is string {\n // Check for null, undefined, or empty\n if (!recipient) {\n throw new X402Error(\n 'Recipient address is required. The payTo/recipient field cannot be empty. ' +\n 'Please provide a valid recipient address where payments should be sent.',\n 'INVALID_RECIPIENT'\n );\n }\n\n // Check for whitespace-only\n const trimmed = recipient.trim();\n if (trimmed === '') {\n throw new X402Error(\n 'Recipient address cannot be empty or whitespace. ' +\n 'Please provide a valid recipient address.',\n 'INVALID_RECIPIENT'\n );\n }\n\n // Network-specific validation\n if (networkType) {\n switch (networkType) {\n case 'evm':\n if (!ETH_ADDRESS_REGEX.test(trimmed)) {\n throw new X402Error(\n `Invalid EVM recipient address: \"${trimmed}\". ` +\n 'Expected a 40-character hexadecimal address starting with 0x.',\n 'INVALID_RECIPIENT'\n );\n }\n break;\n\n case 'svm':\n case 'solana':\n if (!SOLANA_ADDRESS_REGEX.test(trimmed)) {\n throw new X402Error(\n `Invalid Solana recipient address: \"${trimmed}\". ` +\n 'Expected a base58-encoded public key (32-44 characters).',\n 'INVALID_RECIPIENT'\n );\n }\n break;\n\n case 'stellar':\n if (!STELLAR_ADDRESS_REGEX.test(trimmed)) {\n throw new X402Error(\n `Invalid Stellar recipient address: \"${trimmed}\". ` +\n 'Expected a G-prefixed public key (56 characters).',\n 'INVALID_RECIPIENT'\n );\n }\n break;\n\n case 'near':\n if (!NEAR_ADDRESS_REGEX.test(trimmed) || trimmed.length > 64) {\n throw new X402Error(\n `Invalid NEAR recipient address: \"${trimmed}\". ` +\n 'Expected a valid NEAR account ID.',\n 'INVALID_RECIPIENT'\n );\n }\n break;\n\n case 'hedera':\n if (!/^0\\.0\\.[1-9][0-9]*$/.test(trimmed)) {\n throw new X402Error('Hedera recipient must be a native numeric account ID', 'INVALID_RECIPIENT');\n }\n break;\n\n case 'xrpl':\n if (!XRPL_ADDRESS_REGEX.test(trimmed)) {\n throw new X402Error(\n `Invalid XRPL recipient address: \"${trimmed}\". ` +\n 'Expected a classic r-address (base58, Ripple alphabet).',\n 'INVALID_RECIPIENT'\n );\n }\n break;\n }\n }\n}\n\n/**\n * Validate payment amount\n *\n * Ensures the amount is a valid positive number string\n *\n * @param amount - The amount string to validate\n * @throws X402Error with code 'INVALID_AMOUNT' if validation fails\n */\nexport function validateAmount(amount: string | undefined | null): asserts amount is string {\n if (!amount) {\n throw new X402Error(\n 'Payment amount is required.',\n 'INVALID_AMOUNT'\n );\n }\n\n const trimmed = amount.trim();\n if (trimmed === '') {\n throw new X402Error(\n 'Payment amount cannot be empty.',\n 'INVALID_AMOUNT'\n );\n }\n\n // Parse as number\n const num = parseFloat(trimmed);\n if (isNaN(num)) {\n throw new X402Error(\n `Invalid payment amount: \"${trimmed}\". Expected a valid number.`,\n 'INVALID_AMOUNT'\n );\n }\n\n if (num <= 0) {\n throw new X402Error(\n `Payment amount must be positive. Got: ${trimmed}`,\n 'INVALID_AMOUNT'\n );\n }\n}\n\n// ============================================================================\n// PAYMENT HEADER UTILITIES\n// ============================================================================\n\n/**\n * Create payment headers object from a base64-encoded payload\n *\n * Returns an object with both X-PAYMENT and PAYMENT-SIGNATURE headers,\n * making it easy to use either header format.\n *\n * @param paymentHeader - Base64-encoded payment payload\n * @returns PaymentHeaders object with both header formats\n *\n * @example\n * ```ts\n * const headers = createPaymentHeaders(paymentHeader);\n *\n * // Use v1 header (most compatible)\n * fetch(url, { headers: { 'X-PAYMENT': headers['X-PAYMENT'] } });\n *\n * // Use v2 header\n * fetch(url, { headers: { 'PAYMENT-SIGNATURE': headers['PAYMENT-SIGNATURE'] } });\n * ```\n */\nexport function createPaymentHeaders(paymentHeader: string): PaymentHeaders {\n return {\n 'X-PAYMENT': paymentHeader,\n 'PAYMENT-SIGNATURE': paymentHeader,\n };\n}\n\n/**\n * Get a single payment header by name\n *\n * @param paymentHeader - Base64-encoded payment payload\n * @param headerName - Header name to use ('X-PAYMENT' or 'PAYMENT-SIGNATURE')\n * @returns Object with a single header entry\n *\n * @example\n * ```ts\n * // Use with fetch spread operator\n * fetch(url, {\n * headers: {\n * 'Content-Type': 'application/json',\n * ...getPaymentHeader(result.paymentHeader, 'X-PAYMENT'),\n * },\n * });\n * ```\n */\nexport function getPaymentHeader(\n paymentHeader: string,\n headerName: X402HeaderName = 'X-PAYMENT'\n): Record<X402HeaderName, string> {\n return { [headerName]: paymentHeader } as Record<X402HeaderName, string>;\n}\n\n/**\n * Default x402 payment header name\n *\n * Use 'X-PAYMENT' for maximum compatibility with all facilitators.\n * Use 'PAYMENT-SIGNATURE' for x402 v2 compliance.\n */\nexport const DEFAULT_PAYMENT_HEADER: X402HeaderName = 'X-PAYMENT';\n\n/**\n * All supported x402 payment header names\n */\nexport const PAYMENT_HEADER_NAMES: readonly X402HeaderName[] = [\n 'X-PAYMENT',\n 'PAYMENT-SIGNATURE',\n] as const;\n","/**\n * uvd-x402-sdk - EIP-191 personal_sign helpers\n *\n * Generic recover/verify for an EIP-191 `personal_sign` over an arbitrary\n * string message — the shape a wallet produces for `eth_sign`/`personal_sign`\n * and `cast wallet sign <message>`.\n *\n * This is deliberately NOT the ERC-8128 machinery (`verifyRequest`), which\n * verifies an RFC 9421 SIGNED HTTP REQUEST (method;url;headers;content-digest).\n * A challenge/response flow — a service hands out a nonce string, the wallet\n * signs that string, the service recovers the signer — is a different, simpler\n * case that the ERC-8128 path does not cover. Consumers doing wallet-ownership\n * challenges (e.g. MeshRelay's IRC `VERIFY`/`VERIFY-SIG`) needed this and were\n * each reaching for `ethers.verifyMessage` directly; this centralizes it.\n */\n\nimport { ethers } from 'ethers';\n\n/**\n * Recover the address that produced an EIP-191 `personal_sign` over `message`.\n *\n * @param message - the exact string that was signed\n * @param signature - the 0x-prefixed signature\n * @returns the checksummed recovered address\n * @throws if the signature is malformed (propagates ethers' error)\n */\nexport function recoverPersonalSignAddress(message: string, signature: string): string {\n return ethers.verifyMessage(message, signature);\n}\n\n/**\n * Whether `signature` over `message` was produced by `expected`.\n *\n * Compares case-insensitively (recovered addresses are checksummed, linked\n * wallets are often stored lower-cased) and never throws: a malformed\n * signature is a failed verification, not an exception to handle at every\n * call site.\n *\n * @returns true iff the recovered signer equals `expected`\n */\nexport function verifyPersonalSign(params: {\n message: string;\n signature: string;\n expected: string;\n}): boolean {\n const { message, signature, expected } = params;\n if (!expected) return false;\n try {\n const recovered = recoverPersonalSignAddress(message, signature);\n return recovered.toLowerCase() === expected.toLowerCase();\n } catch {\n return false;\n }\n}\n","/**\n * uvd-x402-sdk - EIP-3009 validity window\n *\n * How long a signed authorization stays settleable: `validBefore = now +\n * validitySeconds`. One definition, read by every EVM signing path, because the\n * number used to be written twice — `X402Client.createEVMPayment` and\n * `EVMProvider.signPayment` each carried their own copy of a per-chain ternary:\n * 300 s on Base, 60 s on every other network.\n *\n * Why the per-chain ternary is gone: the window is not a property of the chain,\n * it is how long the SELLER needs to settle, and the seller is the one party\n * that could not set it. A seller that settles async — verify, hand over the\n * resource, settle afterwards — has to land the settlement inside this window\n * or the authorization expires by itself and a paid-for resource gets revoked.\n * That is MeshRelay Turnstile's exact flow. On Base (300 s) nobody ever felt it;\n * on the other eleven EVM networks the buyer had 60 s, minus the facilitator's\n * 6 s clock-skew grace, to open a wallet and sign.\n *\n * Why 300 and not 60 or 3600 — where the number actually comes from:\n * - it is the timeout the seller side of THIS SDK announces by default\n * (`DEFAULT_PAYMENT_TIMEOUT_SECONDS` in `src/backend/index.ts`), so a buyer\n * and a seller both built on `uvd-x402-sdk` agree without configuring\n * anything;\n * - it is what MeshRelay Turnstile, the async seller that surfaced this,\n * announces (`timeoutSeconds: 300` in its `turnstile/payments.js`);\n * - it is the fallback the facilitator's catalog applies to a seller entry\n * that omits the field (`DEFAULT_MAX_TIMEOUT_SECS` in `x402-rs`\n * `src/discovery_price.rs`). That is a catalog default, not a timeout the\n * facilitator enforces or advertises for itself: its `/supported` carries\n * no timeout at all.\n *\n * The facilitator only ever rejects a window for being too SHORT — `assert_time`\n * (`x402-rs`, `src/chain/evm.rs`), which runs in both verify and settle, refuses\n * `valid_before < now + 6 s` — and compares `valid_before` against no ceiling.\n * That is why the ceiling below lives in the payer's SDK, and why signing LESS\n * than a seller declared is the failure that bites.\n *\n * When the seller's 402 declares `maxTimeoutSeconds`, `X402Client.fetch()` signs\n * that window instead of the client's own; see {@link clampValiditySeconds}.\n *\n * The Python SDK's equivalent (`valid_duration`, 3600 s) stays where it is: the\n * two SDKs still differ, but both are configurable now.\n */\n\nimport { X402Error } from '../types';\n\n/**\n * Seconds an EIP-3009 authorization stays valid when nobody says otherwise.\n *\n * Exported so a consumer can READ the effective default instead of re-typing\n * `300` in its own timeout math.\n */\nexport const DEFAULT_VALIDITY_SECONDS = 300;\n\n/**\n * Longest window this SDK will sign, one hour.\n *\n * A ceiling exists because the seller gets a say in the window: `fetch()`\n * honours the `maxTimeoutSeconds` a 402 declares, and {@link PaymentInfo} is\n * shaped like \"what the backend returned on its 402\", so a caller that hands a\n * parsed 402 body straight to `createPayment` lets the seller pick too. Without\n * a limit, a year-long window is a standing claim on the payer's balance: the\n * resource is never delivered, the authorization looks expired to a buyer who\n * assumed minutes, and it settles months later against a funded wallet.\n * Cancelling one costs gas and knowing the nonce.\n *\n * 3600 and not something rounder: it is the largest window anything in this\n * stack signs today — the Python SDK's `valid_duration` default — so nothing\n * that works now is refused by this limit.\n */\nexport const MAX_VALIDITY_SECONDS = 3600;\n\n/**\n * Pick the validity window for one payment, most specific source first.\n *\n * @param perPayment - `PaymentInfo.validitySeconds`, the window for this single\n * payment. Wins over everything.\n * @param clientDefault - `X402ClientConfig.validitySeconds`, the window this\n * client signs with when a payment does not ask for one.\n * @returns The window in whole seconds; {@link DEFAULT_VALIDITY_SECONDS} when\n * neither source named one.\n * @throws {X402Error} `INVALID_CONFIG` when a source named something that is not\n * a positive whole number of seconds, or more than\n * {@link MAX_VALIDITY_SECONDS}. Thrown rather than silently falling back to\n * the default: a caller that asked for a window and got a different one would\n * be signing an authorization it did not choose, and the mistake would only\n * surface as a failed settlement much later.\n */\nexport function resolveValiditySeconds(\n perPayment?: number,\n clientDefault?: number\n): number {\n const chosen = perPayment ?? clientDefault ?? DEFAULT_VALIDITY_SECONDS;\n\n // `Number.isInteger` is false for NaN, Infinity and 1.5 alike, and a\n // fractional window would reach `validBefore` as a fractional unix timestamp\n // that the EIP-712 uint256 encoder rejects anyway — just later, and with a\n // message about the signature rather than about the window.\n if (!Number.isInteger(chosen) || chosen <= 0) {\n throw new X402Error(\n `validitySeconds must be a positive whole number of seconds, got ${String(chosen)}`,\n 'INVALID_CONFIG',\n { validitySeconds: chosen }\n );\n }\n\n if (chosen > MAX_VALIDITY_SECONDS) {\n throw new X402Error(\n `validitySeconds must be at most ${MAX_VALIDITY_SECONDS} seconds, got ${String(chosen)}. ` +\n 'A longer window is a standing claim on the payer: it can be settled long ' +\n 'after the payer gave the payment up for expired.',\n 'INVALID_CONFIG',\n { validitySeconds: chosen, max: MAX_VALIDITY_SECONDS }\n );\n }\n\n return chosen;\n}\n\n/**\n * The window to sign when a seller's 402 declared `maxTimeoutSeconds`.\n *\n * The seller's number wins over the client's configured window: it is the one\n * party that knows how long its settlement takes, and since the facilitator\n * never rejects a window for being long, signing less than it declared only\n * produces an authorization that dies before the seller's own settle.\n *\n * Clamped to `[1, MAX_VALIDITY_SECONDS]` rather than refused, because a 402 is\n * the seller's declaration and not the buyer's config: a seller asking for a\n * day still gets paid, inside the payer's ceiling. A fractional declaration is\n * floored.\n */\nexport function clampValiditySeconds(maxTimeoutSeconds: number): number {\n return Math.min(MAX_VALIDITY_SECONDS, Math.max(1, Math.floor(maxTimeoutSeconds)));\n}\n","/**\n * uvd-x402-sdk - Utilities\n *\n * Re-exports all utility functions.\n */\n\nexport {\n detectX402Version,\n paymentChallengeFrom,\n chainToCAIP2,\n caip2ToChain,\n parseNetworkIdentifier,\n encodeX402Header,\n decodeX402Header,\n createX402V1Header,\n createX402V2Header,\n createX402Header,\n generatePaymentOptions,\n isCAIP2Format,\n convertX402Header,\n} from './x402';\n\nexport { buildTokenMetadata } from './token-metadata';\n\nexport {\n encodeBase64Utf8,\n decodeBase64Utf8,\n encodeBase64Json,\n} from './base64';\n\nexport {\n validateRecipient,\n validateAmount,\n createPaymentHeaders,\n getPaymentHeader,\n DEFAULT_PAYMENT_HEADER,\n PAYMENT_HEADER_NAMES,\n} from './validation';\n\nexport {\n recoverPersonalSignAddress,\n verifyPersonalSign,\n} from './personal-sign';\n\nexport {\n DEFAULT_VALIDITY_SECONDS,\n MAX_VALIDITY_SECONDS,\n resolveValiditySeconds,\n clampValiditySeconds,\n} from './validity';\n","/**\n * uvd-x402-sdk - SVM Provider (Solana Virtual Machine)\n *\n * Provides wallet connection and payment creation for SVM-based chains via Phantom.\n * Supports: Solana, Fogo\n * Uses partially-signed transactions where the facilitator is the fee payer.\n *\n * @example Solana\n * ```ts\n * import { SVMProvider } from 'uvd-x402-sdk/solana';\n * import { getChainByName } from 'uvd-x402-sdk';\n *\n * const svm = new SVMProvider();\n *\n * // Connect\n * const address = await svm.connect();\n *\n * // Create Solana payment\n * const chainConfig = getChainByName('solana')!;\n * const paymentPayload = await svm.signPayment(paymentInfo, chainConfig);\n * const header = svm.encodePaymentHeader(paymentPayload, chainConfig);\n * ```\n *\n * @example Fogo\n * ```ts\n * import { SVMProvider } from 'uvd-x402-sdk/solana';\n * import { getChainByName } from 'uvd-x402-sdk';\n *\n * const svm = new SVMProvider();\n *\n * // Connect (same wallet works for all SVM chains)\n * const address = await svm.connect();\n *\n * // Create Fogo payment\n * const chainConfig = getChainByName('fogo')!;\n * const paymentPayload = await svm.signPayment(paymentInfo, chainConfig);\n * const header = svm.encodePaymentHeader(paymentPayload, chainConfig);\n * ```\n */\n\nimport type {\n ChainConfig,\n PaymentInfo,\n SolanaPaymentPayload,\n TokenInfo,\n WalletAdapter,\n X402Version,\n} from '../../types';\nimport { X402Error } from '../../types';\nimport { getChainByName } from '../../chains';\nimport { chainToCAIP2, encodeBase64Json } from '../../utils';\n\n/**\n * Browser-compatible base64 encoding for Uint8Array\n * Avoids Node.js Buffer dependency for browser bundlers\n */\nfunction uint8ArrayToBase64(bytes: Uint8Array): string {\n let binary = '';\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary);\n}\n\n// Lazy import Solana dependencies to avoid bundling when not used\nlet Connection: typeof import('@solana/web3.js').Connection;\nlet PublicKey: typeof import('@solana/web3.js').PublicKey;\nlet TransactionMessage: typeof import('@solana/web3.js').TransactionMessage;\nlet VersionedTransaction: typeof import('@solana/web3.js').VersionedTransaction;\nlet ComputeBudgetProgram: typeof import('@solana/web3.js').ComputeBudgetProgram;\nlet getAssociatedTokenAddress: typeof import('@solana/spl-token').getAssociatedTokenAddress;\nlet createTransferCheckedInstruction: typeof import('@solana/spl-token').createTransferCheckedInstruction;\nlet createAssociatedTokenAccountIdempotentInstruction: typeof import('@solana/spl-token').createAssociatedTokenAccountIdempotentInstruction;\nlet TOKEN_PROGRAM_ID: typeof import('@solana/spl-token').TOKEN_PROGRAM_ID;\n\nasync function loadSolanaDeps() {\n if (!Connection) {\n const web3 = await import('@solana/web3.js');\n const splToken = await import('@solana/spl-token');\n Connection = web3.Connection;\n PublicKey = web3.PublicKey;\n TransactionMessage = web3.TransactionMessage;\n VersionedTransaction = web3.VersionedTransaction;\n ComputeBudgetProgram = web3.ComputeBudgetProgram;\n getAssociatedTokenAddress = splToken.getAssociatedTokenAddress;\n createTransferCheckedInstruction = splToken.createTransferCheckedInstruction;\n createAssociatedTokenAccountIdempotentInstruction = splToken.createAssociatedTokenAccountIdempotentInstruction;\n TOKEN_PROGRAM_ID = splToken.TOKEN_PROGRAM_ID;\n }\n}\n\n/**\n * Phantom wallet provider interface\n */\ninterface PhantomProvider {\n isPhantom?: boolean;\n isConnected?: boolean;\n publicKey?: { toBase58(): string };\n connect(): Promise<{ publicKey: { toBase58(): string } }>;\n disconnect(): Promise<void>;\n signTransaction<T>(transaction: T): Promise<T>;\n}\n\n/**\n * SVMProvider - Wallet adapter for SVM chains (Solana, Fogo) via Phantom\n *\n * @alias SolanaProvider for backward compatibility\n */\nexport class SVMProvider implements WalletAdapter {\n readonly id = 'phantom';\n readonly name = 'Phantom';\n readonly networkType = 'svm' as const;\n\n private provider: PhantomProvider | null = null;\n private publicKey: InstanceType<typeof PublicKey> | null = null;\n private connections: Map<string, InstanceType<typeof Connection>> = new Map();\n private address: string | null = null;\n\n /**\n * Check if Phantom wallet is available\n */\n isAvailable(): boolean {\n if (typeof window === 'undefined') return false;\n return !!(\n (window as Window & { phantom?: { solana?: PhantomProvider } }).phantom?.solana?.isPhantom ||\n (window as Window & { solana?: PhantomProvider }).solana?.isPhantom\n );\n }\n\n /**\n * Connect to Phantom wallet\n */\n async connect(): Promise<string> {\n await loadSolanaDeps();\n\n // Get Phantom provider\n this.provider = await this.getPhantomProvider();\n if (!this.provider) {\n throw new X402Error(\n 'Phantom wallet not installed. Please install from phantom.app',\n 'WALLET_NOT_FOUND'\n );\n }\n\n try {\n // Check if already connected\n if (this.provider.publicKey && this.provider.isConnected) {\n const publicKeyString = this.provider.publicKey.toBase58();\n this.publicKey = new PublicKey(publicKeyString);\n this.address = publicKeyString;\n await this.initConnection();\n return publicKeyString;\n }\n\n // Connect\n const resp = await this.provider.connect();\n const publicKeyString = resp.publicKey.toBase58();\n\n this.publicKey = new PublicKey(publicKeyString);\n this.address = publicKeyString;\n\n await this.initConnection();\n\n return publicKeyString;\n } catch (error: unknown) {\n if (error instanceof Error) {\n if (error.message.includes('User rejected') || (error as { code?: number }).code === 4001) {\n throw new X402Error('Connection rejected by user', 'WALLET_CONNECTION_REJECTED');\n }\n }\n throw new X402Error(\n `Failed to connect Phantom: ${error instanceof Error ? error.message : 'Unknown error'}`,\n 'UNKNOWN_ERROR',\n error\n );\n }\n }\n\n /**\n * Disconnect from Phantom\n */\n async disconnect(): Promise<void> {\n if (this.provider) {\n try {\n await this.provider.disconnect();\n } catch {\n // Ignore disconnect errors\n }\n }\n this.provider = null;\n this.publicKey = null;\n this.connections.clear();\n this.address = null;\n }\n\n /**\n * Get current address\n */\n getAddress(): string | null {\n return this.address;\n }\n\n /**\n * Get USDC balance\n */\n async getBalance(chainConfig: ChainConfig): Promise<string> {\n await loadSolanaDeps();\n\n if (!this.address) {\n throw new X402Error('Wallet not connected', 'WALLET_NOT_CONNECTED');\n }\n\n await this.initConnection(chainConfig);\n const connection = this.connections.get(chainConfig.name);\n if (!connection) {\n throw new X402Error('Failed to connect to Solana RPC', 'NETWORK_ERROR');\n }\n\n try {\n const response = await fetch(chainConfig.rpcUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n jsonrpc: '2.0',\n id: 1,\n method: 'getTokenAccountsByOwner',\n params: [\n this.address,\n { mint: chainConfig.usdc.address },\n { encoding: 'jsonParsed' },\n ],\n }),\n });\n\n const data = await response.json();\n\n if (!data.result?.value?.length) {\n return '0.00';\n }\n\n const tokenAccountInfo = data.result.value[0].account.data.parsed.info;\n const balance = Number(tokenAccountInfo.tokenAmount.amount) / Math.pow(10, tokenAccountInfo.tokenAmount.decimals);\n\n return balance.toFixed(2);\n } catch {\n return '0.00';\n }\n }\n\n /**\n * Create SVM payment (partially-signed transaction)\n *\n * Works for both Solana and Fogo chains.\n *\n * Transaction structure required by facilitator:\n * 1. SetComputeUnitLimit\n * 2. SetComputeUnitPrice\n * 3. (Optional) CreateAssociatedTokenAccount if recipient ATA doesn't exist\n * 4. TransferChecked (USDC transfer)\n *\n * Fee payer: Facilitator (not user)\n * User pays: ZERO SOL/FOGO\n */\n async signPayment(paymentInfo: PaymentInfo, chainConfig: ChainConfig): Promise<string> {\n await loadSolanaDeps();\n\n if (!this.provider || !this.publicKey || !this.address) {\n throw new X402Error('Wallet not connected', 'WALLET_NOT_CONNECTED');\n }\n\n const connection = await this.getConnection(chainConfig);\n if (!connection) {\n throw new X402Error(`Failed to connect to ${chainConfig.displayName} RPC`, 'NETWORK_ERROR');\n }\n\n // Get recipient and facilitator addresses\n const recipient = paymentInfo.recipients?.solana || paymentInfo.recipient;\n const facilitatorAddress = paymentInfo.facilitator;\n\n if (!facilitatorAddress) {\n throw new X402Error('Facilitator address not provided', 'INVALID_CONFIG');\n }\n\n const recipientPubkey = new PublicKey(recipient);\n const facilitatorPubkey = new PublicKey(facilitatorAddress);\n const usdcMint = new PublicKey(chainConfig.usdc.address);\n\n // Parse amount (6 decimals for USDC)\n const amount = Math.floor(parseFloat(paymentInfo.amount) * 1_000_000);\n\n // Get token accounts\n const fromTokenAccount = await getAssociatedTokenAddress(\n usdcMint,\n this.publicKey,\n true,\n TOKEN_PROGRAM_ID\n );\n\n const toTokenAccount = await getAssociatedTokenAddress(\n usdcMint,\n recipientPubkey,\n true,\n TOKEN_PROGRAM_ID\n );\n\n // Check if recipient ATA exists\n const toTokenAccountInfo = await connection.getAccountInfo(toTokenAccount);\n const needsATACreation = toTokenAccountInfo === null;\n\n // Get recent blockhash\n const { blockhash } = await connection.getLatestBlockhash('finalized');\n\n // Build instructions in exact order required by facilitator\n const instructions = [];\n\n // Instruction 0: SetComputeUnitLimit\n instructions.push(\n ComputeBudgetProgram.setComputeUnitLimit({\n units: needsATACreation ? 50_000 : 20_000,\n })\n );\n\n // Instruction 1: SetComputeUnitPrice\n // Use 100k microlamports/CU for fast landing on mainnet\n // Lower values (like 1) cause transactions to be deprioritized and time out\n instructions.push(\n ComputeBudgetProgram.setComputeUnitPrice({\n microLamports: 100_000,\n })\n );\n\n // Instruction 2 (optional): CreateAssociatedTokenAccountIdempotent\n // User pays for ATA creation (not facilitator - security check in x402-rs)\n if (needsATACreation) {\n instructions.push(\n createAssociatedTokenAccountIdempotentInstruction(\n this.publicKey, // User pays for ATA creation\n toTokenAccount,\n recipientPubkey,\n usdcMint,\n TOKEN_PROGRAM_ID\n )\n );\n }\n\n // Instruction 2/3: TransferChecked\n instructions.push(\n createTransferCheckedInstruction(\n fromTokenAccount,\n usdcMint,\n toTokenAccount,\n this.publicKey,\n amount,\n 6,\n [],\n TOKEN_PROGRAM_ID\n )\n );\n\n // Build VersionedTransaction with facilitator as fee payer\n const messageV0 = new TransactionMessage({\n payerKey: facilitatorPubkey,\n recentBlockhash: blockhash,\n instructions,\n }).compileToV0Message();\n\n const transaction = new VersionedTransaction(messageV0);\n\n // User signs (partial signature - facilitator will co-sign)\n // IMPORTANT: Phantom may modify the transaction (add memo instruction).\n // We send the FULL signed transaction to the facilitator, which will use it\n // exactly as signed (not reconstruct it). This ensures signature validity.\n let signedTransaction: InstanceType<typeof VersionedTransaction>;\n try {\n signedTransaction = await this.provider.signTransaction(transaction);\n } catch (error: unknown) {\n if (error instanceof Error && error.message.includes('User rejected')) {\n throw new X402Error('Signature rejected by user', 'SIGNATURE_REJECTED');\n }\n throw new X402Error(\n `Failed to sign transaction: ${error instanceof Error ? error.message : 'Unknown error'}`,\n 'PAYMENT_FAILED',\n error\n );\n }\n\n // Serialize the FULL signed transaction (including any wallet modifications)\n // The facilitator will use this exact transaction, adding only its signature\n const serialized = signedTransaction.serialize();\n\n const payload: SolanaPaymentPayload = {\n transaction: uint8ArrayToBase64(serialized),\n };\n\n return JSON.stringify(payload);\n }\n\n /**\n * Encode SVM payment as X-PAYMENT header\n *\n * @param paymentPayload - JSON-encoded payment payload from signPayment()\n * @param chainConfig - Chain configuration (optional, defaults to 'solana')\n * @param version - x402 protocol version (1 or 2, defaults to 1)\n * @returns Base64-encoded X-PAYMENT header value\n */\n encodePaymentHeader(\n paymentPayload: string,\n chainConfig?: ChainConfig,\n version: X402Version = 1\n ): string {\n const payload = JSON.parse(paymentPayload) as SolanaPaymentPayload;\n\n // Use chain name from config, or default to 'solana' for backward compatibility\n const networkName = chainConfig?.name || 'solana';\n\n // Build the payload data - preserve token info for Token2022 (AUSD, etc.)\n const payloadData: { transaction: string; token?: TokenInfo } = {\n transaction: payload.transaction,\n };\n\n // CRITICAL: Preserve token info for non-USDC tokens (Token2022 like AUSD)\n // Without this, the facilitator cannot verify Token2022 transfers correctly\n if (payload.token) {\n payloadData.token = payload.token;\n }\n\n // Format in x402 standard format (v1 or v2)\n const x402Payload = version === 2\n ? {\n x402Version: 2 as const,\n scheme: 'exact' as const,\n network: chainToCAIP2(networkName), // CAIP-2 format for v2\n payload: payloadData,\n }\n : {\n x402Version: 1 as const,\n scheme: 'exact' as const,\n network: networkName, // Plain chain name for v1\n payload: payloadData,\n };\n\n return encodeBase64Json(x402Payload);\n }\n\n // Private helpers\n\n private async getPhantomProvider(): Promise<PhantomProvider | null> {\n if (typeof window === 'undefined') return null;\n\n // Try window.phantom.solana first\n const win = window as Window & {\n phantom?: { solana?: PhantomProvider };\n solana?: PhantomProvider;\n };\n\n if (win.phantom?.solana?.isPhantom) {\n return win.phantom.solana;\n }\n\n // Fallback to window.solana\n if (win.solana?.isPhantom) {\n return win.solana;\n }\n\n // Wait a bit for Phantom to inject itself\n for (let i = 0; i < 5; i++) {\n await new Promise(resolve => setTimeout(resolve, 100));\n if (win.phantom?.solana?.isPhantom) {\n return win.phantom.solana;\n }\n if (win.solana?.isPhantom) {\n return win.solana;\n }\n }\n\n return null;\n }\n\n /**\n * Get or create a connection for a specific chain\n *\n * IMPORTANT: Caches by RPC URL, not chain name. This allows consumers to\n * override the RPC URL (e.g., use Helius instead of public RPC) and get\n * a fresh connection with their custom RPC.\n */\n private async getConnection(chainConfig?: ChainConfig): Promise<InstanceType<typeof Connection>> {\n await loadSolanaDeps();\n\n const config = chainConfig || getChainByName('solana');\n if (!config) {\n throw new X402Error('Chain config not found', 'CHAIN_NOT_SUPPORTED');\n }\n\n // Cache by RPC URL, not chain name - allows custom RPC overrides\n const cacheKey = config.rpcUrl;\n\n // Check if we already have a connection for this RPC\n if (this.connections.has(cacheKey)) {\n return this.connections.get(cacheKey)!;\n }\n\n // Create new connection for this RPC\n const connection = new Connection(config.rpcUrl, 'confirmed');\n this.connections.set(cacheKey, connection);\n\n return connection;\n }\n\n /**\n * @deprecated Use getConnection instead\n */\n private async initConnection(chainConfig?: ChainConfig): Promise<void> {\n await this.getConnection(chainConfig);\n }\n}\n\n/**\n * @deprecated Use SVMProvider instead\n */\nexport class SolanaProvider extends SVMProvider {\n constructor() {\n super();\n console.warn('SolanaProvider is deprecated. Use SVMProvider instead.');\n }\n}\n\n// Default export\nexport default SVMProvider;\n","/**\n * DX402 `durable-evidence`: recover a paid response after the fact.\n *\n * x402 settles payment on-chain permanently but delivers the purchased resource\n * **exactly once**, in the body of a `200 OK`, and keeps nothing. A buyer who did\n * not capture it at that instant cannot recover it, and neither party can later\n * prove *what* was delivered — only *that* payment happened.\n *\n * DX402 closes that gap. The seller seals a copy of the response to the payer's\n * own public key — recovered from the payment signature itself — and anchors it.\n * The buyer gets an `X-Durable-Evidence` header pointing at it.\n *\n * **Paying is publishing your encryption key.** No registration, no key\n * exchange, no extra round trip.\n *\n * ```ts\n * const evidence = evidenceFromHeaders(response.headers);\n * const body = await recoverEvidence(evidence, myPrivateKey);\n * ```\n *\n * Specification: `docs/plans/dx402/02-SPEC-v0.1.md` in x402-rs.\n */\n\nimport { gcm } from '@noble/ciphers/aes';\nimport { ed25519, x25519 } from '@noble/curves/ed25519';\nimport { secp256k1 } from '@noble/curves/secp256k1';\nimport { hkdf } from '@noble/hashes/hkdf';\nimport {\n hexToBytes as nobleHexToBytes,\n bytesToHex,\n} from '@noble/hashes/utils';\nimport { keccak_256 } from '@noble/hashes/sha3';\n\nimport { getChainById, getChainByName } from './chains';\nimport { sha256, sha512 } from '@noble/hashes/sha2';\n\nexport const EVIDENCE_HEADER = 'X-Durable-Evidence';\n\nconst MAGIC = new Uint8Array([0x44, 0x58, 0x34, 0x30, 0x32]); // \"DX402\"\n/** One recipient (the payer). Still emitted for that case, so deployed readers keep working. */\nconst FORMAT_V1 = 1;\n/** Several recipients. A v2 blob positively signals that somebody besides the payer can open it. */\nconst FORMAT_V2 = 2;\n\n/** Why a party holds a key to this evidence. */\nexport type RecipientRole = 'payer' | 'seller' | 'auditor';\nconst ROLE_NAMES: RecipientRole[] = ['payer', 'seller', 'auditor'];\nconst NONCE_LEN = 12;\nconst CEK_LEN = 32;\nconst HKDF_INFO = new TextEncoder().encode('DX402-v1-wrap');\n\nexport class DX402Error extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'DX402Error';\n }\n}\n\n/**\n * No evidence was anchored for this payment.\n *\n * A normal outcome, not a fault: the body may have exceeded the seller's size\n * cap, the store may have been unreachable, or the payer may be a\n * smart-contract wallet with no recoverable key.\n */\nexport class EvidenceSkipped extends DX402Error {\n constructor(public readonly reason: string) {\n super(`no durable evidence was anchored: ${reason}`);\n this.name = 'EvidenceSkipped';\n }\n}\n\n/**\n * The anchored bytes are not the bytes that were delivered.\n *\n * This is the interesting failure: the seller anchored something other than\n * what it served, which is precisely the fraud `contentHash` exists to expose.\n * Treat it as evidence of misbehaviour, not a transport glitch.\n */\nexport class ContentHashMismatch extends DX402Error {\n constructor(\n public readonly anchored: string,\n public readonly actual: string,\n ) {\n super(`content hash mismatch: anchored ${anchored}, decrypted ${actual}`);\n this.name = 'ContentHashMismatch';\n }\n}\n\nexport type EvidenceMode = 'direct' | 'escrowed';\n\nexport interface AnchoredEvidence {\n v: number;\n paymentId: string;\n pointer: string;\n backend: string;\n contentHash: string;\n cipher: string;\n keyAlg: 'ECIES-secp256k1' | 'ECIES-X25519';\n mode: EvidenceMode;\n retention: string;\n receipt?: string;\n}\n\n/**\n * Whether the facilitator is cryptographically unable to read this payload.\n *\n * `direct` and `escrowed` make materially different claims about who can open\n * the payload, so a caller that cares about confidentiality must check rather\n * than assume.\n */\nexport function isEndToEnd(evidence: AnchoredEvidence): boolean {\n return evidence.mode === 'direct';\n}\n\nfunction b64urlDecode(value: string): Uint8Array {\n const normalized = value.trim().replace(/-/g, '+').replace(/_/g, '/');\n const padded = normalized + '='.repeat((4 - (normalized.length % 4)) % 4);\n return Uint8Array.from(atob(padded), (c) => c.charCodeAt(0));\n}\n\n/**\n * Hex decode, strictly.\n *\n * The hand-rolled loop this replaces used `parseInt`, which returns NaN for\n * non-hex input — and a Uint8Array stores NaN as 0. So `'zz'.repeat(32)`\n * decoded to 32 zero bytes and `parseInt('4z', 16)` to 4: malformed input\n * became a plausible-looking key instead of an error. This gates real key\n * material (the payer private key in `recoverEvidence`, the 65-byte signature\n * in `payerKeyFromEvmSignature`, the payee address in `anchorDigest`), and the\n * symptom was a misleading 'wrong key, or the blob belongs to another payment'\n * one layer later. Same failure class as the base58 `rjust(32)` bug in the\n * Python SDK. Python (`bytes.fromhex`) and Rust (`hex::decode`) already reject;\n * TypeScript was the permissive outlier.\n */\nfunction hexToBytes(hex: string): Uint8Array {\n const clean = hex.startsWith('0x') ? hex.slice(2) : hex;\n try {\n return nobleHexToBytes(clean);\n } catch (e) {\n throw new DX402Error(`invalid hex: ${(e as Error).message}`);\n }\n}\n\n/** keccak256 of a body, `0x`-prefixed — matching the facilitator's `contentHash`. */\nexport function contentHash(body: Uint8Array): string {\n return '0x' + bytesToHex(keccak_256(body));\n}\n\n/**\n * Derive the canonical payment identifier: `keccak256(caip2Network || txHash)`.\n *\n * This value is the AEAD associated data binding a ciphertext to its payment.\n * Buyer and seller must derive it identically or decryption fails with no\n * obvious cause, which is why it lives in the SDK rather than in each caller.\n */\nexport function paymentId(caip2Network: string, txHash: string): string {\n const enc = new TextEncoder();\n const clean = txHash.startsWith('0x') ? txHash.slice(2) : txHash;\n const preimage = new Uint8Array([...enc.encode(caip2Network), ...enc.encode(clean)]);\n return '0x' + bytesToHex(keccak_256(preimage));\n}\n\n/** Parse an `X-Durable-Evidence` header value. */\nexport function parseEvidenceHeader(value: string): AnchoredEvidence {\n let payload: Record<string, unknown>;\n try {\n payload = JSON.parse(new TextDecoder().decode(b64urlDecode(value)));\n } catch (err) {\n throw new DX402Error(`malformed ${EVIDENCE_HEADER} header: ${String(err)}`);\n }\n if ('skipped' in payload) {\n throw new EvidenceSkipped(String(payload.skipped));\n }\n if (!payload.paymentId || !payload.pointer || !payload.contentHash) {\n throw new DX402Error(`malformed ${EVIDENCE_HEADER} header: missing required fields`);\n }\n return payload as unknown as AnchoredEvidence;\n}\n\n/**\n * Pull the anchored evidence out of a response's headers.\n *\n * Accepts a `Headers` object or a plain record. Lookup is case-insensitive,\n * because HTTP does not care and different clients disagree about casing.\n */\nexport function evidenceFromHeaders(\n headers: Headers | Record<string, string>,\n): AnchoredEvidence {\n let raw: string | null | undefined;\n if (typeof (headers as Headers).get === 'function') {\n raw = (headers as Headers).get(EVIDENCE_HEADER);\n } else {\n const target = EVIDENCE_HEADER.toLowerCase();\n for (const [key, value] of Object.entries(headers as Record<string, string>)) {\n if (key.toLowerCase() === target) {\n raw = value;\n break;\n }\n }\n }\n if (!raw) throw new DX402Error(`no ${EVIDENCE_HEADER} header on this response`);\n return parseEvidenceHeader(raw);\n}\n\n/**\n * Turn a DX402 pointer into a fetchable URL.\n *\n * `s3+https://...` is a scheme tag over an ordinary HTTPS URL; `ipfs://` and\n * `ar://` go through public gateways. Anything else passes through untouched, so\n * a caller with their own resolver is not blocked by this function.\n */\nexport function dereferencePointer(pointer: string): string {\n if (pointer.startsWith('s3+')) return pointer.slice(3);\n if (pointer.startsWith('ipfs://')) return `https://ipfs.io/ipfs/${pointer.slice(7)}`;\n if (pointer.startsWith('ar://')) return `https://arweave.net/${pointer.slice(5)}`;\n return pointer;\n}\n\ninterface Recipient {\n role: RecipientRole;\n alg: 'secp256k1' | 'x25519';\n ephemeral: Uint8Array;\n cekNonce: Uint8Array;\n wrappedCek: Uint8Array;\n}\n\ninterface SealedEnvelope {\n recipients: Recipient[];\n bodyNonce: Uint8Array;\n ciphertext: Uint8Array;\n}\n\n/**\n * Who can open this blob, without decrypting anything.\n *\n * Worth surfacing: a buyer has to be able to see that the seller — or a\n * designated auditor — also holds a key to what they bought. Finding that out\n * afterwards would destroy the privacy property.\n */\nexport function sealedRoles(raw: Uint8Array): RecipientRole[] {\n return parseSealed(raw).recipients.map((r) => r.role);\n}\n\n/**\n * Parse the sealed-blob layout.\n *\n * `MAGIC | version | alg | ephLen | eph | cekNonce | wrappedLen | wrapped |\n * bodyNonce | ciphertext`\n *\n * Every read is bounds-checked, so a truncated blob is a clear parse failure\n * rather than an out-of-range surprise later.\n */\nexport function parseSealed(raw: Uint8Array): SealedEnvelope {\n let pos = 0;\n const take = (n: number, what: string): Uint8Array => {\n if (raw.length < pos + n) throw new DX402Error(`truncated DX402 sealed blob at ${what}`);\n const chunk = raw.subarray(pos, pos + n);\n pos += n;\n return chunk;\n };\n\n const magic = take(MAGIC.length, 'magic');\n for (let i = 0; i < MAGIC.length; i++) {\n if (magic[i] !== MAGIC[i]) throw new DX402Error('not a DX402 sealed blob');\n }\n\n const version = take(1, 'version')[0];\n let count: number;\n if (version === FORMAT_V1) count = 1;\n else if (version === FORMAT_V2) count = take(1, 'recipient count')[0];\n else throw new DX402Error(`unsupported sealed-blob version ${version}`);\n\n // An envelope nobody can open is not evidence.\n if (count === 0) throw new DX402Error('DX402 sealed blob has no recipients');\n\n const recipients: Recipient[] = [];\n for (let i = 0; i < count; i++) {\n let role: RecipientRole = 'payer';\n if (version === FORMAT_V2) {\n const b = take(1, 'role')[0];\n if (b >= ROLE_NAMES.length) throw new DX402Error(`unknown role ${b}`);\n role = ROLE_NAMES[b];\n }\n\n const algByte = take(1, 'algorithm')[0];\n if (algByte !== 1 && algByte !== 2) {\n throw new DX402Error(`unknown key algorithm ${algByte}`);\n }\n const ephLen = take(1, 'ephemeral key length')[0];\n const ephemeral = take(ephLen, 'ephemeral key');\n const cekNonce = take(NONCE_LEN, 'cek nonce');\n const lenBytes = take(2, 'wrapped key length');\n const wrappedCek = take((lenBytes[0] << 8) | lenBytes[1], 'wrapped cek');\n\n recipients.push({\n role,\n alg: algByte === 1 ? 'secp256k1' : 'x25519',\n ephemeral,\n cekNonce,\n wrappedCek,\n });\n }\n\n const bodyNonce = take(NONCE_LEN, 'body nonce');\n return { recipients, bodyNonce, ciphertext: raw.subarray(pos) };\n}\n\nfunction sharedSecret(sealed: Recipient, privateKey: Uint8Array): Uint8Array {\n if (sealed.alg === 'secp256k1') {\n // Compressed output is 33 bytes: a 0x02/0x03 tag plus the x-coordinate.\n // Only the x-coordinate is the ECDH result, matching what the Rust side\n // feeds into HKDF. Including the tag byte would derive a different key and\n // fail with no useful diagnostic.\n const full = secp256k1.getSharedSecret(privateKey, sealed.ephemeral, true);\n return full.subarray(1);\n }\n\n // ed25519 seed -> X25519 scalar: SHA-512 the seed, take the low half.\n // @noble/curves clamps internally.\n const scalar = sha512(privateKey).subarray(0, 32);\n const shared = x25519.getSharedSecret(scalar, sealed.ephemeral);\n\n // RFC 7748 section 6.1: an all-zero result means a small-order public key was\n // supplied, which would make the wrapping key reproducible by whoever\n // supplied it.\n if (shared.every((b) => b === 0)) {\n throw new DX402Error('degenerate ECDH result (small-order public key)');\n }\n return shared;\n}\n\n/**\n * Decrypt a sealed envelope with whichever recipient slot belongs to `privateKey`.\n *\n * Tries every slot: a holder does not necessarily know which one is theirs, and\n * in a multi-recipient envelope the payer is not always first. A slot that does\n * not open is skipped, not reported — \"that one was not for me\" is not an error.\n */\nexport function unseal(\n sealed: SealedEnvelope,\n privateKey: Uint8Array,\n aad: Uint8Array,\n): Uint8Array {\n for (const recipient of sealed.recipients) {\n let shared: Uint8Array;\n try {\n shared = sharedSecret(recipient, privateKey);\n } catch (err) {\n if (err instanceof DX402Error) throw err;\n continue;\n }\n\n const wrapKey = hkdf(sha256, shared, aad, HKDF_INFO, 32);\n let cek: Uint8Array;\n try {\n cek = gcm(wrapKey, recipient.cekNonce, aad).decrypt(recipient.wrappedCek);\n } catch {\n continue; // not our slot\n }\n if (cek.length !== CEK_LEN) {\n throw new DX402Error(`unwrapped CEK is ${cek.length} bytes, expected ${CEK_LEN}`);\n }\n return gcm(cek, sealed.bodyNonce, aad).decrypt(sealed.ciphertext);\n }\n\n throw new DX402Error(\n 'no recipient slot opened -- wrong key, or the blob belongs to another payment',\n );\n}\n\n/**\n * Fetch, decrypt and verify the body behind `evidence`.\n *\n * `privateKey` is the raw key of the wallet that paid: 32 bytes for both an EVM\n * secp256k1 key and an ed25519 seed. Hex accepted with or without `0x`.\n *\n * In `direct` mode this needs no permission from anyone — the ciphertext was\n * sealed to the public key of the wallet that paid, so retrieval is arithmetic\n * rather than an access-control decision that could be refused or misconfigured.\n *\n * The `contentHash` check is **not optional**: it is what catches a seller that\n * anchored something other than what it served.\n */\nexport async function recoverEvidence(\n evidence: AnchoredEvidence,\n privateKey: Uint8Array | string,\n options: { fetch?: typeof fetch } = {},\n): Promise<Uint8Array> {\n const key = typeof privateKey === 'string' ? hexToBytes(privateKey) : privateKey;\n if (key.length !== 32) {\n throw new DX402Error(`private key must be 32 bytes, got ${key.length}`);\n }\n\n const doFetch = options.fetch ?? fetch;\n const url = dereferencePointer(evidence.pointer);\n const res = await doFetch(url);\n if (!res.ok) {\n throw new DX402Error(`could not fetch sealed evidence: HTTP ${res.status}`);\n }\n const blob = new Uint8Array(await res.arrayBuffer());\n\n const sealed = parseSealed(blob);\n const aad = new TextEncoder().encode(evidence.paymentId);\n\n let plaintext: Uint8Array;\n try {\n plaintext = unseal(sealed, key, aad);\n } catch (err) {\n if (err instanceof DX402Error) throw err;\n throw new DX402Error(\n 'decryption failed -- wrong key, or the blob belongs to another payment',\n );\n }\n\n const actual = contentHash(plaintext);\n if (actual.toLowerCase() !== evidence.contentHash.toLowerCase()) {\n throw new ContentHashMismatch(evidence.contentHash, actual);\n }\n\n return plaintext;\n}\n\n// ============================================================================\n// Seller side -- sealing\n// ============================================================================\n//\n// The half above recovers evidence. This half PRODUCES it, and it belongs to\n// whoever holds the plaintext: the resource server, right after settlement.\n//\n// The facilitator is deliberately not involved. It only ever sees /verify and\n// /settle, never a response body, so sealing cannot happen there.\n\nimport { edwardsToMontgomeryPub } from '@noble/curves/ed25519';\nimport { randomBytes } from '@noble/hashes/utils';\n\n/**\n * Map an ed25519 public key to its X25519 form.\n *\n * On ed25519 chains (Solana, NEAR, Stellar, Algorand) the address **is** the\n * public key, so this is all that stands between an address and an encryption\n * target — no signature, no lookup.\n */\nexport function ed25519ToX25519(pubkey: Uint8Array): Uint8Array {\n if (pubkey.length !== 32) {\n throw new DX402Error(`ed25519 public key must be 32 bytes, got ${pubkey.length}`);\n }\n return edwardsToMontgomeryPub(pubkey);\n}\n\n/**\n * Recover an EVM payer's secp256k1 public key from their payment signature.\n *\n * `digest` is the EIP-712 digest the payer actually signed. Getting it wrong\n * does not throw: it recovers a *different, perfectly valid* key, and the body\n * would be sealed to a stranger while every log line said success. The token's\n * EIP-712 domain name varies per chain and even flips between a chain's mainnet\n * and testnet, so derive it from the same table the facilitator uses.\n *\n * Returns the SEC1-compressed key (33 bytes).\n */\nexport function payerKeyFromEvmSignature(\n signature: Uint8Array | string,\n digest: Uint8Array,\n): Uint8Array {\n const sig = typeof signature === 'string' ? hexToBytes(signature) : signature;\n if (sig.length !== 65) {\n throw new DX402Error(`signature must be 65 bytes, got ${sig.length}`);\n }\n\n let v = sig[65 - 1];\n if (v === 27 || v === 28) v -= 27;\n else if (v >= 35) v = (v - 35) % 2;\n if (v !== 0 && v !== 1) throw new DX402Error(`invalid recovery id ${sig[64]}`);\n\n const parsed = secp256k1.Signature.fromCompact(sig.subarray(0, 64)).addRecoveryBit(v);\n return parsed.recoverPublicKey(digest).toRawBytes(true);\n}\n\n/**\n * Seal `body` so that only the holder of the payer's private key can read it.\n *\n * `payerKey` is a 33-byte SEC1-compressed secp256k1 key (EVM, XRPL) or a 32-byte\n * X25519 key from {@link ed25519ToX25519}.\n *\n * `paymentIdValue` is bound in as AEAD associated data, which is what stops a\n * ciphertext from being replayed as the evidence for a different payment.\n * Derive it with {@link paymentId} on both sides — deriving it differently makes\n * decryption fail with no obvious cause.\n *\n * Returns the bytes to upload. Nothing here touches the network.\n */\nexport function sealEvidence(\n body: Uint8Array,\n payerKey: Uint8Array,\n paymentIdValue: string,\n): Uint8Array {\n const aad = new TextEncoder().encode(paymentIdValue);\n const cek = randomBytes(32);\n const bodyNonce = randomBytes(NONCE_LEN);\n const cekNonce = randomBytes(NONCE_LEN);\n\n const ciphertext = gcm(cek, bodyNonce, aad).encrypt(body);\n\n let algByte: number;\n let ephemeral: Uint8Array;\n let shared: Uint8Array;\n\n if (payerKey.length === 33) {\n algByte = 1;\n const ephPriv = secp256k1.utils.randomPrivateKey();\n ephemeral = secp256k1.getPublicKey(ephPriv, true);\n // Only the x-coordinate is the ECDH result; the leading tag byte is not\n // part of it. Including it would derive a different key and fail with no\n // useful diagnostic.\n shared = secp256k1.getSharedSecret(ephPriv, payerKey, true).subarray(1);\n } else if (payerKey.length === 32) {\n algByte = 2;\n const ephPriv = randomBytes(32);\n ephemeral = x25519.getPublicKey(ephPriv);\n shared = x25519.getSharedSecret(ephPriv, payerKey);\n\n // RFC 7748 section 6.1: a small-order payer key would drive the shared\n // secret to a constant that whoever supplied it could reproduce.\n if (shared.every((b) => b === 0)) {\n throw new DX402Error('degenerate ECDH result (small-order public key)');\n }\n } else {\n throw new DX402Error(\n `payer key must be 33 bytes (secp256k1) or 32 (X25519), got ${payerKey.length}`,\n );\n }\n\n const wrapKey = hkdf(sha256, shared, aad, HKDF_INFO, 32);\n const wrappedCek = gcm(wrapKey, cekNonce, aad).encrypt(cek);\n\n const out = new Uint8Array(\n MAGIC.length + 3 + ephemeral.length + NONCE_LEN + 2 + wrappedCek.length +\n NONCE_LEN + ciphertext.length,\n );\n let pos = 0;\n out.set(MAGIC, pos); pos += MAGIC.length;\n out[pos++] = FORMAT_V1;\n out[pos++] = algByte;\n out[pos++] = ephemeral.length;\n out.set(ephemeral, pos); pos += ephemeral.length;\n out.set(cekNonce, pos); pos += NONCE_LEN;\n out[pos++] = (wrappedCek.length >> 8) & 0xff;\n out[pos++] = wrappedCek.length & 0xff;\n out.set(wrappedCek, pos); pos += wrappedCek.length;\n out.set(bodyNonce, pos); pos += NONCE_LEN;\n out.set(ciphertext, pos);\n return out;\n}\n\n// ============================================================================\n// Anchor authorization -- proving the anchor is yours\n// ============================================================================\n//\n// An anchor carrying a valid payee signature is `verified` and final. One\n// without is provisional: it still blocks a duplicate, but a verified anchor\n// for the same payment supersedes it.\n//\n// That asymmetry exists because the paymentId claim is permanent. Without it,\n// whoever anchored first owned the evidence of a payment forever and the real\n// seller was locked out.\n\nconst ANCHOR_DOMAIN_NAME = 'DX402 Anchor';\nconst ANCHOR_DOMAIN_VERSION = '1';\nconst ANCHOR_TYPE =\n 'Dx402AnchorAuthorization(bytes32 paymentId,bytes32 contentHash,string pointer,address payee)';\nconst EIP712_DOMAIN_TYPE = 'EIP712Domain(string name,string version,uint256 chainId)';\n\n/** The zero address, for the ed25519 form of the digest. */\nexport const ZERO_ADDRESS = '0x' + '00'.repeat(20);\n\nfunction concatBytes(...parts: Uint8Array[]): Uint8Array {\n const total = parts.reduce((n, p) => n + p.length, 0);\n const out = new Uint8Array(total);\n let pos = 0;\n for (const p of parts) {\n out.set(p, pos);\n pos += p.length;\n }\n return out;\n}\n\nfunction uint256(n: number | bigint): Uint8Array {\n const out = new Uint8Array(32);\n let v = BigInt(n);\n for (let i = 31; i >= 0 && v > 0n; i--) {\n out[i] = Number(v & 0xffn);\n v >>= 8n;\n }\n return out;\n}\n\n/**\n * The 32-byte digest a seller signs to prove an anchor is theirs.\n *\n * One canonical message across every curve. `payee` is the EVM address for a\n * secp256k1 payee and the **zero address** for an ed25519 one — an ed25519\n * address does not fit the `address` field, and the binding is already\n * established by which key verifies the signature.\n *\n * `pointer` is whatever you send in the anchor, or the **empty string** when you\n * send `sealed` and the facilitator issues the pointer itself: you cannot sign a\n * value you have not seen.\n *\n * Getting this wrong throws nothing — it produces a signature that simply never\n * verifies, and the anchor stays provisional with no clue why. The tests pin it\n * against digests emitted by the facilitator's own Rust implementation.\n */\nexport function anchorDigest(\n paymentId: string,\n contentHash: string,\n pointer: string,\n payee: string,\n chainId: number,\n): Uint8Array {\n const b32 = (value: string, field: string): Uint8Array => {\n const raw = hexToBytes(value);\n if (raw.length !== 32) throw new DX402Error(`${field} must be 32 bytes, got ${raw.length}`);\n return raw;\n };\n\n const addr = hexToBytes(payee);\n if (addr.length !== 20) {\n throw new DX402Error(`payee must be a 20-byte address, got ${addr.length}`);\n }\n\n const enc = new TextEncoder();\n const domainSeparator = keccak_256(\n concatBytes(\n keccak_256(enc.encode(EIP712_DOMAIN_TYPE)),\n keccak_256(enc.encode(ANCHOR_DOMAIN_NAME)),\n keccak_256(enc.encode(ANCHOR_DOMAIN_VERSION)),\n uint256(chainId),\n ),\n );\n\n const structHash = keccak_256(\n concatBytes(\n keccak_256(enc.encode(ANCHOR_TYPE)),\n b32(paymentId, 'paymentId'),\n b32(contentHash, 'contentHash'),\n keccak_256(enc.encode(pointer)),\n new Uint8Array(12),\n addr,\n ),\n );\n\n return keccak_256(concatBytes(new Uint8Array([0x19, 0x01]), domainSeparator, structHash));\n}\n\n/**\n * Sign an anchor authorization with a Solana / Stellar ed25519 key.\n *\n * A Solana payee cannot produce an EIP-712 signature at all — its address is an\n * ed25519 key — so requiring one would leave that chain unable to prove\n * authorship even once the on-chain gate is enforced. This closes it today, with\n * no RPC.\n */\nexport function signAnchorEd25519(\n privateKey: Uint8Array,\n paymentId: string,\n contentHash: string,\n pointer = '',\n): string {\n if (privateKey.length !== 32) {\n throw new DX402Error(`ed25519 seed must be 32 bytes, got ${privateKey.length}`);\n }\n const digest = anchorDigest(paymentId, contentHash, pointer, ZERO_ADDRESS, 0);\n return '0x' + bytesToHex(ed25519.sign(digest, privateKey));\n}\n\n/**\n * Sign an anchor authorization with an EVM secp256k1 key.\n *\n * `payee` must be the address of `privateKey` — the facilitator recovers the\n * signer and compares, so declaring somebody else's address simply leaves the\n * anchor provisional.\n */\nexport function signAnchorEvm(\n privateKey: Uint8Array,\n paymentId: string,\n contentHash: string,\n pointer: string,\n payee: string,\n chainId: number,\n): string {\n const digest = anchorDigest(paymentId, contentHash, pointer, payee, chainId);\n const sig = secp256k1.sign(digest, privateKey);\n return '0x' + bytesToHex(sig.toCompactRawBytes()) + (sig.recovery === 1 ? '01' : '00');\n}\n\n/**\n * Derive the encryption target from a Solana (or Fogo) address.\n *\n * On ed25519 chains the address **is** the public key, so this needs no\n * signature and no lookup. Rejects anything that does not decode to exactly 32\n * bytes: a short decode silently padded up to 32 produces a small-order point,\n * which fails a layer later with a message that points nowhere near the cause.\n */\nexport function payerKeyFromSolanaAddress(address: string): Uint8Array {\n if (!address || !address.trim()) throw new DX402Error('empty Solana address');\n\n const alphabet = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';\n let num = 0n;\n for (const ch of address) {\n const idx = alphabet.indexOf(ch);\n if (idx < 0) throw new DX402Error(`invalid base58 character '${ch}' in address`);\n num = num * 58n + BigInt(idx);\n }\n\n let hex = num.toString(16);\n if (hex.length % 2) hex = '0' + hex;\n const body = hexToBytes(hex);\n const leading = address.length - address.replace(/^1+/, '').length;\n\n const decoded = new Uint8Array(leading + body.length);\n decoded.set(body, leading);\n if (decoded.length !== 32) {\n throw new DX402Error(`Solana address decodes to ${decoded.length} bytes, expected 32`);\n }\n return ed25519ToX25519(decoded);\n}\n\n/**\n * Seal `body` so every listed recipient can read it, and nobody else.\n *\n * The body is encrypted **once**; only the content key is wrapped per recipient,\n * so adding the seller costs about sixty bytes rather than a second copy of the\n * payload. That is what makes it practical for a seller to keep a readable copy\n * of what it delivered — and answer a false \"that is not what you sent\" —\n * instead of paying to anchor evidence it cannot open.\n *\n * A single payer recipient is emitted as format **v1, byte-for-byte**, so\n * nothing already anchored becomes unreadable and readers still on v1 keep\n * working.\n */\nexport function sealEvidenceTo(\n body: Uint8Array,\n recipients: Array<{ role: RecipientRole; key: Uint8Array }>,\n paymentIdValue: string,\n): Uint8Array {\n if (recipients.length === 0) {\n throw new DX402Error('an envelope with no recipients could never be opened');\n }\n\n const aad = new TextEncoder().encode(paymentIdValue);\n const cek = randomBytes(CEK_LEN);\n const bodyNonce = randomBytes(NONCE_LEN);\n const ciphertext = gcm(cek, bodyNonce, aad).encrypt(body);\n\n const wrapped = recipients.map(({ role, key }) => {\n let algByte: number;\n let ephemeral: Uint8Array;\n let shared: Uint8Array;\n\n if (key.length === 33) {\n algByte = 1;\n const priv = secp256k1.utils.randomPrivateKey();\n ephemeral = secp256k1.getPublicKey(priv, true);\n shared = secp256k1.getSharedSecret(priv, key, true).subarray(1);\n } else if (key.length === 32) {\n algByte = 2;\n const priv = randomBytes(32);\n ephemeral = x25519.getPublicKey(priv);\n shared = x25519.getSharedSecret(priv, key);\n if (shared.every((b) => b === 0)) {\n throw new DX402Error('degenerate ECDH result (small-order public key)');\n }\n } else {\n throw new DX402Error(\n `public key must be 33 bytes (secp256k1) or 32 (X25519), got ${key.length}`,\n );\n }\n\n const wrapKey = hkdf(sha256, shared, aad, HKDF_INFO, 32);\n const cekNonce = randomBytes(NONCE_LEN);\n return {\n role,\n algByte,\n ephemeral,\n cekNonce,\n wrappedCek: gcm(wrapKey, cekNonce, aad).encrypt(cek),\n };\n });\n\n const singlePayer = wrapped.length === 1 && wrapped[0].role === 'payer';\n const parts: Uint8Array[] = [MAGIC, new Uint8Array([singlePayer ? FORMAT_V1 : FORMAT_V2])];\n if (!singlePayer) parts.push(new Uint8Array([wrapped.length]));\n\n for (const r of wrapped) {\n if (!singlePayer) parts.push(new Uint8Array([ROLE_NAMES.indexOf(r.role)]));\n parts.push(new Uint8Array([r.algByte, r.ephemeral.length]));\n parts.push(r.ephemeral, r.cekNonce);\n parts.push(new Uint8Array([(r.wrappedCek.length >> 8) & 0xff, r.wrappedCek.length & 0xff]));\n parts.push(r.wrappedCek);\n }\n\n parts.push(bodyNonce, ciphertext);\n return concatBytes(...parts);\n}\n\n// ============================================================================\n// The whole seller side, in one call\n// ============================================================================\n\nexport interface AnchorOptions {\n paymentId: string;\n network: string;\n txHash: string;\n payer: string;\n payee: string;\n /** The buyer's encryption key, from `payerKeyFromSolanaAddress` or similar. */\n payerKey: Uint8Array;\n /**\n * Your **public** key, to keep a readable copy so you can answer a false\n * \"that is not what you sent\".\n *\n * It does not have to be your payment key, and should not be — a custodial\n * payment wallet works fine here, because this key only ever decrypts.\n */\n sellerEncryptionKey?: Uint8Array;\n /**\n * The settlement proof, in the facilitator's `ProofOfPayment` shape\n * (`transactionHash`, `blockNumber`, `network`, `payer`, `payee`, `amount`,\n * `token`, `timestamp`, `paymentHash`).\n *\n * **The only thing that reaches `verified: true`.** Without it the\n * facilitator has checked no chain, so it records the anchor as provisional\n * and answers `notVerifiedReason: \"dx402_proof_missing\"`: the signature is\n * accepted (`signed: true`) but authorship is not certified, and a claim that\n * proves more may supersede it.\n */\n proofOfPayment?: Record<string, unknown>;\n /**\n * Which backend to anchor to (`\"s3\"`, `\"ipfs-private\"`, `\"ipfs-public\"`).\n * Omit to take the facilitator's default.\n *\n * Ask {@link availableBackends} what a given facilitator offers rather than\n * assuming — it depends on the deployment, and you may be pointed at one that\n * is not ours. **`ipfs-public` is irreversible**: the bytes become permanently\n * resolvable by anyone, and nobody, the facilitator included, can take them\n * down.\n */\n storage?: string;\n /**\n * `(digest) => \"0x...\"`. A callable rather than a private key is what lets a\n * custodian sign: it receives the digest and returns the signature without the\n * seed ever leaving it.\n *\n * Without one the anchor is **provisional** — it holds the slot, but a signed\n * anchor for the same payment supersedes it.\n */\n sign?: (digest: Uint8Array) => string | Promise<string>;\n /**\n * `(sealedBytes) => pointer`. Bring your own storage.\n *\n * Without this the sealed envelope travels **inside** the anchor request and\n * the facilitator hosts it, which is the easy path and stays the default. With\n * it, the SDK still seals exactly as before -- the buyer has to be able to\n * decrypt, so the sealing is not optional -- then hands you the ciphertext,\n * you write it wherever you keep durable bytes, and you return the pointer\n * that addresses it. The request then carries only that pointer, so the\n * ciphertext never travels through the anchor call and\n * {@link ANCHOR_MAX_REQUEST_BYTES} does not apply to your body.\n *\n * A callable rather than a precomputed pointer, for the same reason\n * {@link AnchorOptions.sign} is one: the SDK must seal first, and only then\n * can anything be uploaded. Handing in a pointer computed in advance would\n * mean addressing bytes that do not exist yet.\n *\n * The returned pointer is what the buyer will dereference, so it must be\n * readable by them -- see {@link dereferencePointer} for the schemes the SDK\n * resolves out of the box. It is also bound into the seller signature.\n *\n * **It is never allowed to break the sale.** If it throws or returns\n * something unusable, the anchor degrades to a skip and the payment is\n * untouched.\n */\n upload?: (sealed: Uint8Array) => string | Promise<string>;\n /**\n * Which storage family the pointer belongs to: `s3`, `ipfs` or `arweave`.\n *\n * Defaults to `s3`, and in {@link AnchorOptions.upload} mode it is inferred\n * from the pointer's scheme when you do not say. Distinct from `storage`,\n * which names one of the FACILITATOR's own offers and is meaningless when you\n * supply the bytes yourself.\n */\n backend?: 's3' | 'ipfs' | 'arweave';\n retention?: string;\n facilitator?: string;\n fetch?: typeof fetch;\n}\n\n/**\n * Seal a response body, anchor it, and return the `X-Durable-Evidence` value.\n *\n * **It never throws.** Every failure resolves to a skip notice, because evidence\n * is an addition to the payment path and must never be a gate in front of it —\n * an unreachable facilitator has to cost the receipt, never the sale.\n *\n * # Two ways to store the ciphertext\n *\n * **Hosted (default).** The sealed envelope travels inside the anchor request\n * and the facilitator stores it and issues the pointer. Nothing to set up. The\n * request carries the ciphertext, so it is bounded by\n * {@link ANCHOR_MAX_REQUEST_BYTES}.\n *\n * **Your own storage.** Pass {@link AnchorOptions.upload}. The SDK seals\n * identically, hands you the ciphertext, and sends the pointer you return in\n * place of the blob — so the ciphertext never travels through the anchor call\n * and that request bound does not apply to your body. The facilitator has\n * accepted a caller-supplied pointer since v0.1; this is the SDK catching up.\n *\n * ```ts\n * await anchorEvidence(body, {\n * ...common,\n * // called with the SEALED bytes, never the plaintext\n * upload: async (sealed) => {\n * await myBucket.put(key, sealed);\n * return `s3+https://cdn.example.com/${key}`;\n * },\n * });\n * ```\n *\n * Either way the seller keeps custody of nothing it did not already have: the\n * facilitator cannot read a `direct`-mode envelope in the hosted case either.\n * What changes is durability and cost, which become yours.\n */\n\n/** `0x` + 40 hex. An ed25519 payee (Solana, Stellar) never matches. */\nfunction isEvmAddress(value: string): boolean {\n return /^0x[0-9a-fA-F]{40}$/.test((value ?? '').trim());\n}\n\n/** The chain id behind a network name or CAIP-2 id, or undefined if unknown. */\nfunction chainIdFor(network: string): number | undefined {\n // `eip155:8453` carries the chain id literally. Read it rather than going\n // through the chain table, which has no entry for EVM TESTNETS -- so without\n // this a seller on one cannot produce a verifiable anchor signature at all.\n const raw = network ?? '';\n if (raw.toLowerCase().startsWith('eip155:')) {\n const tail = raw.slice('eip155:'.length);\n if (/^\\d+$/.test(tail)) return Number(tail);\n }\n const name = raw.includes(':') ? (raw.split(':')[1] ?? '') : raw;\n const byId = Number(name);\n if (Number.isFinite(byId) && byId > 0) return getChainById(byId)?.chainId;\n return getChainByName(name)?.chainId;\n}\n\n/**\n * The digest the facilitator will ACTUALLY verify, chosen by the payee's curve.\n *\n * The gate dispatches on the payee and checks **one** form -- never both. A\n * secp256k1 payee is verified against the digest built with its REAL address and\n * chain id; an ed25519 payee, whose address does not fit the `address` field, is\n * verified against the zero address and chain id 0.\n *\n * Signing the wrong form throws nothing. It yields a signature that never\n * verifies, the anchor silently stays **provisional**, and a provisional anchor\n * can be superseded by anyone -- the very hijack a signed anchor exists to stop.\n * Reproduced against production by KarmaKadabra, 2026-08-19: with everything else\n * identical, the ed25519 form was refused (`409 dx402_already_anchored`) and the\n * EVM form superseded the provisional.\n *\n * `pointer` defaults to the empty string, which is right when you send `sealed`:\n * the facilitator issues the pointer and you cannot sign what you have not seen.\n * When you supply your OWN pointer it must be passed here **verbatim** -- the\n * facilitator verifies against `req.pointer` when one is present and against\n * `\"\"` when it is absent (x402-rs `dx402/service.rs`, `signed_pointer`), so\n * signing the empty string alongside a pointer produces a signature that never\n * verifies and an anchor that silently stays provisional.\n */\nexport function sellerDigestFor(\n paymentId: string,\n contentHash: string,\n payee: string,\n network: string,\n pointer = '',\n): Uint8Array | undefined {\n if (isEvmAddress(payee)) {\n const chainId = chainIdFor(network);\n // An EVM payee whose chain id we cannot resolve. Falling through to the\n // ed25519 form is how this shipped in 0.53.0: it throws nothing and yields\n // a signature that never verifies, so the anchor stays provisional forever\n // with no error anywhere. Refuse instead -- unsigned is honest and\n // recoverable, signed-but-worthless only looks done.\n if (!chainId) return undefined;\n return anchorDigest(paymentId, contentHash, pointer, payee, chainId);\n }\n return anchorDigest(paymentId, contentHash, pointer, ZERO_ADDRESS, 0);\n}\n\n\n/**\n * Largest `POST /dx402/anchor` request the facilitator accepts, mirroring its\n * `MAX_REQUEST_BODY_BYTES` (default 64 KiB, an anti-OOM bound on every route).\n */\nexport const ANCHOR_MAX_REQUEST_BYTES = 64 * 1024;\n\n\n/** base64 without spreading the array into arguments -- a large blob would\n * otherwise overflow the call stack and surface as a generic failure. */\nfunction toBase64(bytes: Uint8Array): string {\n let out = '';\n const CHUNK = 0x8000;\n for (let i = 0; i < bytes.length; i += CHUNK) {\n out += String.fromCharCode(...bytes.subarray(i, i + CHUNK));\n }\n return btoa(out);\n}\n\n/**\n * Which storage family a pointer names, for the anchor's `backend` field.\n *\n * The facilitator records this; it does not fetch through it. `s3` is the\n * fallback because `s3+https://` is the SDK's own scheme for \"an ordinary HTTPS\n * URL\", which is what most sellers' own sinks are.\n */\nfunction backendForPointer(pointer: string): 's3' | 'ipfs' | 'arweave' {\n if (pointer.startsWith('ipfs://')) return 'ipfs';\n if (pointer.startsWith('ar://')) return 'arweave';\n return 's3';\n}\n\nexport async function anchorEvidence(\n body: Uint8Array,\n opts: AnchorOptions,\n): Promise<Record<string, unknown>> {\n try {\n const recipients: Array<{ role: RecipientRole; key: Uint8Array }> = [\n { role: 'payer', key: opts.payerKey },\n ];\n if (opts.sellerEncryptionKey) {\n recipients.push({ role: 'seller', key: opts.sellerEncryptionKey });\n }\n const blob = sealEvidenceTo(body, recipients, opts.paymentId);\n const hash = contentHash(body);\n\n // Bring-your-own-storage. The sealing above is identical either way -- the\n // buyer must be able to decrypt -- so all that changes is who holds the\n // ciphertext and, therefore, whether it has to travel in this request.\n //\n // The upload is fenced off completely: a seller's bucket going down is not\n // a reason for a paid response to fail, so anything thrown here becomes a\n // skip, exactly like an unreachable facilitator.\n let pointer: string | undefined;\n if (opts.upload) {\n try {\n pointer = await opts.upload(blob);\n } catch {\n return { v: 1, skipped: 'anchor_failed', stage: 'upload' };\n }\n if (typeof pointer !== 'string' || pointer.trim() === '') {\n // An empty pointer addresses nothing, and the facilitator would record\n // an anchor that dereferences to a 404 forever. Worse than no anchor.\n return { v: 1, skipped: 'anchor_failed', stage: 'upload' };\n }\n pointer = pointer.trim();\n }\n\n const payload: Record<string, unknown> = {\n paymentId: opts.paymentId,\n network: opts.network,\n txHash: opts.txHash,\n payer: opts.payer,\n payee: opts.payee,\n // Exactly one of these. The facilitator dispatches on their presence:\n // `sealed` -> it hosts and derives the pointer; `pointer` alone -> it uses\n // yours; neither -> error (x402-rs `dx402/service.rs`).\n ...(pointer !== undefined ? { pointer } : { sealed: toBase64(blob) }),\n // Declared, not measured. Since x402-rs 2.3.0 the facilitator records\n // the store that ACTUALLY took the bytes and returns that, so a response\n // may name a different backend than the request did -- `ipfs` where you\n // said `s3`, because a deployment whose primary is Pinata wrote there.\n // That is the facilitator correcting the record, not a mismatch to\n // assert on.\n backend: opts.backend ?? (pointer !== undefined ? backendForPointer(pointer) : 's3'),\n contentHash: hash,\n keyAlg: opts.payerKey.length === 32 ? 'ECIES-X25519' : 'ECIES-secp256k1',\n mode: 'direct',\n retention: opts.retention ?? '90d',\n };\n\n let unsigned: string | undefined;\n if (opts.proofOfPayment) {\n payload.proofOfPayment = opts.proofOfPayment;\n }\n\n if (opts.storage) {\n payload.storage = opts.storage;\n }\n\n if (opts.sign) {\n // The signature covers the pointer the facilitator will verify against:\n // ours when we supply one, the empty string when the facilitator issues\n // it. Signing the wrong one throws nothing and leaves the anchor\n // provisional -- which is the state anyone can supersede.\n const digest = sellerDigestFor(opts.paymentId, hash, opts.payee, opts.network, pointer ?? '');\n if (digest === undefined) {\n unsigned = 'unknown_chain_id';\n } else {\n payload.sellerSignature = await opts.sign(digest);\n }\n }\n\n // Measure the SEALED, serialised request -- not the plaintext. The\n // envelope adds a nonce, the wrapped CEK and its JSON, and the ciphertext\n // travels base64 (4/3). Checking the plaintext lets through bodies the\n // facilitator then rejects, arriving as a generic failure long after the\n // sealing work was done. Measured by KarmaKadabra, 2026-08-19: 47 KB of\n // plaintext fits, 48 KB does not.\n //\n // In `upload` mode the ciphertext is not in the request at all, so this\n // bound says nothing about the body and is not applied. The request is a\n // pointer and some metadata; only a pathological pointer could approach it.\n const wire = JSON.stringify(payload);\n if (pointer === undefined && new TextEncoder().encode(wire).length > ANCHOR_MAX_REQUEST_BYTES) {\n return { v: 1, skipped: 'too_large' };\n }\n\n const base = (opts.facilitator ?? 'https://facilitator.ultravioletadao.xyz').replace(\n /\\/+$/,\n '',\n );\n const doFetch = opts.fetch ?? fetch;\n const res = await doFetch(`${base}/dx402/anchor`, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: wire,\n });\n // Carry the facilitator's own diagnosis out rather than flattening every\n // failure to `anchor_failed`. A rejected signature answers 422\n // `dx402_signature_not_verified`; erasing it here would reproduce, one\n // layer down, the exact problem that code exists to solve.\n if (!res.ok) {\n let error: unknown;\n try {\n error = ((await res.json()) as { error?: unknown }).error;\n } catch {\n /* a non-JSON error body is still a failure */\n }\n return { v: 1, skipped: 'anchor_failed', status: res.status, error };\n }\n const out = (await res.json()) as Record<string, unknown>;\n if (unsigned) out.unsigned = unsigned;\n return out;\n } catch {\n return { v: 1, skipped: 'anchor_failed' };\n }\n}\n\n/** One storage option a facilitator offers, from `GET /dx402/stats`. */\nexport interface BackendOffer {\n id: string;\n retention: string;\n /**\n * Whether the bytes can actually be removed when retention expires.\n *\n * `false` means the `retentionUntil` in the signed receipt **cannot be\n * honoured**: on public IPFS, unpinning removes the facilitator's copy, not\n * the network's.\n */\n revocable: boolean;\n /** Whether anyone resolves the bytes without going through the facilitator. */\n public: boolean;\n enabled: boolean;\n disabledReason?: string;\n}\n\n/**\n * Ask a facilitator which storage backends it actually offers.\n *\n * Ask instead of assuming. What exists depends on the deployment — one without\n * a Pinata credential offers only `s3` — and an integrator may be pointed at a\n * facilitator that is not ours. A hardcoded list in your code is a promise\n * somebody else has to keep.\n *\n * Resolves to `[]` rather than rejecting when the facilitator is unreachable or\n * does not run DX402 — same discipline as {@link anchorEvidence}.\n */\nexport async function availableBackends(\n facilitator = 'https://facilitator.ultravioletadao.xyz',\n opts: { fetch?: typeof fetch } = {},\n): Promise<BackendOffer[]> {\n try {\n const doFetch = opts.fetch ?? fetch;\n const res = await doFetch(`${facilitator.replace(/\\/+$/, '')}/dx402/stats`);\n if (!res.ok) return [];\n const body = (await res.json()) as { backends?: BackendOffer[] };\n return body.backends ?? [];\n } catch {\n return [];\n }\n}\n\n/** Encode an anchor result for the `X-Durable-Evidence` response header. */\nexport function evidenceHeader(evidence: unknown): string {\n // Encode to UTF-8 first. `btoa` takes a *binary* string: any code point above\n // U+00FF throws InvalidCharacterError, and one between U+0080 and U+00FF is\n // silently emitted as a single latin-1 byte, so the far side decodes mojibake.\n // Either is reachable from ordinary evidence -- a `notVerifiedReason` or a\n // pointer with a non-ASCII character is enough.\n const bytes = new TextEncoder().encode(JSON.stringify(evidence));\n return toBase64(bytes).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\n}\n","/** Portable payment receipts. They attest settlement, not merchant delivery. */\nimport { ed25519 } from '@noble/curves/ed25519';\nimport { sha256 } from '@noble/hashes/sha256';\nimport { bytesToHex, randomBytes } from '@noble/hashes/utils';\nimport type { X402FetchOptions } from './types';\n\nexport const RECEIPT_ISSUER = 'https://facilitator.ultravioletadao.xyz';\nexport type PaymentState = 'verified' | 'pending' | 'confirmed' | 'rejected' | 'unknown' | 'not_required';\nexport interface FacilitatorReceipt {\n schemaVersion: number; receiptId: string; revision: number; issuer: string; issuedAt: number;\n operation: string; purchaseId: string | null; network: string; scheme: string; x402Version: number;\n asset: string; amount: string; decimals: number | null; payTo: string; payer: string | null;\n requestHash: string; requestHashVersion: string; request: Record<string, unknown>;\n paymentRequestHash: string; authorizationId: string; status: string;\n settlement: { id: string; idType: string; paymentId?: string | null; [key: string]: unknown } | null;\n refusalReason: string | null; diagnosticCode: string | null;\n retry: { action: string; afterSeconds?: number; [key: string]: unknown };\n proof: { type: string; jws?: string; [key: string]: unknown } | null;\n [key: string]: unknown;\n}\nexport interface PurchaseContext {\n purchaseId: string;\n /** Secret lookup capability. Store privately alongside paymentHeaders. */\n accessToken: string;\n method?: string; url?: string; bodySha256?: string;\n paymentHeaders?: Record<string, string>;\n receipt?: FacilitatorReceipt;\n}\nexport interface ReceiptKeys { keys: Array<{ kid?: string; kty?: string; crv?: string; x?: string }> }\nexport interface FetchReceiptResult {\n response: Response | null; receipt: FacilitatorReceipt | null; paymentState: PaymentState;\n context: PurchaseContext; proofVerified: boolean; error?: unknown;\n}\nexport interface ReceiptFetchOptions extends X402FetchOptions {\n context: PurchaseContext;\n /** Must complete before the authorized request is sent. */\n persist: (context: PurchaseContext) => void | Promise<void>;\n trustedKeys?: ReceiptKeys;\n issuer?: string;\n}\n\nconst encoder = new TextEncoder();\nconst decoder = new TextDecoder('utf-8', { fatal: true });\nconst digest = (value: Uint8Array): string => bytesToHex(sha256(value));\n\nexport function canonicalReceiptJson(value: unknown): string {\n if (value === null || typeof value === 'string' || typeof value === 'boolean') return JSON.stringify(value);\n if (typeof value === 'number' && Number.isSafeInteger(value) && value >= 0) return String(value);\n if (Array.isArray(value)) return `[${value.map(canonicalReceiptJson).join(',')}]`;\n if (typeof value === 'object' && value) {\n const object = value as Record<string, unknown>;\n const keys = Object.keys(object).sort();\n if (keys.some(key => !/^[\\x00-\\x7f]*$/.test(key))) throw new Error('non-ASCII canonical key');\n return `{${keys.map(key => `${JSON.stringify(key)}:${canonicalReceiptJson(object[key])}`).join(',')}}`;\n }\n throw new Error('unsupported canonical value');\n}\nexport function receiptCommitment(domain: string, value: unknown): string {\n return digest(encoder.encode(`${domain}\\n${canonicalReceiptJson(value)}`));\n}\n\nfunction encode64(bytes: Uint8Array): string {\n if (typeof Buffer !== 'undefined') return Buffer.from(bytes).toString('base64');\n return btoa(Array.from(bytes, b => String.fromCharCode(b)).join(''));\n}\nfunction decode64(value: string): Uint8Array {\n if (!/^[A-Za-z0-9+/]*={0,2}$/.test(value) || value.length % 4 !== 0) throw new Error('invalid base64');\n if (typeof Buffer !== 'undefined') return new Uint8Array(Buffer.from(value, 'base64'));\n return Uint8Array.from(atob(value), c => c.charCodeAt(0));\n}\nfunction decodeUrl64(value: string): Uint8Array {\n const padded = value.replace(/-/g, '+').replace(/_/g, '/');\n return decode64(padded + '='.repeat((4 - padded.length % 4) % 4));\n}\n\nexport function parseFacilitatorReceipt(value: unknown): FacilitatorReceipt | null {\n if (value === null || value === undefined) return null;\n const r = value as FacilitatorReceipt;\n if (r.schemaVersion !== 1 || !['verified', 'pending', 'confirmed', 'rejected', 'unknown'].includes(r.status)) throw new Error('unsupported receipt version or state');\n for (const key of ['receiptId', 'issuer', 'operation', 'network', 'scheme', 'asset', 'amount', 'payTo', 'paymentRequestHash', 'authorizationId']) {\n if (typeof r[key] !== 'string' || !r[key]) throw new Error(`invalid receipt ${key}`);\n }\n if (!Number.isSafeInteger(r.revision) || r.revision < 1 || !r.request || !r.retry) throw new Error('incomplete receipt');\n if (r.requestHashVersion !== 'uvd-x402-request-v1' || r.requestHash !== receiptCommitment(r.requestHashVersion, r.request)) throw new Error('receipt request hash mismatch');\n for (const key of ['network', 'scheme', 'asset', 'amount', 'payTo', 'purchaseId']) {\n if (r[key] !== r.request[key]) throw new Error('receipt terms mismatch');\n }\n if (!/^[0-9]+$/.test(r.amount)) throw new Error('receipt amount must be an atomic integer string');\n if (r.status === 'confirmed' && (r.operation !== 'settle' || !r.settlement?.id)) throw new Error('confirmation has no settlement');\n return r;\n}\n\n/** Keys must be trusted independently of the receipt; no auto-fetch of issuer URLs. */\nexport function verifyFacilitatorReceipt(receipt: FacilitatorReceipt, jwks: ReceiptKeys, issuer = RECEIPT_ISSUER): boolean {\n try {\n parseFacilitatorReceipt(receipt);\n if (receipt.issuer !== issuer || receipt.proof?.type !== 'jws' || !receipt.proof.jws) return false;\n const parts = receipt.proof.jws.split('.');\n if (parts.length !== 3) return false;\n const [protectedHeader, payload, signature] = parts;\n const header = JSON.parse(decoder.decode(decodeUrl64(protectedHeader)));\n if (header.alg !== 'EdDSA' || header.typ !== 'uvd-facilitator-receipt+jws') return false;\n const keys = jwks.keys.filter(k => k.kid === header.kid && k.kty === 'OKP' && k.crv === 'Ed25519');\n if (keys.length !== 1 || !keys[0].x) return false;\n if (decoder.decode(decodeUrl64(payload)) !== canonicalReceiptJson({ ...receipt, proof: null })) return false;\n return ed25519.verify(decodeUrl64(signature), encoder.encode(`${protectedHeader}.${payload}`), decodeUrl64(keys[0].x));\n } catch { return false; }\n}\n\nexport function createPurchaseContext(): PurchaseContext {\n return { purchaseId: bytesToHex(randomBytes(16)), accessToken: bytesToHex(randomBytes(32)) };\n}\nexport function purchaseContextHeader(context: PurchaseContext): string {\n return encode64(encoder.encode(canonicalReceiptJson({ purchaseId: context.purchaseId, accessToken: context.accessToken,\n method: context.method, url: context.url, bodySha256: context.bodySha256 })));\n}\n/** Merchant-side binding to the actual request, before asking the facilitator. */\nexport function validatePurchaseContext(header: string | undefined, method: string, url: string, body: Uint8Array): string | undefined {\n if (!header) return undefined;\n if (header.length > 8192) throw new Error('invalid purchase context');\n const context = JSON.parse(decoder.decode(decode64(header)));\n if (typeof context.purchaseId !== 'string' || !context.purchaseId || context.purchaseId.length > 128\n || typeof context.accessToken !== 'string' || !/^[0-9a-f]{64}$/.test(context.accessToken)\n || context.method !== method.toUpperCase() || context.url !== new URL(url).toString()\n || context.bodySha256 !== digest(body)) throw new Error('purchase context does not match the HTTP request');\n return header;\n}\nexport function paymentResponseHeaders(result: Record<string, unknown>): Record<string, string> {\n const encoded = encode64(encoder.encode(JSON.stringify(result)));\n if (encoded.length > 32768) throw new Error('payment response too large');\n return { 'PAYMENT-RESPONSE': encoded, 'X-PAYMENT-RESPONSE': encoded,\n 'Access-Control-Expose-Headers': 'PAYMENT-RESPONSE, X-PAYMENT-RESPONSE', 'Cache-Control': 'no-store' };\n}\n/** Headers that hold a comma-separated list the application may already have set. */\nconst LIST_HEADERS = ['Access-Control-Expose-Headers', 'Cache-Control'];\n/**\n * Adds the comma-separated `additions` to `existing`, keeping every entry already\n * there and its spelling. Entries compare case-insensitively by name, so a\n * `Cache-Control` of `no-store, max-age=0` does not gain a second `no-store`.\n */\nexport function mergeHeaderList(existing: string | undefined, additions: string): string {\n const name = (entry: string) => entry.split('=')[0].trim().toLowerCase();\n const kept = (existing || '').split(',').map(entry => entry.trim()).filter(Boolean);\n const seen = new Set(kept.map(name));\n for (const entry of additions.split(',').map(value => value.trim()).filter(Boolean)) {\n if (!seen.has(name(entry))) { kept.push(entry); seen.add(name(entry)); }\n }\n return kept.join(', ');\n}\n/**\n * {@link paymentResponseHeaders} for a response that may already carry CORS or\n * cache headers: `Access-Control-Expose-Headers` and `Cache-Control` are merged\n * with the current value read through `current`, never replaced.\n */\nexport function mergePaymentResponseHeaders(\n result: Record<string, unknown>, current: (name: string) => string | undefined,\n): Record<string, string> {\n const headers = paymentResponseHeaders(result);\n for (const name of LIST_HEADERS) headers[name] = mergeHeaderList(current(name), headers[name]);\n return headers;\n}\nexport function receiptFromResponse(response: Response): FacilitatorReceipt | null {\n const values = [response.headers.get('PAYMENT-RESPONSE'), response.headers.get('X-PAYMENT-RESPONSE')].filter((v): v is string => v !== null);\n if (!values.length) return null;\n if (new Set(values).size !== 1 || values[0].includes(',') || values[0].length > 32768) throw new Error('ambiguous or oversized payment response header');\n return parseFacilitatorReceipt(JSON.parse(decoder.decode(decode64(values[0]))).receipt);\n}\n/** HTTP error bodies can be plain text. Preserve their original diagnosis. */\nexport function receiptFromErrorBody(body: string): FacilitatorReceipt | null {\n try { return parseFacilitatorReceipt(JSON.parse(body).receipt); } catch { return null; }\n}\n\nexport async function fetchWithReceipt(\n fetchClient: (url: string, options: X402FetchOptions) => Promise<Response>, url: string, options: ReceiptFetchOptions,\n): Promise<FetchReceiptResult> {\n const { context, persist, trustedKeys, issuer = RECEIPT_ISSUER } = options;\n const transport = options.fetchImpl || globalThis.fetch;\n const method = (options.method || 'GET').toUpperCase();\n const request = new Request(url, { ...options.init, method });\n const bytes = new Uint8Array(await request.arrayBuffer());\n const bodyHash = digest(bytes);\n if (context.method && (context.method !== method || context.url !== request.url || context.bodySha256 !== bodyHash)) throw new Error('purchase context cannot be reused for another HTTP request');\n context.method = method; context.url = request.url; context.bodySha256 = bodyHash;\n const init = { ...options.init, method, headers: new Headers(request.headers), body: ['GET', 'HEAD'].includes(method) ? undefined : bytes };\n let receipt = parseFacilitatorReceipt(context.receipt);\n let transportError: unknown;\n const persistCopy = async () => { await persist(JSON.parse(JSON.stringify(context))); };\n const send: typeof fetch = async (input, sendOptions) => {\n const headers = new Headers(sendOptions?.headers);\n const paid = headers.get('X-PAYMENT') || headers.get('PAYMENT-SIGNATURE');\n if (paid) {\n const paymentHeaders: Record<string, string> = {};\n for (const name of ['X-PAYMENT', 'PAYMENT-SIGNATURE']) {\n const value = headers.get(name); if (value) paymentHeaders[name] = value;\n }\n if (context.paymentHeaders && JSON.stringify(context.paymentHeaders) !== JSON.stringify(paymentHeaders)) throw new Error('refusing a new authorization for an existing purchase');\n context.paymentHeaders = paymentHeaders;\n headers.set('X-UVD-Purchase', purchaseContextHeader(context));\n await persistCopy();\n }\n try { return await transport(input, { ...sendOptions, headers }); }\n catch (error) { transportError = error; throw error; }\n };\n try {\n let response: Response;\n if (context.paymentHeaders) {\n const headers = new Headers(init.headers);\n for (const [name, value] of Object.entries(context.paymentHeaders)) headers.set(name, value);\n response = await send(request.url, { ...init, headers });\n } else {\n response = await fetchClient(request.url, { ...options, method, init, fetchImpl: send });\n }\n const incoming = receiptFromResponse(response);\n if (incoming) {\n if (incoming.issuer !== issuer || Object.entries({ purchaseId: context.purchaseId, method, url: context.url, bodySha256: bodyHash }).some(([key, value]) => incoming.request[key] !== value)) throw new Error('receipt does not bind this purchase');\n if (receipt?.operation === 'settle' && (incoming.receiptId !== receipt.receiptId || incoming.revision < receipt.revision)) throw new Error('receipt revision conflict');\n if (trustedKeys && !verifyFacilitatorReceipt(incoming, trustedKeys, issuer)) throw new Error('receipt signature verification failed');\n receipt = incoming; context.receipt = incoming; await persistCopy();\n }\n const proofVerified = !!(receipt && trustedKeys && verifyFacilitatorReceipt(receipt, trustedKeys, issuer));\n if (receipt && trustedKeys && !proofVerified) throw new Error('receipt signature verification failed');\n return { response, receipt, paymentState: receipt ? receipt.status as PaymentState : context.paymentHeaders ? 'unknown' : 'not_required', context, proofVerified };\n } catch (error) {\n if (!transportError) throw error;\n return { response: null, receipt, paymentState: 'unknown', context, proofVerified: false, error };\n }\n}\n\nexport async function getFacilitatorReceipt(receiptId: string, context: PurchaseContext, options: { issuer?: string; fetchImpl?: typeof fetch } = {}): Promise<FacilitatorReceipt> {\n if (!/^[0-9a-f-]{36}$/.test(receiptId)) throw new Error('invalid receipt ID');\n const issuer = options.issuer || RECEIPT_ISSUER;\n const response = await (options.fetchImpl || globalThis.fetch)(`${issuer}/receipts/${receiptId}`, { headers: { Authorization: `Bearer ${context.accessToken}` } });\n if (!response.ok) throw new Error(`receipt lookup failed: ${response.status}`);\n const receipt = parseFacilitatorReceipt((await response.json()).receipt);\n if (!receipt || receipt.issuer !== issuer || receipt.purchaseId !== context.purchaseId) throw new Error('receipt lookup mismatch');\n return receipt;\n}\n","/**\n * uvd-x402-sdk - Main Client\n *\n * The X402Client is the primary entry point for the SDK.\n * It manages wallet connections, chain switching, and payment creation.\n */\n\nimport { ethers } from 'ethers';\nimport { fetchWithReceipt, type ReceiptFetchOptions, type FetchReceiptResult } from '../receipts';\nimport type {\n ChainConfig,\n NetworkType,\n PaymentInfo,\n PaymentResult,\n WalletState,\n X402ClientConfig,\n X402Event,\n X402EventData,\n X402EventHandler,\n EVMPaymentPayload,\n TokenType,\n X402EVMPayload,\n X402Version,\n X402PaymentOffer,\n X402FetchOptions,\n WalletAdapter,\n} from '../types';\nimport { X402Error, DEFAULT_CONFIG } from '../types';\nimport {\n PurchasePolicy,\n PolicyRefusedError,\n decideOnChallenge,\n noReadableOffer,\n canonicalRecipient,\n} from '../policy';\nimport type { PolicyApproval, ReadChallenge } from '../policy';\nimport {\n SUPPORTED_CHAINS,\n getChainByName,\n getChainById,\n getEnabledChains,\n getTokenConfig,\n} from '../chains';\nimport {\n validateRecipient,\n chainToCAIP2,\n caip2ToChain,\n encodeBase64Json,\n buildTokenMetadata,\n resolveValiditySeconds,\n clampValiditySeconds,\n} from '../utils';\n\n/**\n * The x402 scheme vocabulary, shared by all three implementations.\n *\n * The same five the Rust facilitator's closed `Scheme` enum holds and the same\n * five the Python SDK keys `KNOWN_SCHEMES` on. A scheme outside this set is one\n * no implementation in the stack can name, so an entry carrying one is unreadable\n * and is counted by the name the seller used.\n *\n * Kept as a set of known NAMES rather than of payable ones because the two are\n * different questions, and conflating them is what rule 7 is about: naming what a\n * seller offered is how a caller learns to go find a facilitator that implements\n * it. See {@link CLIENT_PAYABLE_SCHEMES} for the other question.\n */\nexport const KNOWN_SCHEMES: ReadonlySet<string> = new Set([\n 'exact',\n 'upto',\n 'escrow',\n 'commerce',\n 'fhe-transfer',\n]);\n\n/**\n * Of those, the ones the BUYER path in this client can actually sign.\n *\n * One entry, and that is the point: the payload builder stamps\n * `scheme: 'exact'` into everything it produces, so `exact` is the only thing\n * this client can honestly present. `escrow` and `commerce` are implemented on\n * the SELLER side (`src/backend`) and in the pre-auth builder, and `upto` and\n * `fhe-transfer` are not implemented here at all.\n *\n * # Why this is a SECOND set and not a narrower first one\n *\n * `parse402` used to accept any entry carrying an amount, a payee and a network,\n * so a well-formed offer asking for a scheme this build cannot present was read\n * as payable and then **signed as `exact`** -- a payment offered to the seller\n * under a scheme it never asked for. Recognising a scheme is not being able to\n * pay it. Collapsing these two sets into one re-opens exactly that hole: widen\n * this one to the five known names and a well-formed `escrow` offer gets signed\n * as `exact` again.\n *\n * Both cases end the same way for the caller -- the entry is excluded and counted\n * by its scheme name -- and `no-readable-offer` says \"no offer in this challenge\n * is one this build **can pay**\", which is the frame both of them sit in.\n */\nexport const CLIENT_PAYABLE_SCHEMES: ReadonlySet<string> = new Set(['exact']);\n\n/**\n * X402Client - Main SDK client for x402 payments\n *\n * @example\n * ```ts\n * import { X402Client } from 'uvd-x402-sdk';\n *\n * const client = new X402Client({ defaultChain: 'base' });\n *\n * // Connect wallet\n * await client.connect('base');\n *\n * // Create payment\n * const result = await client.createPayment({\n * recipient: '0x...',\n * amount: '10.00',\n * });\n *\n * // Use result.paymentHeader in your API request\n * ```\n */\nexport class X402Client {\n // Configuration\n private readonly config: Required<Pick<X402ClientConfig, 'facilitatorUrl' | 'defaultChain' | 'autoConnect' | 'debug'>> & X402ClientConfig;\n\n // Wallet state\n private provider: ethers.BrowserProvider | ethers.JsonRpcProvider | null = null;\n private signer: ethers.Signer | null = null;\n private connectedAddress: string | null = null;\n private currentChainId: number | null = null;\n private currentNetwork: NetworkType | null = null;\n private currentChainName: string | null = null;\n /**\n * Non-EVM wallet, when one is connected. EVM keeps using `provider`/`signer`\n * because those are ethers-typed; every other network type talks through the\n * {@link WalletAdapter} contract instead.\n */\n private walletAdapter: WalletAdapter | null = null;\n\n // Event emitter\n private eventHandlers: Map<X402Event, Set<X402EventHandler<X402Event>>> = new Map();\n\n /**\n * What this buyer is allowed to sign, evaluated against the offer in hand\n * before anything is signed.\n *\n * `permissive()` when the caller supplied none, and that asymmetry is\n * deliberate: this SDK had no budget before 2.89.0, so switching one on\n * silently would refuse payments consumers are making today, while whoever\n * sits down to WRITE a policy gets the deny-by-default one.\n */\n private readonly purchasePolicy: PurchasePolicy;\n\n constructor(config: X402ClientConfig = {}) {\n // A window that cannot be signed is refused while the client is built, not\n // on its first payment with a user waiting -- and before the RPC and chain\n // overrides below touch the shared registry.\n resolveValiditySeconds(undefined, config.validitySeconds);\n\n this.config = {\n ...DEFAULT_CONFIG,\n ...config,\n };\n\n // Apply custom RPC overrides\n if (config.rpcOverrides) {\n for (const [chainName, rpcUrl] of Object.entries(config.rpcOverrides)) {\n if (SUPPORTED_CHAINS[chainName]) {\n SUPPORTED_CHAINS[chainName].rpcUrl = rpcUrl;\n }\n }\n }\n\n // Apply custom chain configurations\n if (config.customChains) {\n for (const [chainName, chainConfig] of Object.entries(config.customChains)) {\n if (SUPPORTED_CHAINS[chainName]) {\n Object.assign(SUPPORTED_CHAINS[chainName], chainConfig);\n }\n }\n }\n\n this.purchasePolicy = config.policy ?? PurchasePolicy.permissive();\n\n this.log('X402Client initialized', { config: this.config });\n }\n\n /**\n * The policy in force, for a caller that wants to record a settled payment\n * against it with {@link PurchasePolicy.recordSpend}.\n *\n * Nothing on the payment path ever widens it.\n */\n get policy(): PurchasePolicy {\n return this.purchasePolicy;\n }\n\n // ============================================================================\n // PUBLIC API - Wallet Connection\n // ============================================================================\n\n /**\n * Connect to a wallet on the specified chain\n */\n async connect(chainName?: string): Promise<string> {\n const targetChain = chainName || this.config.defaultChain;\n const chain = getChainByName(targetChain);\n\n if (!chain) {\n throw new X402Error(`Unsupported chain: ${targetChain}`, 'CHAIN_NOT_SUPPORTED');\n }\n\n if (!chain.x402.enabled) {\n throw new X402Error(`Chain ${targetChain} is not enabled for x402 payments`, 'CHAIN_NOT_SUPPORTED');\n }\n\n this.log(`Connecting wallet on ${chain.displayName}...`);\n\n // Route to appropriate connection method based on network type\n switch (chain.networkType) {\n case 'evm':\n return this.connectEVMWallet(chain);\n case 'svm':\n // The registry says 'svm' for Solana and Fogo; this used to read\n // `case 'solana'`, which no chain has ever carried, so every SVM\n // caller fell through to `default:`. `NetworkType` allows both\n // spellings, so the compiler never caught it.\n return this.connectSVMWallet(chain);\n case 'stellar':\n throw new X402Error(\n 'Stellar support requires importing from \"uvd-x402-sdk/stellar\"',\n 'CHAIN_NOT_SUPPORTED'\n );\n case 'near':\n throw new X402Error(\n 'NEAR support requires importing from \"uvd-x402-sdk/near\"',\n 'CHAIN_NOT_SUPPORTED'\n );\n case 'hedera':\n throw new X402Error('Use HederaProvider from \"uvd-x402-sdk/hedera\" with connectWithAdapter()', 'CHAIN_NOT_SUPPORTED');\n case 'xrpl':\n throw new X402Error(\n 'XRPL support requires importing from \"uvd-x402-sdk/xrpl\"',\n 'CHAIN_NOT_SUPPORTED'\n );\n default:\n throw new X402Error(`Unknown network type for chain ${targetChain}`, 'CHAIN_NOT_SUPPORTED');\n }\n }\n\n /** Connect a native-chain adapter, e.g. HederaProvider, without an EVM wallet. */\n async connectWithAdapter(adapter: WalletAdapter, chainName: string): Promise<string> {\n const chain = getChainByName(chainName);\n if (!chain?.x402.enabled || chain.networkType !== adapter.networkType) {\n throw new X402Error('Adapter does not support the selected chain', 'CHAIN_NOT_SUPPORTED');\n }\n await this.disconnect();\n const address = await adapter.connect(chain.name);\n this.walletAdapter = adapter;\n this.connectedAddress = address;\n this.currentChainName = chain.name;\n this.currentChainId = chain.chainId;\n this.currentNetwork = chain.networkType;\n this.emit('connect', this.getState());\n return address;\n }\n\n /** Connect using a private key (Node.js / server-side, no browser wallet needed). */\n async connectWithPrivateKey(privateKey: string, chainName?: string): Promise<string> {\n const targetChain = chainName || this.config.defaultChain;\n const chain = getChainByName(targetChain);\n\n if (!chain) {\n throw new X402Error(`Unsupported chain: ${targetChain}`, 'CHAIN_NOT_SUPPORTED');\n }\n\n if (!chain.x402.enabled) {\n throw new X402Error(`Chain ${targetChain} is not enabled for x402 payments`, 'CHAIN_NOT_SUPPORTED');\n }\n\n if (chain.networkType !== 'evm') {\n throw new X402Error('connectWithPrivateKey is only supported for EVM chains', 'CHAIN_NOT_SUPPORTED');\n }\n\n this.log(`Connecting with private key on ${chain.displayName}...`);\n\n const rpcProvider = new ethers.JsonRpcProvider(chain.rpcUrl);\n const wallet = new ethers.Wallet(privateKey, rpcProvider);\n\n this.provider = rpcProvider;\n this.signer = wallet;\n this.connectedAddress = wallet.address;\n this.currentChainId = chain.chainId;\n this.currentNetwork = 'evm';\n this.currentChainName = chain.name;\n\n const state = this.getState();\n this.emit('connect', state);\n this.log('Private key wallet connected', { address: this.connectedAddress, chain: chain.name });\n\n return this.connectedAddress;\n }\n\n /**\n * Disconnect the current wallet\n */\n async disconnect(): Promise<void> {\n if (this.walletAdapter) {\n try {\n await this.walletAdapter.disconnect();\n } catch {\n // A wallet that is already gone must not block local teardown.\n }\n this.walletAdapter = null;\n }\n this.provider = null;\n this.signer = null;\n this.connectedAddress = null;\n this.currentChainId = null;\n this.currentNetwork = null;\n this.currentChainName = null;\n\n this.emit('disconnect', undefined);\n this.log('Wallet disconnected');\n }\n\n /**\n * Switch to a different chain (EVM only)\n */\n async switchChain(chainName: string): Promise<void> {\n const chain = getChainByName(chainName);\n\n if (!chain) {\n throw new X402Error(`Unsupported chain: ${chainName}`, 'CHAIN_NOT_SUPPORTED');\n }\n\n if (chain.networkType !== 'evm') {\n throw new X402Error(\n 'switchChain is only supported for EVM networks. Reconnect with connect() for other networks.',\n 'CHAIN_NOT_SUPPORTED'\n );\n }\n\n if (!this.provider) {\n throw new X402Error('Wallet not connected', 'WALLET_NOT_CONNECTED');\n }\n\n // Private key connections cannot use wallet_switchEthereumChain — re-create provider\n if (this.provider instanceof ethers.JsonRpcProvider && this.signer instanceof ethers.Wallet) {\n const rpcProvider = new ethers.JsonRpcProvider(chain.rpcUrl);\n const wallet = new ethers.Wallet(this.signer.privateKey, rpcProvider);\n this.provider = rpcProvider;\n this.signer = wallet;\n this.currentChainId = chain.chainId;\n this.currentChainName = chain.name;\n this.emit('chainChanged', { chainId: chain.chainId, chainName: chain.name });\n this.log('Switched chain (private key mode)', { chain: chain.name });\n return;\n }\n\n await this.switchEVMChain(chain);\n }\n\n // ============================================================================\n // PUBLIC API - Payment Creation\n // ============================================================================\n\n /**\n * Create a payment authorization\n *\n * @param paymentInfo - Payment information from 402 response\n * @returns Payment result with encoded X-PAYMENT header\n */\n async createPayment(paymentInfo: PaymentInfo): Promise<PaymentResult> {\n if (!this.connectedAddress) {\n throw new X402Error('Wallet not connected', 'WALLET_NOT_CONNECTED');\n }\n\n if (!this.currentChainName) {\n throw new X402Error('Chain not set', 'CHAIN_NOT_SUPPORTED');\n }\n\n const chain = getChainByName(this.currentChainName);\n if (!chain) {\n throw new X402Error(`Chain ${this.currentChainName} not found`, 'CHAIN_NOT_SUPPORTED');\n }\n\n this.emit('paymentStarted', { amount: paymentInfo.amount, network: chain.name });\n this.log('Creating payment...', { paymentInfo, chain: chain.name });\n\n try {\n // Route to appropriate payment method\n switch (chain.networkType) {\n case 'evm':\n return await this.createEVMPayment(paymentInfo, chain);\n default:\n if (this.walletAdapter?.networkType === chain.networkType) {\n return await this.createAdapterPayment(paymentInfo, chain);\n }\n throw new X402Error(\n `Payment creation for ${chain.networkType} requires the appropriate provider`,\n 'CHAIN_NOT_SUPPORTED'\n );\n }\n } catch (error) {\n const x402Error = error instanceof X402Error\n ? error\n : new X402Error(\n error instanceof Error ? error.message : 'Unknown error',\n 'PAYMENT_FAILED',\n error\n );\n\n this.emit('paymentFailed', { error: x402Error.message, code: x402Error.code });\n throw x402Error;\n }\n }\n\n\n // ============================================================================\n // PUBLIC API - Buyer loop\n // ============================================================================\n\n /**\n * Fetch a resource, paying its `402 Payment Required` challenge if it has one.\n *\n * The BUYER side of x402, and the half this client was missing: it could sign\n * a payment ({@link createPayment}) but never ask for one, so every consumer\n * hand-rolled the same loop -- probe, read `accepts`, pick, sign, retry --\n * and each one picked its own answer to \"how much is too much\".\n *\n * Safe by default: `maxAmount` is a hard ceiling. A 402 that asks for more\n * throws `PAYMENT_EXCEEDS_MAX` instead of quietly signing it. A response that\n * is not a 402 -- a first-try 200 included -- comes back untouched; this pays\n * only when payment is what was asked for.\n *\n * @param url - Resource URL.\n * @param options - See {@link X402FetchOptions}.\n * @returns The paid response after a 402, or the original response.\n *\n * @example\n * ```ts\n * await client.connectWithPrivateKey(key, 'base');\n * const res = await client.fetch('https://api.example.com/data', {\n * maxAmount: '0.05',\n * });\n * const data = await res.json();\n * ```\n */\n async fetchWithReceipt(url: string, options: ReceiptFetchOptions): Promise<FetchReceiptResult> {\n return fetchWithReceipt((target, init) => this.fetch(target, init), url, options);\n }\n\n async fetch(url: string, options: X402FetchOptions = {}): Promise<Response> {\n if (!this.connectedAddress) {\n throw new X402Error('Wallet not connected', 'WALLET_NOT_CONNECTED');\n }\n\n const method = options.method || 'GET';\n const doFetch = options.fetchImpl || globalThis.fetch;\n if (typeof doFetch !== 'function') {\n throw new X402Error(\n 'No fetch implementation available; pass options.fetchImpl',\n 'NETWORK_ERROR'\n );\n }\n\n const probe = await doFetch(url, { ...options.init, method });\n if (probe.status !== 402) {\n return probe;\n }\n\n let body: unknown;\n try {\n body = await probe.json();\n } catch (error) {\n throw new X402Error(\n `402 response body is not JSON: ${error instanceof Error ? error.message : 'unknown'}`,\n 'PAYMENT_FAILED',\n error\n );\n }\n\n const tokenType: TokenType = options.tokenType || 'usdc';\n const challenge = this.parse402(body, tokenType);\n const { version, offers } = challenge;\n if (offers.length === 0) {\n // Step 1 of the policy contract, and two different facts that used to be\n // one error. A seller that sent offers none of which this build can read is\n // asking for a scheme we do not implement; saying so names what it wanted,\n // where \"no usable payment options\" sends the caller hunting a bug in its\n // own code. A seller that sent none at all is the other fact, and keeps the\n // error it always had.\n const unreadableCount = challenge.unreadableCount ?? challenge.unreadable.length;\n if (unreadableCount > 0) {\n throw new PolicyRefusedError(noReadableOffer(challenge.unreadable));\n }\n throw new X402Error(\n '402 response offered no usable payment options',\n 'NO_ACCEPTABLE_PAYMENT'\n );\n }\n\n // The ceiling is deliberately NOT applied while selecting: if even the\n // cheapest offer is over budget the caller wants to be told the price, not\n // handed a vague \"nothing acceptable\".\n const chosen = options.select\n ? options.select(offers)\n : X402Client.cheapestOffer(offers);\n if (!chosen) {\n throw new X402Error(\n 'No payment option selected for the 402 challenge',\n 'NO_ACCEPTABLE_PAYMENT'\n );\n }\n\n if (options.maxAmount !== undefined) {\n const ceiling = ethers.parseUnits(options.maxAmount, chosen.decimals);\n if (BigInt(chosen.amount) > ceiling) {\n throw new X402Error(\n `Payment of ${ethers.formatUnits(chosen.amount, chosen.decimals)} exceeds ` +\n `maxAmount ${options.maxAmount} for ${url}`,\n 'PAYMENT_EXCEEDS_MAX',\n {\n amount: chosen.amount,\n decimals: chosen.decimals,\n maxAmount: options.maxAmount,\n }\n );\n }\n }\n\n // The policy, evaluated against THIS offer, before anything is signed. An\n // offer that diverges from a listing but sits inside an authorised policy\n // proceeds -- stopping to ask would turn every ordinary reprice into a halt --\n // and one that does not is refused with a concrete cause. The policy is never\n // widened to fit the offer, and there is no confirmation hook in this path.\n //\n // The whole challenge goes in, never just the offer: `validUntil` lives in\n // the challenge's `extensions`, and a call that takes the parts is how it gets\n // dropped.\n const decision = decideOnChallenge(this.purchasePolicy, challenge, chosen, {\n now: Math.floor(Date.now() / 1000),\n quote: options.advertised,\n });\n if (!decision.ok) {\n this.log('policy refused this offer', { cause: decision.refusal.code });\n this.emit('paymentFailed', {\n error: decision.refusal.message,\n code: 'POLICY_REFUSED',\n });\n throw new PolicyRefusedError(decision.refusal);\n }\n const approval: PolicyApproval = decision.approval;\n this.log('policy approved this offer', {\n versusQuote: approval.versusQuote.code,\n amount: String(approval.amount),\n });\n\n if (!chosen.chainName) {\n throw new X402Error(\n `402 asked for payment on unknown network '${chosen.network}'`,\n 'CHAIN_NOT_SUPPORTED'\n );\n }\n\n // The policy just approved the offer's OWN asset, but `createPayment` signs\n // for whatever token `tokenType` resolves to on this chain -- and reads the\n // price at that token's decimals. With USDC on both sides they coincide,\n // which is why this never showed. They do not have to: a seller pricing in a\n // token that is not the configured one would get an approval for asset A and\n // a signature for asset B, at B's decimals, and the caller would believe a\n // budget it never actually enforced.\n //\n // Refused rather than silently re-pointed: which token to pay with is the\n // caller's decision, and guessing it from the seller's 402 is how a wallet\n // ends up signing for a token nobody chose.\n const configuredToken = getTokenConfig(chosen.chainName, tokenType);\n if (\n chosen.asset &&\n configuredToken &&\n canonicalRecipient(configuredToken.address) !== canonicalRecipient(chosen.asset)\n ) {\n throw new X402Error(\n `402 wants ${chosen.asset} on ${chosen.chainName}, but this client signs ` +\n `${configuredToken.address} (tokenType '${tokenType}'). Pass the tokenType ` +\n 'that matches the offer; signing the configured token would pay a ' +\n 'different asset than the one that was approved.',\n 'NO_ACCEPTABLE_PAYMENT',\n {\n offered: chosen.asset,\n wouldSign: configuredToken.address,\n tokenType,\n network: chosen.chainName,\n }\n );\n }\n\n if (chosen.chainName !== this.currentChainName) {\n await this.switchChain(chosen.chainName);\n }\n\n // The window: the seller's declared `maxTimeoutSeconds` when its 402 carried\n // one, clamped to the payer's ceiling; otherwise this client's own. The\n // facilitator never rejects a long window, so signing LESS than the seller\n // declared is the failure that bites -- an authorization that dies before the\n // seller's own settle and revokes a payment that was made.\n const payment = await this.createPayment({\n accepted: chosen.raw,\n resource: { url },\n extensions: challenge.extensions as Record<string, unknown> | undefined,\n recipient: chosen.payTo,\n amount: ethers.formatUnits(chosen.amount, chosen.decimals),\n tokenType,\n network: chosen.chainName,\n x402Version: version,\n validitySeconds:\n chosen.maxTimeoutSeconds !== undefined\n ? clampValiditySeconds(chosen.maxTimeoutSeconds)\n : undefined,\n });\n\n // v1 servers read `X-PAYMENT`; v2 ones read `PAYMENT-SIGNATURE`. Both carry\n // the identical base64 payload, so sending both on a v2 retry costs nothing\n // and spares the caller from guessing which name the resource implemented.\n const paidHeaders: Record<string, string> = {\n ...X402Client.headersToRecord(options.init?.headers),\n 'X-PAYMENT': payment.paymentHeader,\n };\n if (version === 2) {\n paidHeaders['PAYMENT-SIGNATURE'] = payment.paymentHeader;\n }\n\n const paid = await doFetch(url, { ...options.init, method, headers: paidHeaders });\n\n // Approving did not spend: signing can fail and a settlement can be refused,\n // and a cumulative limit that counted attempts would lock a caller out of\n // money it never spent. A retry that came back as anything but another 402 is\n // the seller accepting the payment, which is the moment a caller records it --\n // by its own hand, in `onPaid`, never automatically here.\n if (paid.status !== 402) {\n options.onPaid?.(approval);\n }\n return paid;\n }\n\n /**\n * Normalise a 402 body into its envelope version, its payment offers, the ones\n * it could not read, and the challenge's `extensions`.\n *\n * Reads both spec shapes -- `{x402Version, accepts: [...]}` and the non-spec\n * one where a lone requirement sits at the top level -- and both dialects of\n * the price field (`maxAmountRequired` in v1, `amount` in v2).\n *\n * **`accepts` is a list, so one unreadable entry does not sink the list.** A\n * seller offering `exact` alongside a scheme this build does not implement used\n * to be unpayable in the Rust crate, and the buyer never learned there was a\n * perfectly payable offer right there. The readable ones are kept and the\n * others are counted by scheme name, so a refusal can say what the seller\n * offered instead of \"could not parse\". Discovering the service keeps working\n * even when buying it automatically does not.\n *\n * Returns the WHOLE challenge on purpose: handing `offers` alone downstream is\n * what dropped the seller's `validUntil` on the floor in Rust for a full commit\n * with every unit test green.\n */\n private parse402(\n body: unknown,\n tokenType: TokenType\n ): ReadChallenge & { version: X402Version } {\n const doc = (body ?? {}) as Record<string, unknown>;\n const version: X402Version = Number(doc.x402Version) === 2 ? 2 : 1;\n\n const rawAccepts = Array.isArray(doc.accepts)\n ? doc.accepts\n : doc.payTo\n ? [doc]\n : [];\n\n const offers: X402PaymentOffer[] = [];\n const unreadable: string[] = [];\n let unreadableCount = 0;\n\n /** Count an entry this build cannot pay, by scheme name when it has one. */\n const cannotRead = (accept: Record<string, unknown> | null) => {\n unreadableCount += 1;\n const scheme = accept?.scheme;\n if (typeof scheme === 'string' && scheme) unreadable.push(scheme);\n };\n\n for (const entry of rawAccepts) {\n if (!entry || typeof entry !== 'object') {\n cannotRead(null);\n continue;\n }\n const accept = entry as Record<string, unknown>;\n\n // The scheme first, so a well-formed offer in a scheme we cannot pay is\n // counted by the NAME the seller used -- the informative half of rule 7 --\n // instead of being reported for whichever field it also happened to omit.\n //\n // An ABSENT scheme is unreadable, not `exact`. Rust requires the field, so a\n // challenge without it fails to deserialise there, and a buyer that guessed\n // `exact` would sign under a scheme the seller never actually named -- which\n // is the same hole as signing a named one we cannot present, minus the\n // evidence. It is counted (`unreadableCount`) without a name, because it has\n // none to report.\n //\n // Note this is deliberately ASYMMETRIC with the seller side of this SDK,\n // where a missing scheme reads as `exact` (\"the default, not an override\",\n // `src/backend/index.ts`). A seller is lenient about what it accepts; a\n // buyer is strict about what it signs.\n const declaredScheme = accept.scheme;\n if (\n typeof declaredScheme !== 'string' ||\n !declaredScheme ||\n !KNOWN_SCHEMES.has(declaredScheme) ||\n !CLIENT_PAYABLE_SCHEMES.has(declaredScheme)\n ) {\n cannotRead(accept);\n continue;\n }\n\n const amount = accept.amount ?? accept.maxAmountRequired;\n const payTo = accept.payTo;\n const network = accept.network;\n if (amount === undefined || amount === null) {\n cannotRead(accept);\n continue;\n }\n if (typeof payTo !== 'string' || !payTo) {\n cannotRead(accept);\n continue;\n }\n if (typeof network !== 'string' || !network) {\n cannotRead(accept);\n continue;\n }\n\n const chainName = getChainByName(network) ? network : caip2ToChain(network);\n\n // The seller's settlement window, when it declared a usable one. Anything\n // that is not a finite number counts as NOT declared instead of making the\n // offer unreadable: price, payee and network are intact, and the client's\n // own window still applies.\n const declaredTimeout =\n typeof accept.maxTimeoutSeconds === 'number' && Number.isFinite(accept.maxTimeoutSeconds)\n ? accept.maxTimeoutSeconds\n : undefined;\n\n offers.push({\n network,\n chainName,\n asset: typeof accept.asset === 'string' ? accept.asset : undefined,\n amount: String(amount),\n decimals: X402Client.offerDecimals(chainName, tokenType),\n payTo,\n ...(declaredTimeout !== undefined ? { maxTimeoutSeconds: declaredTimeout } : {}),\n raw: accept,\n });\n }\n\n const extensions =\n doc.extensions && typeof doc.extensions === 'object' && !Array.isArray(doc.extensions)\n ? (doc.extensions as Record<string, unknown>)\n : undefined;\n\n return { version, offers, unreadable, unreadableCount, extensions };\n }\n\n /**\n * Decimals to read an offer's atomic `amount` with.\n *\n * Not cosmetic: BSC USDC has 18 and everyone else's has 6, so reading every\n * price at 6 makes one chain look 10^12 times cheaper than it is and the\n * cheapest offer gets chosen wrong. Falls back to 6 only when the chain is\n * unknown -- and an unknown chain cannot be paid anyway.\n */\n private static offerDecimals(chainName: string | null, tokenType: TokenType): number {\n if (!chainName) return 6;\n const token = getTokenConfig(chainName, tokenType);\n if (token) return token.decimals;\n return getChainByName(chainName)?.usdc.decimals ?? 6;\n }\n\n /** Cheapest offer, compared across chains at a common scale. */\n private static cheapestOffer(offers: X402PaymentOffer[]): X402PaymentOffer {\n return offers.reduce((best, offer) =>\n X402Client.scaled(offer) < X402Client.scaled(best) ? offer : best\n );\n }\n\n /** An offer's price scaled to 18 decimals, so BigInt comparison is exact. */\n private static scaled(offer: X402PaymentOffer): bigint {\n const exponent = 18 - offer.decimals;\n const value = BigInt(offer.amount);\n return exponent >= 0\n ? value * 10n ** BigInt(exponent)\n : value / 10n ** BigInt(-exponent);\n }\n\n /** Flatten whatever `HeadersInit` shape the caller passed into a record. */\n private static headersToRecord(init?: HeadersInit): Record<string, string> {\n if (!init) return {};\n if (Array.isArray(init)) return Object.fromEntries(init);\n const maybeHeaders = init as Headers;\n if (typeof maybeHeaders.forEach === 'function') {\n const out: Record<string, string> = {};\n maybeHeaders.forEach((value, key) => {\n out[key] = value;\n });\n return out;\n }\n return { ...(init as Record<string, string>) };\n }\n\n /**\n * Check USDC balance on current chain\n */\n async getBalance(): Promise<string> {\n if (!this.connectedAddress || !this.currentChainName) {\n throw new X402Error('Wallet not connected', 'WALLET_NOT_CONNECTED');\n }\n\n const chain = getChainByName(this.currentChainName);\n if (!chain) {\n throw new X402Error(`Chain ${this.currentChainName} not found`, 'CHAIN_NOT_SUPPORTED');\n }\n\n switch (chain.networkType) {\n case 'evm':\n return this.getEVMBalance(chain);\n default:\n if (this.walletAdapter?.networkType === chain.networkType) {\n return this.walletAdapter.getBalance(chain);\n }\n throw new X402Error(\n `Balance check for ${chain.networkType} requires the appropriate provider`,\n 'CHAIN_NOT_SUPPORTED'\n );\n }\n }\n\n // ============================================================================\n // PUBLIC API - Getters\n // ============================================================================\n\n /**\n * Get current wallet state\n */\n getState(): WalletState {\n return {\n connected: this.connectedAddress !== null,\n address: this.connectedAddress,\n chainId: this.currentChainId,\n network: this.currentChainName,\n networkType: this.currentNetwork,\n balance: null, // Call getBalance() separately\n };\n }\n\n /**\n * Get connected wallet address\n */\n getAddress(): string | null {\n return this.connectedAddress;\n }\n\n /**\n * Get current chain ID\n */\n getChainId(): number | null {\n return this.currentChainId;\n }\n\n /**\n * Get current chain name\n */\n getChainName(): string | null {\n return this.currentChainName;\n }\n\n /**\n * Get current chain display name\n */\n getChainDisplayName(): string | null {\n if (!this.currentChainName) return null;\n const chain = getChainByName(this.currentChainName);\n return chain?.displayName ?? null;\n }\n\n /**\n * Check if wallet is connected\n */\n isConnected(): boolean {\n return this.connectedAddress !== null;\n }\n\n /**\n * Get list of enabled chains\n */\n getEnabledChains(): ChainConfig[] {\n return getEnabledChains();\n }\n\n /**\n * Get chain config by name\n */\n getChain(name: string): ChainConfig | undefined {\n return getChainByName(name);\n }\n\n // ============================================================================\n // PUBLIC API - Events\n // ============================================================================\n\n /**\n * Subscribe to an event\n */\n on<E extends X402Event>(event: E, handler: X402EventHandler<E>): () => void {\n if (!this.eventHandlers.has(event)) {\n this.eventHandlers.set(event, new Set());\n }\n this.eventHandlers.get(event)!.add(handler as X402EventHandler<X402Event>);\n\n // Return unsubscribe function\n return () => this.off(event, handler);\n }\n\n /**\n * Unsubscribe from an event\n */\n off<E extends X402Event>(event: E, handler: X402EventHandler<E>): void {\n this.eventHandlers.get(event)?.delete(handler as X402EventHandler<X402Event>);\n }\n\n // ============================================================================\n // PRIVATE - EVM Wallet Connection\n // ============================================================================\n\n /**\n * Connect an SVM chain (Solana, Fogo) through the Phantom-backed provider.\n *\n * The provider is imported lazily: `@solana/web3.js` and `@solana/spl-token`\n * are OPTIONAL peer dependencies, so an EVM-only consumer must never pay for\n * them at module load. They are resolved only once someone actually asks for\n * an SVM chain.\n */\n private async connectSVMWallet(chain: ChainConfig): Promise<string> {\n const { SVMProvider } = await import('../providers/solana');\n const adapter = new SVMProvider();\n\n // SVMProvider.connect() takes no chain: one Phantom session serves every\n // SVM chain, and the chain is passed per call via chainConfig.\n const address = await adapter.connect();\n\n this.walletAdapter = adapter;\n this.provider = null;\n this.signer = null;\n this.connectedAddress = address;\n this.currentChainId = chain.chainId;\n this.currentNetwork = chain.networkType;\n this.currentChainName = chain.name;\n\n const state = this.getState();\n this.emit('connect', state);\n this.log('SVM wallet connected', { address, chain: chain.name });\n\n return address;\n }\n\n private async connectEVMWallet(chain: ChainConfig): Promise<string> {\n // Check for injected provider\n if (typeof window === 'undefined' || !window.ethereum) {\n throw new X402Error(\n 'No Ethereum wallet found. Please install MetaMask or another EVM wallet.',\n 'WALLET_NOT_FOUND'\n );\n }\n\n try {\n this.provider = new ethers.BrowserProvider(window.ethereum);\n\n // Request account access\n await this.provider.send('eth_requestAccounts', []);\n\n // Switch to target chain\n await this.switchEVMChain(chain);\n\n // Get signer and address\n this.signer = await this.provider.getSigner();\n this.connectedAddress = await this.signer.getAddress();\n this.currentChainId = chain.chainId;\n this.currentNetwork = 'evm';\n this.currentChainName = chain.name;\n\n // Setup event listeners\n this.setupEVMEventListeners();\n\n const state = this.getState();\n this.emit('connect', state);\n this.log('EVM wallet connected', { address: this.connectedAddress, chain: chain.name });\n\n return this.connectedAddress;\n } catch (error: unknown) {\n if (error instanceof Error) {\n if (error.message.includes('User rejected') || (error as { code?: number }).code === 4001) {\n throw new X402Error('Connection rejected by user', 'WALLET_CONNECTION_REJECTED');\n }\n }\n throw new X402Error(\n `Failed to connect wallet: ${error instanceof Error ? error.message : 'Unknown error'}`,\n 'UNKNOWN_ERROR',\n error\n );\n }\n }\n\n private async switchEVMChain(chain: ChainConfig): Promise<void> {\n if (!this.provider) {\n throw new X402Error('Wallet not connected', 'WALLET_NOT_CONNECTED');\n }\n\n try {\n await this.provider.send('wallet_switchEthereumChain', [{ chainId: chain.chainIdHex }]);\n } catch (switchError: unknown) {\n // Chain not added - try to add it\n if ((switchError as { code?: number }).code === 4902) {\n try {\n await this.provider.send('wallet_addEthereumChain', [\n {\n chainId: chain.chainIdHex,\n chainName: chain.displayName,\n nativeCurrency: chain.nativeCurrency,\n rpcUrls: [chain.rpcUrl],\n blockExplorerUrls: [chain.explorerUrl],\n },\n ]);\n } catch (addError) {\n throw new X402Error(\n `Failed to add ${chain.displayName} network`,\n 'CHAIN_SWITCH_REJECTED',\n addError\n );\n }\n } else if ((switchError as { code?: number }).code === 4001) {\n throw new X402Error('Network switch rejected by user', 'CHAIN_SWITCH_REJECTED');\n } else {\n throw new X402Error(\n `Failed to switch to ${chain.displayName}`,\n 'CHAIN_SWITCH_REJECTED',\n switchError\n );\n }\n }\n\n this.currentChainId = chain.chainId;\n this.currentChainName = chain.name;\n this.emit('chainChanged', { chainId: chain.chainId, chainName: chain.name });\n }\n\n private setupEVMEventListeners(): void {\n if (typeof window === 'undefined' || !window.ethereum) return;\n\n window.ethereum.on?.('accountsChanged', ((...args: unknown[]) => {\n const accounts = args[0] as string[];\n if (accounts.length === 0) {\n this.disconnect();\n } else if (accounts[0] !== this.connectedAddress) {\n this.connectedAddress = accounts[0];\n this.emit('accountChanged', { address: accounts[0] });\n }\n }) as (...args: unknown[]) => void);\n\n window.ethereum.on?.('chainChanged', ((...args: unknown[]) => {\n const chainIdHex = args[0] as string;\n const chainId = parseInt(chainIdHex, 16);\n const chain = getChainById(chainId);\n if (chain) {\n this.currentChainId = chainId;\n this.currentChainName = chain.name;\n this.emit('chainChanged', { chainId, chainName: chain.name });\n }\n }) as (...args: unknown[]) => void);\n }\n\n // ============================================================================\n // PRIVATE - EVM Payment Creation\n // ============================================================================\n\n private async createEVMPayment(paymentInfo: PaymentInfo, chain: ChainConfig): Promise<PaymentResult> {\n if (!this.signer) {\n throw new X402Error('Wallet not connected', 'WALLET_NOT_CONNECTED');\n }\n\n // Get recipient address for EVM\n const recipient = this.getRecipientForNetwork(paymentInfo, 'evm');\n\n // Validate recipient address - prevents empty/invalid addresses\n validateRecipient(recipient, 'evm');\n\n // Which stablecoin to charge. Defaults to USDC so existing callers are\n // unaffected; anything else is resolved from the chain's token registry.\n const tokenType: TokenType = paymentInfo.tokenType || 'usdc';\n const token = getTokenConfig(chain.name, tokenType);\n if (!token) {\n throw new X402Error(\n `Token ${tokenType} not supported on ${chain.name}`,\n 'CHAIN_NOT_SUPPORTED'\n );\n }\n\n // Generate random nonce\n const nonceBytes = new Uint8Array(32);\n if (typeof window !== 'undefined' && window.crypto) {\n window.crypto.getRandomValues(nonceBytes);\n } else {\n for (let i = 0; i < 32; i++) {\n nonceBytes[i] = Math.floor(Math.random() * 256);\n }\n }\n const nonce = ethers.hexlify(nonceBytes);\n\n // How long this authorization stays settleable. Per payment first, then the\n // client's default, then 300 s -- see `resolveValiditySeconds`.\n const validAfter = 0;\n const validityWindowSeconds = resolveValiditySeconds(\n paymentInfo.validitySeconds,\n this.config.validitySeconds\n );\n const validBefore = Math.floor(Date.now() / 1000) + validityWindowSeconds;\n\n // EIP-712 domain of the token being charged\n const domain = {\n name: token.name,\n version: token.version,\n chainId: chain.chainId,\n verifyingContract: token.address,\n };\n\n // EIP-712 types for TransferWithAuthorization (ERC-3009)\n const types = {\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 };\n\n // Parse amount in the token's own decimals\n const value = ethers.parseUnits(paymentInfo.amount, token.decimals);\n const from = await this.signer.getAddress();\n const to = ethers.getAddress(recipient);\n\n // Message to sign\n const message = {\n from,\n to,\n value,\n validAfter,\n validBefore,\n nonce,\n };\n\n this.log('Signing EIP-712 message...', { domain, message });\n\n // Sign the EIP-712 message\n let signature: string;\n try {\n signature = await this.signer.signTypedData(domain, types, message);\n } catch (error: unknown) {\n if (error instanceof Error && (error.message.includes('User rejected') || (error as { code?: number }).code === 4001)) {\n throw new X402Error('Signature rejected by user', 'SIGNATURE_REJECTED');\n }\n throw new X402Error(\n `Failed to sign payment: ${error instanceof Error ? error.message : 'Unknown error'}`,\n 'PAYMENT_FAILED',\n error\n );\n }\n\n const sig = ethers.Signature.from(signature);\n\n // Construct payload\n const payload: EVMPaymentPayload = {\n from,\n to,\n value: value.toString(),\n validAfter,\n validBefore,\n nonce,\n v: sig.v,\n r: sig.r,\n s: sig.s,\n chainId: chain.chainId,\n token: token.address,\n };\n\n // Encode as X-PAYMENT header. The 402 wins over the config when it spoke:\n // `x402Version: 'auto'` means \"whatever the resource asked for\".\n const paymentHeader = this.encodeEVMPaymentHeader(\n payload,\n chain,\n paymentInfo.x402Version\n );\n\n this.emit('paymentSigned', { paymentHeader });\n\n const result: PaymentResult = {\n success: true,\n paymentHeader,\n headers: {\n 'X-PAYMENT': paymentHeader,\n 'PAYMENT-SIGNATURE': paymentHeader,\n },\n network: chain.name,\n payer: from,\n };\n\n this.emit('paymentCompleted', result);\n this.log('Payment created successfully', { network: chain.name, from });\n\n return result;\n }\n\n /**\n * Build a payment through a non-EVM {@link WalletAdapter}.\n *\n * The adapter signs and returns its own payload; encoding that payload into\n * the X-PAYMENT header is network-specific, so it stays with the provider\n * that produced it. Version resolution matches the EVM path exactly: a hint\n * read off the resource's own 402 wins over the client config.\n */\n private async createAdapterPayment(\n paymentInfo: PaymentInfo,\n chain: ChainConfig\n ): Promise<PaymentResult> {\n const adapter = this.walletAdapter;\n if (!adapter) {\n throw new X402Error('Wallet not connected', 'WALLET_NOT_CONNECTED');\n }\n\n const encode = (adapter as { encodePaymentHeader?: (p: string, c: ChainConfig, v: X402Version) => string })\n .encodePaymentHeader;\n if (typeof encode !== 'function') {\n throw new X402Error(\n `The ${adapter.name} adapter cannot encode an X-PAYMENT header`,\n 'CHAIN_NOT_SUPPORTED'\n );\n }\n\n const version = paymentInfo.x402Version ?? (chain.networkType === 'hedera' ? 2 : this.config.x402Version === 2 ? 2 : 1);\n const signed = await adapter.signPayment({ ...paymentInfo, x402Version: version }, chain);\n const paymentHeader = encode.call(adapter, signed, chain, version);\n\n this.emit('paymentSigned', { paymentHeader });\n\n const result: PaymentResult = {\n success: true,\n paymentHeader,\n headers: {\n 'X-PAYMENT': paymentHeader,\n 'PAYMENT-SIGNATURE': paymentHeader,\n },\n network: chain.name,\n payer: adapter.getAddress() ?? undefined,\n };\n\n this.emit('paymentCompleted', result);\n this.log('Payment created successfully', { network: chain.name, adapter: adapter.name });\n\n return result;\n }\n\n private encodeEVMPaymentHeader(\n payload: EVMPaymentPayload,\n chain: ChainConfig,\n versionHint?: X402Version\n ): string {\n // Reconstruct full signature from v, r, s\n const fullSignature = payload.r + payload.s.slice(2) + payload.v.toString(16).padStart(2, '0');\n\n // Determine version to use. A hint read off the resource's own 402 wins;\n // with no hint we fall back to the config (default v1 for compatibility).\n const version = versionHint ?? (this.config.x402Version === 2 ? 2 : 1);\n\n // Build the payload data\n const payloadData: X402EVMPayload = {\n signature: fullSignature,\n authorization: {\n from: payload.from,\n to: payload.to,\n value: payload.value,\n validAfter: payload.validAfter.toString(),\n validBefore: payload.validBefore.toString(),\n nonce: payload.nonce,\n },\n };\n\n if (this.config.includeTokenMetadata) {\n const token = buildTokenMetadata(chain.name, payload.token);\n if (!token) {\n throw new X402Error(\n `Token ${payload.token} is not in the registry for ${chain.name}; cannot build token metadata`,\n 'CHAIN_NOT_SUPPORTED'\n );\n }\n payloadData.token = token;\n }\n\n // Format in x402 standard format (v1 or v2)\n const x402Payload = version === 2\n ? {\n x402Version: 2 as const,\n scheme: 'exact' as const,\n network: chainToCAIP2(chain.name), // CAIP-2 format for v2\n payload: payloadData,\n }\n : {\n x402Version: 1 as const,\n scheme: 'exact' as const,\n network: chain.name, // Plain chain name for v1\n payload: payloadData,\n };\n\n // Base64 encode (UTF-8 safe: token domain names like `USD₮0` are not ASCII)\n return encodeBase64Json(x402Payload);\n }\n\n // ============================================================================\n // PRIVATE - EVM Balance Check\n // ============================================================================\n\n private async getEVMBalance(chain: ChainConfig): Promise<string> {\n // Use public RPC for balance check (more reliable than wallet provider)\n const publicProvider = new ethers.JsonRpcProvider(chain.rpcUrl);\n\n const usdcAbi = ['function balanceOf(address owner) view returns (uint256)'];\n const usdcContract = new ethers.Contract(chain.usdc.address, usdcAbi, publicProvider);\n\n try {\n const balance = await usdcContract.balanceOf(this.connectedAddress);\n const formatted = ethers.formatUnits(balance, chain.usdc.decimals);\n return parseFloat(formatted).toFixed(2);\n } catch {\n return '0.00';\n }\n }\n\n // ============================================================================\n // PRIVATE - Utilities\n // ============================================================================\n\n private getRecipientForNetwork(paymentInfo: PaymentInfo, network: NetworkType): string {\n // Map SVM to solana for recipient lookup\n const lookupNetwork = network === 'svm' ? 'solana' : network;\n const recipients = paymentInfo.recipients as Record<string, string> | undefined;\n if (recipients?.[lookupNetwork]) {\n return recipients[lookupNetwork];\n }\n return paymentInfo.recipient;\n }\n\n private emit<E extends X402Event>(event: E, data: X402EventData[E]): void {\n this.eventHandlers.get(event)?.forEach(handler => {\n try {\n handler(data);\n } catch (error) {\n console.error(`Error in ${event} handler:`, error);\n }\n });\n }\n\n private log(message: string, data?: unknown): void {\n if (this.config.debug) {\n console.log(`[X402Client] ${message}`, data ?? '');\n }\n }\n}\n\n// Type augmentation for window.ethereum\ndeclare global {\n interface Window {\n ethereum?: {\n request: (args: { method: string; params?: unknown[] }) => Promise<unknown>;\n on?: (event: string, handler: (...args: unknown[]) => void) => void;\n removeListener?: (event: string, handler: (...args: unknown[]) => void) => void;\n };\n }\n}\n","/**\n * uvd-x402-sdk - What this buyer is allowed to sign, decided before it signs.\n *\n * # The rule this module exists to enforce\n *\n * A catalog listing is a claim somebody else made about their own price. The\n * `402` that comes back from the actual request is the offer. They can differ,\n * legitimately: a seller may have repriced, and the listing may be a copy of a\n * copy. So the buying decision cannot be made against the listing. It has to be\n * made against **the offer in hand**, every time, before anything is signed.\n *\n * Two things follow, and both are load-bearing:\n *\n * - **A divergence from the listing is not, by itself, a refusal.** If the offer\n * costs more than the catalog said but still sits inside a policy the operator\n * already authorised, the payment proceeds. Stopping to ask would turn every\n * ordinary reprice into a halt, and an agent that halts on ordinary commerce\n * is an agent nobody can leave running. There is no human-confirmation hook in\n * this path.\n * - **A policy is never widened to fit an offer.** Not by a byte, not once, not\n * \"because the seller says so\". There is deliberately no method on this type\n * that raises a limit from inside an evaluation. If the offer exceeds what was\n * authorised the answer is a refusal with a concrete cause, and the caller\n * decides whether to authorise more.\n *\n * # Order of evaluation\n *\n * Fixed, and part of the contract, because the FIRST failing check is the one\n * reported and a caller branches on it:\n *\n * 1. Was any offer readable at all? -> `no-readable-offer`\n * 2. Has it expired? -> `offer-expired`\n * 3. Is the recipient one we are willing to pay? -> `recipient-not-permitted`\n * 4. Was its asset budgeted at all? -> `asset-not-budgeted`\n * 5. Does it exceed the per-payment limit for that asset? -> `per-payment-limit`\n * 6. Does it exceed what remains of the cumulative limit? -> `cumulative-limit`\n *\n * The comparison against the listing is made LAST and refuses nothing: it is\n * evidence for the caller, never a gate.\n *\n * This is the same contract the Rust facilitator's `x402-reqwest` crate\n * implements (`PurchasePolicy`, release 2.25.0), written down once so a buyer in\n * either language refuses the same payments for the same stated reasons.\n *\n * @module\n */\n\nimport { X402Error } from './types';\nimport type { X402PaymentOffer } from './types';\n\n// ============================================================================\n// The offer-validity extension\n// ============================================================================\n\n/**\n * Extension key under which a seller declares how long its offer stands.\n *\n * Defined once, here, and read by nobody else's constant: a seller and a buyer\n * naming different keys have nothing to say to each other. The version is IN\n * the key because the offer-and-receipt transport can still change, and a value\n * read from an unversioned key could never be compared with anything later. A\n * key we do not recognise is ignored, which means \"no declared expiry\" -- a\n * different thing from \"expired\".\n */\nexport const OFFER_VALIDITY_EXTENSION = 'offer-receipt/1';\n\n/**\n * Read `validUntil` (Unix seconds) out of a 402 challenge's `extensions`.\n *\n * Shape: `extensions[\"offer-receipt/1\"].info.validUntil`. The `{info, schema}`\n * envelope is the one every merged x402 extension uses; reading the number from\n * anywhere else would be reading a field nobody agreed to publish.\n *\n * Anything unreadable is `undefined`, **never zero**: \"the seller said\n * something we could not read\" must not become \"this offer expired in 1970\".\n * A string, a float, a negative, a number past `Number.MAX_SAFE_INTEGER` -- all\n * unreadable, all absent.\n */\nexport function offerValidUntil(\n extensions: Record<string, unknown> | undefined | null\n): number | undefined {\n if (!extensions || typeof extensions !== 'object') return undefined;\n const entry = (extensions as Record<string, unknown>)[OFFER_VALIDITY_EXTENSION];\n if (!entry || typeof entry !== 'object') return undefined;\n const info = (entry as Record<string, unknown>).info;\n if (!info || typeof info !== 'object') return undefined;\n const value = (info as Record<string, unknown>).validUntil;\n if (typeof value !== 'number') return undefined;\n if (!Number.isSafeInteger(value) || value < 0) return undefined;\n return value;\n}\n\n// ============================================================================\n// Addresses\n// ============================================================================\n\n/**\n * Canonical form of a recipient or token address, for comparison.\n *\n * # Why this is not `toLowerCase()`\n *\n * It was, in the Rust crate, and that is only correct for one family. EVM\n * addresses are hex and arrive both checksummed and lowercase, so folding case\n * is right and necessary. **Base58 is case-sensitive** -- Solana and XRPL\n * addresses use both cases as distinct symbols -- so lowercasing one does not\n * produce the same address spelled differently, it produces a string that is not\n * an address.\n *\n * An allowlist written in the seller's own spelling would then never match, and\n * every payment to a legitimate Solana payee would be refused with\n * `recipient-not-permitted`. Worse in the other direction: two distinct base58\n * addresses can fold to the same lowercase string, so an allowlist could admit\n * an address nobody put on it.\n *\n * So: hex is folded, everything else is compared exactly.\n */\nexport function canonicalRecipient(address: string): string {\n const trimmed = address.trim();\n const rest =\n trimmed.startsWith('0x') || trimmed.startsWith('0X') ? trimmed.slice(2) : null;\n const isHex = rest !== null && rest.length > 0 && /^[0-9a-fA-F]+$/.test(rest);\n return isHex ? trimmed.toLowerCase() : trimmed;\n}\n\n// ============================================================================\n// Assets\n// ============================================================================\n\n/**\n * A token on a network -- the unit a budget is denominated in.\n *\n * Both halves are required. The same USDC contract address on two networks is\n * two different assets, and a budget for one is not a budget for the other: the\n * EVM signer takes its EIP-712 domain from the seller's own `extra`, so it will\n * sign for whatever token and network the seller names.\n */\nexport interface PolicyAsset {\n /**\n * SDK chain name (`'base'`) when the 402's network resolved to one, otherwise\n * the network string exactly as the 402 wrote it.\n *\n * Resolving first is what lets one written policy cover both 402 dialects:\n * a v1 challenge says `base` and a v2 one says `eip155:8453`, and a budget\n * keyed on the raw string would silently miss half of a seller's offers.\n */\n network: string;\n /** Token contract address. Compared canonicalised, never raw. */\n address: string;\n}\n\n/**\n * Stable map key for an asset. Not part of the wire format; comparison only.\n *\n * The network is folded to lowercase because SDK chain names and CAIP-2 strings\n * are lowercase by convention, so `'Base'` and `'base'` are the same network\n * written two ways -- never two networks. Leaving the case in fails closed\n * (`asset-not-budgeted`, so no wrong payment), but it trips the operator over a\n * capital letter and the refusal would point at the budget instead of the typo.\n * The address keeps its by-family treatment: see {@link canonicalRecipient}.\n */\nexport function assetKey(asset: PolicyAsset): string {\n return `${asset.network.trim().toLowerCase()}|${canonicalRecipient(asset.address)}`;\n}\n\n/** Human form, for a refusal message. */\nfunction assetLabel(asset: PolicyAsset): string {\n return asset.address ? `${asset.address} on ${asset.network}` : `(no asset declared) on ${asset.network}`;\n}\n\n/**\n * The asset an offer is priced in.\n *\n * An offer that declares no `asset` yields an empty address, which no budget can\n * ever hold -- {@link PurchasePolicy.perPayment} rejects an empty address -- so\n * such an offer is refused with `asset-not-budgeted` unless unlisted assets were\n * explicitly permitted. That is the safe direction: an unnamed token is a token\n * nobody budgeted for.\n */\nexport function offerAsset(offer: X402PaymentOffer): PolicyAsset {\n return {\n network: offer.chainName ?? offer.network,\n address: typeof offer.asset === 'string' ? offer.asset : '',\n };\n}\n\n// ============================================================================\n// Refusals\n// ============================================================================\n\n/**\n * Closed vocabulary of reasons a payment was not signed, in kebab-case, so an\n * SDK in another language branches on it without parsing English.\n *\n * There is no `other`: a refusal a caller cannot interpret is a refusal it will\n * paper over.\n */\nexport type PolicyRefusalCode =\n | 'no-readable-offer'\n | 'offer-expired'\n | 'recipient-not-permitted'\n | 'asset-not-budgeted'\n | 'per-payment-limit'\n | 'cumulative-limit';\n\n/**\n * Why a payment was not signed. Every variant carries the numbers that caused\n * it, so a caller can log the decision without re-deriving it.\n */\nexport type PolicyRefusal =\n | {\n code: 'no-readable-offer';\n /** Scheme names the seller offered, for the ones this build cannot read. */\n offered: string[];\n message: string;\n }\n | { code: 'offer-expired'; validUntil: number; now: number; message: string }\n | { code: 'recipient-not-permitted'; payTo: string; message: string }\n | { code: 'asset-not-budgeted'; asset: PolicyAsset; message: string }\n | {\n code: 'per-payment-limit';\n requested: bigint;\n allowed: bigint;\n asset: PolicyAsset;\n message: string;\n }\n | {\n code: 'cumulative-limit';\n requested: bigint;\n spent: bigint;\n wouldTotal: bigint;\n allowed: bigint;\n asset: PolicyAsset;\n message: string;\n };\n\n/**\n * A 402 whose offers this build could not read, turned into a refusal that says\n * so.\n *\n * The point is the message. A caller that learns the seller offered\n * `batch-settlement` knows to look for a facilitator that implements it, where\n * \"could not parse the response\" would have sent it looking for a bug in its own\n * code. Discovering the service keeps working even though buying it\n * automatically does not.\n */\nexport function noReadableOffer(offered: string[]): PolicyRefusal {\n return {\n code: 'no-readable-offer',\n offered,\n message:\n 'no offer in this challenge is one this build can pay; offered: ' +\n JSON.stringify(offered),\n };\n}\n\n/**\n * Error thrown on the real payment path when the policy refuses.\n *\n * Extends {@link X402Error}, so a consumer already catching `X402Error` keeps\n * catching this; the typed cause is on {@link PolicyRefusedError.refusal} and\n * its stable code on `refusal.code`.\n */\nexport class PolicyRefusedError extends X402Error {\n public readonly refusal: PolicyRefusal;\n\n constructor(refusal: PolicyRefusal) {\n super(`payment refused by policy: ${refusal.message}`, 'POLICY_REFUSED', refusal);\n this.name = 'PolicyRefusedError';\n this.refusal = refusal;\n }\n\n /** Stable kebab code of the refusal, for branching. */\n get policyCode(): PolicyRefusalCode {\n return this.refusal.code;\n }\n}\n\n// ============================================================================\n// The listing, and how the offer compares to it\n// ============================================================================\n\n/**\n * What a catalog listing advertised, for comparison against the real offer.\n *\n * Optional throughout. A buyer that never read a listing simply evaluates the\n * offer against its policy, which is the same decision with one fewer input.\n */\nexport interface AdvertisedQuote {\n asset: PolicyAsset;\n /** Price in the token's own atomic units. */\n amount: bigint;\n}\n\n/** How the offer in hand compares to what the catalog advertised. */\nexport type QuoteComparison =\n | { code: 'not-compared' }\n | { code: 'matches' }\n | { code: 'amount-differs'; advertised: bigint; offered: bigint }\n /**\n * A different asset entirely. The same number in another currency is not the\n * same price, so there is nothing to compare -- and no number is compared.\n */\n | { code: 'different-asset'; advertised: PolicyAsset; offered: PolicyAsset };\n\n/** A payment this policy permits, and what it noticed on the way. */\nexport interface PolicyApproval {\n asset: PolicyAsset;\n /** Price in the token's own atomic units. */\n amount: bigint;\n /**\n * How the offer compared to the listing, when there was one. Carried so a\n * caller can log or surface it; it never changed the decision.\n */\n versusQuote: QuoteComparison;\n}\n\n/** The outcome of an evaluation. Explicit, so no caller needs a `try`. */\nexport type PolicyDecision =\n | { ok: true; approval: PolicyApproval }\n | { ok: false; refusal: PolicyRefusal };\n\n/** Inputs to {@link PurchasePolicy.evaluate} besides the offer itself. */\nexport interface EvaluateOptions {\n /**\n * Unix seconds. Passed rather than read so the decision is testable at an\n * exact instant: money decisions that depend on a hidden clock cannot be\n * pinned.\n */\n now: number;\n /** `validUntil` the seller declared, if any. See {@link offerValidUntil}. */\n validUntil?: number;\n /** What the catalog advertised, if the caller read a listing. */\n quote?: AdvertisedQuote;\n}\n\n// ============================================================================\n// The policy\n// ============================================================================\n\n/**\n * The spending rules a caller authorised in advance.\n *\n * Every builder returns a new policy that **shares the running total**: two\n * copies of one policy spend from the same purse, which is what makes a\n * cumulative limit mean anything when a client is copied per request.\n *\n * @example\n * ```ts\n * const USDC_BASE = { network: 'base', address: '0x8335...2913' };\n * const policy = PurchasePolicy.create()\n * .perPayment(USDC_BASE, 50_000n) // 0.05 USDC, atomic units\n * .cumulative(USDC_BASE, 1_000_000n) // 1 USDC total, for this policy's life\n * .onlyPay(['0xe4dc...e545']);\n *\n * const client = new X402Client({ defaultChain: 'base', policy });\n * ```\n */\nexport class PurchasePolicy {\n private readonly perPaymentLimits: Map<string, bigint>;\n private readonly cumulativeLimits: Map<string, bigint>;\n /** Shared by reference across every copy: one purse, many holders. */\n private readonly spentTotals: Map<string, bigint>;\n private readonly recipients: Set<string> | null;\n private readonly assetsByKey: Map<string, PolicyAsset>;\n private readonly unlistedAssetsAllowed: boolean;\n\n private constructor(\n perPaymentLimits: Map<string, bigint>,\n cumulativeLimits: Map<string, bigint>,\n spentTotals: Map<string, bigint>,\n recipients: Set<string> | null,\n assetsByKey: Map<string, PolicyAsset>,\n unlistedAssetsAllowed: boolean\n ) {\n this.perPaymentLimits = perPaymentLimits;\n this.cumulativeLimits = cumulativeLimits;\n this.spentTotals = spentTotals;\n this.recipients = recipients;\n this.assetsByKey = assetsByKey;\n this.unlistedAssetsAllowed = unlistedAssetsAllowed;\n }\n\n /**\n * A policy that pays nothing until it is told what it may pay.\n *\n * # Why the default is deny\n *\n * The limits are a map keyed by asset, and a map answers \"no entry\" for every\n * asset nobody thought of. Permitting on a missing entry means a budget in\n * USDC is **no budget at all** for any other token: a seller offering the same\n * resource priced in something unlisted walks straight past the ceiling, and\n * the wallet will sign it, because the EVM signer takes the EIP-712 domain\n * from the seller's own `extra` and will happily sign for a token and a\n * network it has never heard of.\n *\n * So an asset with no stated ceiling is refused. A caller that genuinely wants\n * to pay anything says so once, by name, with\n * {@link PurchasePolicy.allowUnlistedAssets}, and that sentence is then in\n * their code where a reader can find it.\n */\n static create(): PurchasePolicy {\n return new PurchasePolicy(new Map(), new Map(), new Map(), null, new Map(), false);\n }\n\n /**\n * A policy that permits an asset it was never told about.\n *\n * This is what {@link X402Client} holds when the caller supplied no policy,\n * and it exists for exactly one reason: this SDK had no budget before 2.89.0,\n * and turning one on silently would refuse payments that callers are making\n * today. Named rather than defaulted, so choosing it is visible. The asymmetry\n * is deliberate -- whoever sits down to WRITE a policy deserves the safe\n * default.\n */\n static permissive(): PurchasePolicy {\n return new PurchasePolicy(new Map(), new Map(), new Map(), null, new Map(), true);\n }\n\n /** Permit assets with no configured ceiling. */\n allowUnlistedAssets(): PurchasePolicy {\n return this.with({ unlistedAssetsAllowed: true });\n }\n\n /**\n * Refuse assets with no configured ceiling. The default; here so the intent\n * can be written down at a call site that wants it explicit.\n */\n denyUnlistedAssets(): PurchasePolicy {\n return this.with({ unlistedAssetsAllowed: false });\n }\n\n /** Most this policy will pay in ONE payment of `asset`, in atomic units. */\n perPayment(asset: PolicyAsset, amount: bigint): PurchasePolicy {\n const key = this.register(asset);\n const perPaymentLimits = new Map(this.perPaymentLimits);\n perPaymentLimits.set(key, requireCeiling(amount, 'perPayment'));\n return this.with({ perPaymentLimits });\n }\n\n /**\n * Most this policy will pay in `asset` in TOTAL, across every payment it\n * approves for as long as it lives.\n */\n cumulative(asset: PolicyAsset, amount: bigint): PurchasePolicy {\n const key = this.register(asset);\n const cumulativeLimits = new Map(this.cumulativeLimits);\n cumulativeLimits.set(key, requireCeiling(amount, 'cumulative'));\n return this.with({ cumulativeLimits });\n }\n\n /**\n * Restrict payment to a set of recipients.\n *\n * Addresses are canonicalised **by family**, not by lowercasing the string:\n * see {@link canonicalRecipient}.\n */\n onlyPay(recipients: Iterable<string>): PurchasePolicy {\n const set = new Set<string>();\n for (const r of recipients) set.add(canonicalRecipient(r));\n return this.with({ recipients: set });\n }\n\n /**\n * Total recorded so far for `asset`, in atomic units.\n *\n * A total that is not a sane bigint means something corrupted the purse.\n * Reporting zero would silently restore the caller's whole budget, so this\n * reports the CEILING instead: for money, the safe direction is to refuse,\n * never to permit.\n */\n spent(asset: PolicyAsset): bigint {\n const key = assetKey(asset);\n const value = this.spentTotals.get(key);\n if (value === undefined) return 0n;\n if (typeof value !== 'bigint' || value < 0n) {\n return this.cumulativeLimits.get(key) ?? 0n;\n }\n return value;\n }\n\n /**\n * Record that a payment actually happened.\n *\n * Separate from {@link PurchasePolicy.evaluate} on purpose. Signing can still\n * fail and a settlement can still be refused; a cumulative limit that counted\n * attempts rather than payments would lock a caller out of money it never\n * spent. Call this when a payment settled.\n *\n * A negative amount is ignored: handing budget back is not something a\n * settlement can do, and treating it as one would be a way to widen a policy\n * from outside.\n */\n recordSpend(asset: PolicyAsset, amount: bigint): void {\n if (typeof amount !== 'bigint' || amount <= 0n) return;\n const key = assetKey(asset);\n if (!this.assetsByKey.has(key)) this.assetsByKey.set(key, asset);\n const current = this.spent(asset);\n this.spentTotals.set(key, current + amount);\n }\n\n /**\n * Whether this policy pays an asset it holds no ceiling for. Read-only: there\n * is no setter that flips it from inside an evaluation.\n */\n get permitsUnlistedAssets(): boolean {\n return this.unlistedAssetsAllowed;\n }\n\n /**\n * Decide whether this offer may be signed. Steps 2 through 6 of the contract;\n * step 1 (`no-readable-offer`) is decided on the challenge, before an offer\n * exists to evaluate -- see {@link decideOnChallenge}.\n *\n * **Approving does not record the spend.** See\n * {@link PurchasePolicy.recordSpend}.\n */\n evaluate(offer: X402PaymentOffer, options: EvaluateOptions): PolicyDecision {\n const { now, validUntil, quote } = options;\n\n // 2. Expiry. Before anything about money: terms that have lapsed are not\n // terms, whatever they say. `validUntil === now` still stands -- it is the\n // last instant the offer is up.\n if (validUntil !== undefined && now > validUntil) {\n return {\n ok: false,\n refusal: {\n code: 'offer-expired',\n validUntil,\n now,\n message:\n `this offer expired at ${validUntil} (now ${now}); ` +\n 'ask the seller for new terms',\n },\n };\n }\n\n // 3. Recipient.\n if (this.recipients !== null) {\n const payTo = canonicalRecipient(offer.payTo);\n if (!this.recipients.has(payTo)) {\n return {\n ok: false,\n refusal: {\n code: 'recipient-not-permitted',\n payTo: offer.payTo,\n message: `this policy does not pay ${offer.payTo}`,\n },\n };\n }\n }\n\n const asset = offerAsset(offer);\n const key = assetKey(asset);\n const requested = readAmount(offer.amount);\n\n // 4. An asset nobody budgeted for. Checked BEFORE the ceilings, because the\n // ceilings are a map and a map has no opinion about a key it does not\n // hold -- which is precisely how an unlisted token would sail past a\n // budget that looks complete. And the caller has to be told \"budget that\n // asset\", not \"raise a ceiling that does not exist\".\n if (\n !this.unlistedAssetsAllowed &&\n !this.perPaymentLimits.has(key) &&\n !this.cumulativeLimits.has(key)\n ) {\n return {\n ok: false,\n refusal: {\n code: 'asset-not-budgeted',\n asset,\n message:\n `this policy has no budget for ${assetLabel(asset)}; ` +\n 'it pays only what it was told it may pay',\n },\n };\n }\n\n // 5. Per-payment ceiling.\n const perPaymentAllowed = this.perPaymentLimits.get(key);\n if (perPaymentAllowed !== undefined && requested > perPaymentAllowed) {\n return {\n ok: false,\n refusal: {\n code: 'per-payment-limit',\n requested,\n allowed: perPaymentAllowed,\n asset,\n message:\n `offer of ${requested} exceeds the per-payment limit of ` +\n `${perPaymentAllowed} for ${assetLabel(asset)}`,\n },\n };\n }\n\n // 6. Cumulative ceiling.\n const cumulativeAllowed = this.cumulativeLimits.get(key);\n if (cumulativeAllowed !== undefined) {\n const spent = this.spent(asset);\n const wouldTotal = spent + requested;\n if (wouldTotal > cumulativeAllowed) {\n return {\n ok: false,\n refusal: {\n code: 'cumulative-limit',\n requested,\n spent,\n wouldTotal,\n allowed: cumulativeAllowed,\n asset,\n message:\n `offer of ${requested} would take spend to ${wouldTotal}, past the ` +\n `cumulative limit of ${cumulativeAllowed} for ${assetLabel(asset)} ` +\n `(already spent ${spent})`,\n },\n };\n }\n }\n\n // The comparison against the listing is made LAST and refuses nothing. It is\n // evidence for the caller, not a gate: a seller repricing inside a policy the\n // operator already authorised is ordinary commerce.\n return {\n ok: true,\n approval: { asset, amount: requested, versusQuote: compareToQuote(asset, requested, quote) },\n };\n }\n\n /** Copy sharing the same purse. Cloning is what a per-request client does. */\n clone(): PurchasePolicy {\n return this.with({});\n }\n\n /**\n * Rebuild with some fields replaced, **always sharing `spentTotals`**. This is\n * the one place that decides copies share a purse, so it is the one place to\n * read when asking whether they do.\n */\n private with(changes: {\n perPaymentLimits?: Map<string, bigint>;\n cumulativeLimits?: Map<string, bigint>;\n recipients?: Set<string> | null;\n unlistedAssetsAllowed?: boolean;\n }): PurchasePolicy {\n return new PurchasePolicy(\n changes.perPaymentLimits ?? this.perPaymentLimits,\n changes.cumulativeLimits ?? this.cumulativeLimits,\n this.spentTotals,\n changes.recipients !== undefined ? changes.recipients : this.recipients,\n this.assetsByKey,\n changes.unlistedAssetsAllowed ?? this.unlistedAssetsAllowed\n );\n }\n\n /** Remember an asset's written form and reject one no budget could match. */\n private register(asset: PolicyAsset): string {\n if (!asset || typeof asset.address !== 'string' || asset.address.trim() === '') {\n throw new X402Error(\n 'A budget needs a token address; an asset with none can never match an offer',\n 'INVALID_CONFIG',\n { asset }\n );\n }\n if (typeof asset.network !== 'string' || asset.network.trim() === '') {\n throw new X402Error(\n 'A budget needs a network; the same address on two networks is two assets',\n 'INVALID_CONFIG',\n { asset }\n );\n }\n const key = assetKey(asset);\n this.assetsByKey.set(key, asset);\n return key;\n }\n}\n\n/** A ceiling has to be a non-negative bigint; anything else is a config bug. */\nfunction requireCeiling(amount: bigint, field: string): bigint {\n if (typeof amount !== 'bigint' || amount < 0n) {\n throw new X402Error(\n `${field} must be a non-negative bigint in atomic units`,\n 'INVALID_AMOUNT',\n { amount: String(amount) }\n );\n }\n return amount;\n}\n\n/**\n * An offer's price as a bigint.\n *\n * Arithmetic is bigint throughout, never `number`: atomic units of an 18-decimal\n * token pass `Number.MAX_SAFE_INTEGER` at 0.01 of a token, and a ceiling\n * compared as a float is a ceiling that rounds.\n *\n * An amount that is not a non-negative integer is read as the largest value we\n * can represent for the comparison, so it fails every ceiling rather than\n * passing as zero: a price we cannot read is not a price we may pay.\n */\nfunction readAmount(amount: string): bigint {\n const text = String(amount).trim();\n if (!/^\\d+$/.test(text)) return UNREADABLE_AMOUNT;\n return BigInt(text);\n}\n\n/**\n * Stand-in for a price we could not read. Absurdly large on purpose: it exceeds\n * every ceiling a caller would write, so an unreadable amount is refused by the\n * limit checks instead of sliding through as zero.\n */\nconst UNREADABLE_AMOUNT = (1n << 256n) - 1n;\n\nfunction compareToQuote(\n asset: PolicyAsset,\n requested: bigint,\n quote: AdvertisedQuote | undefined\n): QuoteComparison {\n if (!quote) return { code: 'not-compared' };\n if (assetKey(quote.asset) !== assetKey(asset)) {\n // Rule 4: a different asset is not the same price. No numbers are compared.\n return { code: 'different-asset', advertised: quote.asset, offered: asset };\n }\n if (quote.amount !== requested) {\n return { code: 'amount-differs', advertised: quote.amount, offered: requested };\n }\n return { code: 'matches' };\n}\n\n// ============================================================================\n// The whole decision, in one place\n// ============================================================================\n\n/** A 402 challenge as the buyer read it, whole. */\nexport interface ReadChallenge {\n /** Offers this build could read. */\n offers: X402PaymentOffer[];\n /**\n * Scheme names of the entries it could not. Rule 7: an `accepts` with one\n * unreadable entry KEEPS the readable ones and counts the others by scheme\n * name, so a refusal can say what the seller offered.\n */\n unreadable: string[];\n /**\n * How many entries were unreadable, which is not the same as how many could be\n * NAMED: an entry too broken to even carry a `scheme` still proves the seller\n * sent offers. Without it, a challenge whose only entry was nameless garbage\n * would read as \"the seller sent nothing\" -- a different fact, and the wrong\n * one to report. Defaults to `unreadable.length`.\n */\n unreadableCount?: number;\n /** The challenge's top-level `extensions`, where `validUntil` lives. */\n extensions?: Record<string, unknown>;\n}\n\n/** Inputs to {@link decideOnChallenge} besides the challenge. */\nexport interface DecideOptions {\n /** Unix seconds. Passed, never read, so the decision can be pinned in a test. */\n now: number;\n /** What the catalog advertised, if the caller read a listing. */\n quote?: AdvertisedQuote;\n}\n\n/**\n * The whole buying decision: all six steps, in the fixed order, against the\n * offer in hand.\n *\n * Takes the challenge WHOLE, deliberately. Passing `offers` alone is what\n * dropped the seller's `validUntil` on the floor in the Rust crate for a full\n * commit with every unit test green, and a signature that takes the parts\n * invites doing it again.\n *\n * Callable without a network stack on purpose: a decision that can only be\n * exercised by driving a real HTTP client is a decision nobody tests.\n *\n * @param offer - The offer already selected out of `challenge.offers`. Selection\n * is the caller's (cheapest, or its own `select`); this decides whether the\n * selected one may be paid.\n */\nexport function decideOnChallenge(\n policy: PurchasePolicy,\n challenge: ReadChallenge,\n offer: X402PaymentOffer | null,\n options: DecideOptions\n): PolicyDecision {\n // 1. Was any offer readable at all? A challenge that carried offers, none of\n // which this build can read, is not \"no matching payment method\": it is a\n // seller asking for a scheme we do not implement, and saying so names what\n // they wanted.\n const unreadableCount = challenge.unreadableCount ?? challenge.unreadable.length;\n if (challenge.offers.length === 0 && unreadableCount > 0) {\n return { ok: false, refusal: noReadableOffer(challenge.unreadable) };\n }\n if (!offer) {\n // Nothing selected out of a challenge that had readable offers, or a seller\n // that sent no offers at all. Either way there is no offer in hand to judge,\n // and the refusal names what the seller offered -- an empty list when it\n // offered nothing.\n return { ok: false, refusal: noReadableOffer(challenge.unreadable) };\n }\n return policy.evaluate(offer, {\n now: options.now,\n validUntil: offerValidUntil(challenge.extensions),\n quote: options.quote,\n });\n}\n","/**\n * uvd-x402-sdk\n *\n * x402 Payment SDK - Gasless crypto payments using the Ultravioleta facilitator.\n *\n * Supports 29 blockchain networks:\n * - EVM (17): Base, Ethereum, Polygon, Arbitrum, Optimism, Avalanche, Celo, HyperEVM, Unichain, Monad, Scroll, SKALE Base (mainnet + Sepolia), Robinhood Chain (mainnet + testnet), Arc mainnet + testnet\n * - SVM (2): Solana, Fogo\n * - Stellar (1): Stellar\n * - NEAR (1): NEAR Protocol\n * - Algorand (2): Algorand mainnet and testnet\n * - Sui (2): Sui mainnet and testnet\n * - XRPL (2): XRP Ledger mainnet and testnet\n *\n * Supports both x402 v1 and v2 protocols.\n *\n * @example Basic usage (EVM)\n * ```ts\n * import { X402Client } from 'uvd-x402-sdk';\n *\n * const client = new X402Client({ defaultChain: 'base' });\n *\n * // Connect wallet\n * await client.connect('base');\n *\n * // Create payment\n * const result = await client.createPayment({\n * recipient: '0x...',\n * amount: '10.00',\n * });\n *\n * // Use result.paymentHeader in X-PAYMENT HTTP header\n * ```\n *\n * @example With SVM (Solana/Fogo)\n * ```ts\n * import { SVMProvider } from 'uvd-x402-sdk/solana';\n * import { getChainByName } from 'uvd-x402-sdk';\n *\n * const svm = new SVMProvider();\n * const address = await svm.connect();\n *\n * // Solana payment\n * const solanaConfig = getChainByName('solana')!;\n * const payload = await svm.signPayment(paymentInfo, solanaConfig);\n * const header = svm.encodePaymentHeader(payload, solanaConfig);\n *\n * // Fogo payment (same provider, different config)\n * const fogoConfig = getChainByName('fogo')!;\n * const fogoPayload = await svm.signPayment(paymentInfo, fogoConfig);\n * const fogoHeader = svm.encodePaymentHeader(fogoPayload, fogoConfig);\n * ```\n *\n * @example With NEAR\n * ```ts\n * import { NEARProvider } from 'uvd-x402-sdk/near';\n * import { getChainByName } from 'uvd-x402-sdk';\n *\n * const near = new NEARProvider();\n * const accountId = await near.connect();\n * const nearConfig = getChainByName('near')!;\n * const payload = await near.signPayment(paymentInfo, nearConfig);\n * const header = near.encodePaymentHeader(payload);\n * ```\n *\n * @example With Algorand\n * ```ts\n * import { AlgorandProvider } from 'uvd-x402-sdk/algorand';\n * import { getChainByName } from 'uvd-x402-sdk';\n *\n * const algorand = new AlgorandProvider();\n * const address = await algorand.connect();\n * const algorandConfig = getChainByName('algorand')!;\n * const payload = await algorand.signPayment(paymentInfo, algorandConfig);\n * const header = algorand.encodePaymentHeader(payload, algorandConfig);\n * ```\n *\n * @example With Sui (Sponsored Transactions)\n * ```ts\n * import { SuiProvider } from 'uvd-x402-sdk/sui';\n * import { getChainByName } from 'uvd-x402-sdk';\n *\n * const sui = new SuiProvider();\n * const address = await sui.connect();\n * const suiConfig = getChainByName('sui')!;\n * const payload = await sui.signPayment(paymentInfo, suiConfig);\n * const header = sui.encodePaymentHeader(payload, suiConfig);\n * // User pays ZERO gas - facilitator sponsors the transaction\n * ```\n *\n * @example With XRPL (t54 pre-signed Payment blob)\n * ```ts\n * import { XRPLProvider } from 'uvd-x402-sdk/xrpl';\n * import { getChainByName } from 'uvd-x402-sdk';\n *\n * const xrpl = new XRPLProvider({ seed: process.env.XRPL_SEED });\n * const address = await xrpl.connect();\n * const xrplConfig = getChainByName('xrpl')!;\n * const payload = await xrpl.signPayment(paymentInfo, xrplConfig); // { signedTxBlob }\n * const header = xrpl.encodePaymentHeader(payload);\n * ```\n *\n * @example With React\n * ```tsx\n * import { X402Provider, useX402, usePayment } from 'uvd-x402-sdk/react';\n *\n * function App() {\n * return (\n * <X402Provider>\n * <PaymentButton />\n * </X402Provider>\n * );\n * }\n * ```\n *\n * @packageDocumentation\n */\n\n// Main client\n// DX402 durable-evidence: recover a paid response after the fact.\nexport {\n EVIDENCE_HEADER,\n DX402Error,\n EvidenceSkipped,\n ContentHashMismatch,\n isEndToEnd,\n contentHash,\n paymentId as dx402PaymentId,\n parseEvidenceHeader,\n evidenceFromHeaders,\n dereferencePointer,\n parseSealed,\n unseal,\n recoverEvidence,\n // seller side\n sealEvidence,\n ed25519ToX25519,\n payerKeyFromEvmSignature,\n sealedRoles,\n anchorDigest,\n signAnchorEd25519,\n signAnchorEvm,\n ZERO_ADDRESS,\n sealEvidenceTo,\n payerKeyFromSolanaAddress,\n anchorEvidence,\n availableBackends,\n type BackendOffer,\n // Reachable only via a deep import before this: the helper that exists so\n // nobody hand-builds a digest was the one you had to already know about.\n sellerDigestFor,\n ANCHOR_MAX_REQUEST_BYTES,\n evidenceHeader,\n} from './dx402';\nexport type { AnchoredEvidence, EvidenceMode, RecipientRole, AnchorOptions } from './dx402';\n\nexport { X402Client } from './client';\n\n// ============================================================================\n// Buyer policy - what this buyer is allowed to sign, decided before it signs\n// ============================================================================\n\nexport {\n PurchasePolicy,\n PolicyRefusedError,\n decideOnChallenge,\n noReadableOffer,\n offerValidUntil,\n offerAsset,\n canonicalRecipient,\n assetKey,\n OFFER_VALIDITY_EXTENSION,\n} from './policy';\nexport type {\n PolicyAsset,\n PolicyRefusal,\n PolicyRefusalCode,\n PolicyApproval,\n PolicyDecision,\n QuoteComparison,\n AdvertisedQuote,\n EvaluateOptions,\n DecideOptions,\n ReadChallenge,\n} from './policy';\n\n// Chain configuration\nexport {\n SUPPORTED_CHAINS,\n DEFAULT_CHAIN,\n DEFAULT_FACILITATOR_URL,\n getChainById,\n getChainByName,\n isChainSupported,\n getEnabledChains,\n getChainsByNetworkType,\n getEVMChainIds,\n getSVMChains,\n isSVMChain,\n getNetworkType,\n getExplorerTxUrl,\n getExplorerAddressUrl,\n // Multi-token support functions\n getTokenConfig,\n getTokenByAddress,\n getSupportedTokens,\n isTokenSupported,\n getChainsByToken,\n // Algorand helper functions\n getAlgorandChains,\n isAlgorandChain,\n // Sui helper functions\n getSuiChains,\n isSuiChain,\n // XRPL helper functions\n getXRPLChains,\n isXRPLChain,\n} from './chains';\n\n// x402 utilities\nexport {\n detectX402Version,\n paymentChallengeFrom,\n chainToCAIP2,\n caip2ToChain,\n parseNetworkIdentifier,\n encodeX402Header,\n decodeX402Header,\n createX402V1Header,\n createX402V2Header,\n createX402Header,\n generatePaymentOptions,\n isCAIP2Format,\n convertX402Header,\n // Validation utilities\n validateRecipient,\n validateAmount,\n // Payment header utilities\n createPaymentHeaders,\n getPaymentHeader,\n DEFAULT_PAYMENT_HEADER,\n PAYMENT_HEADER_NAMES,\n // UTF-8 safe base64 (token domain names like `USD₮0` are not ASCII)\n encodeBase64Utf8,\n decodeBase64Utf8,\n encodeBase64Json,\n // Multi-token payloads\n buildTokenMetadata,\n // EIP-3009 validity window (`validBefore = now + validitySeconds`)\n DEFAULT_VALIDITY_SECONDS,\n MAX_VALIDITY_SECONDS,\n resolveValiditySeconds,\n clampValiditySeconds,\n} from './utils';\n\n// Types\nexport type {\n // Chain types\n ChainConfig,\n USDCConfig,\n NativeCurrency,\n NetworkType,\n\n // Token types (multi-token support)\n TokenType,\n TokenConfig,\n PaymentTokenMetadata,\n\n // Wallet types\n WalletState,\n WalletAdapter,\n EIP712Domain,\n EIP712Types,\n\n // Payment types\n PaymentInfo,\n PaymentRequest,\n PaymentResult,\n X402PaymentOffer,\n X402FetchOptions,\n PaymentHeaders,\n PaymentPayload,\n EVMPaymentPayload,\n SolanaPaymentPayload,\n StellarPaymentPayload,\n NEARPaymentPayload,\n AlgorandPaymentPayload,\n SuiPaymentPayload,\n XRPLPaymentPayload,\n X402HeaderName,\n\n // x402 header types (v1 and v2)\n X402Scheme,\n X402Version,\n X402Header,\n X402HeaderV1,\n X402HeaderV2,\n X402PaymentOption,\n X402PayloadData,\n X402EVMPayload,\n X402SolanaPayload,\n X402SettlementAccountPayload,\n X402StellarPayload,\n X402NEARPayload,\n X402AlgorandPayload,\n X402SuiPayload,\n X402XRPLPayload,\n\n // Config types\n X402ClientConfig,\n MultiPaymentConfig,\n NetworkBalance,\n\n // Event types\n X402Event,\n X402EventData,\n X402EventHandler,\n\n // Error types\n X402ErrorCode,\n} from './types';\n\nexport { X402Error, DEFAULT_CONFIG, CAIP2_IDENTIFIERS, CAIP2_TO_CHAIN } from './types';\n\n// Signing wallet adapters\nexport type { SigningWalletAdapter, EIP3009Params, EIP3009Authorization } from './wallet';\nexport { EnvKeyAdapter } from './adapters/env-key';\nexport { OWSWalletAdapter } from './adapters/ows';\nexport type { OWSWallet } from './adapters/ows';\n\n// Facilitator configuration\nexport { FACILITATOR_ADDRESSES, getFacilitatorAddress } from './facilitator';\nexport type { FacilitatorAddresses } from './facilitator';\n\n// Live traffic stream (GET /events, Server-Sent Events)\nexport {\n streamTrafficEvents,\n parseTrafficEvent,\n matchesFilters,\n SSEParser,\n TrafficStreamError,\n EVENT_KINDS,\n KEEPALIVE_INTERVAL_MS,\n} from './events';\nexport type {\n TrafficEvent,\n TrafficEventKind,\n StreamTrafficEventsOptions,\n SSEFrame,\n} from './events';\n\n// ERC-8128 signed HTTP requests (RFC 9421 signature base + EIP-191)\nexport {\n signRequest,\n signRequestWithWallet,\n signRequestWithSigner,\n fetchNonce,\n createSignedFetch,\n buildSignatureBase,\n buildSignatureParams,\n} from './erc8128';\nexport type {\n ERC8128RequestOptions,\n SignRequestOptions,\n SignRequestWithSignerOptions,\n SignatureHeaders,\n CreateSignedFetchConfig,\n SignatureBaseParams,\n SignatureParamsInput,\n} from './erc8128';\n\n// Escrow pre-auth (sign-on-assignment X-Payment-Auth for the x402r escrow)\nexport {\n buildEscrowPreAuth,\n computeEscrowNonce,\n ESCROW_TIER_WINDOWS,\n ESCROW_DEPOSIT_LIMIT_USD,\n OPERATOR_FEE_BPS,\n MAX_PROTOCOL_FEE_BPS,\n DEFAULT_MIN_FEE_BPS,\n DEFAULT_MAX_FEE_BPS,\n VERIFIED_USDC_DOMAINS,\n} from './escrow-preauth';\nexport type {\n EscrowNetworkConfig,\n EscrowPaymentInfo,\n EscrowPreAuthParams,\n EscrowPreAuthSigner,\n EscrowTierWindows,\n} from './escrow-preauth';\n\n// Signed escrow lifecycle orders (who may release / refund money already held)\nexport {\n buildLifecycleAuth,\n buildLifecycleTypedData,\n lifecycleAuthFromSignature,\n wagmiLifecycleSigner,\n LIFECYCLE_ACTIONS,\n LIFECYCLE_DOMAIN_NAME,\n LIFECYCLE_DOMAIN_VERSION,\n LIFECYCLE_MAX_DEADLINE_SECS,\n LIFECYCLE_DEFAULT_DEADLINE_SECS,\n LIFECYCLE_ORDER_TYPES,\n} from './lifecycle-auth';\nexport type {\n LifecycleAction,\n LifecycleAuth,\n LifecyclePaymentInfo,\n LifecycleSigner,\n LifecycleTypedData,\n LifecycleTypedDataParams,\n BuildLifecycleAuthParams,\n WagmiLifecycleWalletClient,\n} from './lifecycle-auth';\n\n// EIP-7702 delegated accounts (which dialect a delegated payer must sign in)\nexport {\n DELEGATE_PREFIX,\n SMA_WRAP_TARGETS,\n delegateTarget,\n isDelegated,\n needsAccountWrap,\n replaySafeTypedData,\n resolveDelegation,\n rpcDelegationResolver,\n wrapSignature,\n} from './erc7702.js';\nexport type { DelegationResolver, DelegationVerdict } from './erc7702.js';\n\n// Server-side middleware and facilitator client\nexport {\n FacilitatorClient,\n createPaymentMiddleware,\n createHonoMiddleware,\n create402Response,\n extractPaymentFromHeaders,\n buildPaymentRequirements,\n buildVerifyRequest,\n buildSettleRequest,\n buildVerifyRequestV2,\n buildSettleRequestV2,\n // Choosing the envelope instead of assuming v1. `FacilitatorClient` now does\n // this on its own; these are for callers that build the body themselves.\n resolveEnvelopeVersion,\n buildVerifyRequestForVersion,\n buildSettleRequestForVersion,\n toResourceInfoV2,\n toPaymentRequirementsV2,\n getCorsHeaders,\n X402_CORS_HEADERS,\n X402_HEADER_NAMES,\n // Reading a facilitator refusal as data. A 503 is \"no verdict\", not a\n // rejected payment: re-signing on one charges the buyer twice.\n MAX_RETRY_AFTER_SECONDS,\n DEFAULT_RETRY_AFTER_SECONDS,\n DEFAULT_FACILITATOR_RETRIES,\n WRITER_LEASE_REASONS,\n REPLAYABLE_LEASE_REASONS,\n AMBIGUOUS_LEASE_REASONS,\n isReplayableLeaseReason,\n isAmbiguousLeaseReason,\n parseRetryAfterSeconds,\n readFacilitatorError,\n facilitatorFetch,\n // The 502 that must NOT be retried: the transfer was broadcast and may be\n // mined, so the hash is the answer and a retry is a second payment.\n SETTLEMENT_UNCONFIRMED,\n isSettlementUnconfirmed,\n parseFacilitatorErrorBody,\n // One purchase binding per payment. An authorization the facilitator already\n // admitted is answered 409 to a resend without it: the X-PAYMENT was used.\n IDEMPOTENCY_KEY_HEADER,\n IDEMPOTENT_REPLAYED_HEADER,\n createIdempotencyKey,\n AUTHORIZATION_ALREADY_SETTLED,\n AUTHORIZATION_IN_FLIGHT,\n RECEIPT_REQUEST_CONFLICT,\n isAuthorizationAlreadyUsed,\n isAuthorizationInFlight,\n buildPaymentConflictResponse,\n} from './backend';\nexport type {\n ResourceInfoV2,\n PaymentRequirementsV2,\n PaymentPayloadV2,\n VerifyRequestV2,\n SettleRequestV2,\n FacilitatorClientOptions,\n HonoMiddlewareOptions,\n PaymentAcceptance,\n PaymentMiddlewareOptions,\n VerifiedPaymentState,\n FacilitatorErrorInfo,\n FacilitatorFailureFields,\n FacilitatorFetchOptions,\n ParsedFacilitatorErrorBody,\n WriterLeaseReason,\n VerifyResponse,\n SettleResponse,\n FacilitatorCallOptions,\n AdmittedAuthorizationCode,\n PaymentConflictResponse,\n} from './backend';\n\n// Native Hedera; the optional signing peer remains lazily loaded.\nexport { HederaProvider, buildHederaRequirements, buildHederaRequest, validateHederaRequirements, HEDERA_NETWORKS } from './providers/hedera';\nexport type { HederaNetwork, HederaRequirements, HederaPaymentPayload } from './providers/hedera';\n\nexport * from \"./receipts\";\n","/**\n * uvd-x402-sdk - EnvKeyAdapter\n *\n * SigningWalletAdapter implementation using a raw private key.\n * Reads the key from a constructor parameter or the WALLET_PRIVATE_KEY\n * environment variable.\n *\n * Intended for server-side / CLI / agent use cases where the\n * signing key is available in the environment. NEVER use this\n * in browser contexts -- use OWSWalletAdapter instead.\n *\n * @example Using environment variable\n * ```ts\n * // Reads process.env.WALLET_PRIVATE_KEY\n * const wallet = new EnvKeyAdapter();\n * console.log(wallet.getAddress()); // 0x...\n * ```\n *\n * @example Using explicit key\n * ```ts\n * const wallet = new EnvKeyAdapter(process.env.MY_AGENT_KEY!);\n * const auth = await wallet.signEIP3009({\n * to: '0xRecipient',\n * amountUsdc: 0.10,\n * network: 'base',\n * });\n * ```\n */\n\nimport { ethers } from 'ethers';\nimport { getChainByName } from '../chains';\nimport { X402Error } from '../types';\nimport type {\n SigningWalletAdapter,\n EIP3009Params,\n EIP3009Authorization,\n} from '../wallet';\n\n/**\n * EnvKeyAdapter -- SigningWalletAdapter backed by a raw private key.\n */\nexport class EnvKeyAdapter implements SigningWalletAdapter {\n private readonly wallet: ethers.Wallet;\n\n /**\n * Create an EnvKeyAdapter.\n *\n * @param privateKey - Hex-encoded private key (with or without 0x prefix).\n * If omitted, reads from `process.env.WALLET_PRIVATE_KEY`.\n * @throws {X402Error} if no private key is available\n */\n constructor(privateKey?: string) {\n const key = privateKey || (typeof process !== 'undefined' ? process.env.WALLET_PRIVATE_KEY : undefined);\n\n if (!key) {\n throw new X402Error(\n 'No private key provided. Pass it to the constructor or set WALLET_PRIVATE_KEY env var.',\n 'WALLET_NOT_CONNECTED',\n );\n }\n\n this.wallet = new ethers.Wallet(key);\n }\n\n /**\n * Get the checksummed EVM wallet address.\n */\n getAddress(): string {\n return this.wallet.address;\n }\n\n /**\n * Sign a message using EIP-191 personal_sign.\n *\n * @param message - The message string to sign\n * @returns Hex-encoded signature\n */\n async signMessage(message: string): Promise<string> {\n return this.wallet.signMessage(message);\n }\n\n /**\n * Sign EIP-712 typed structured data.\n *\n * @param typedData - JSON string with `domain`, `types`, `primaryType`, and `message` fields\n * @returns Object with signature and v/r/s components\n */\n async signTypedData(typedData: string): Promise<{\n signature: string;\n v: number;\n r: string;\n s: string;\n }> {\n const parsed = JSON.parse(typedData) as {\n domain: ethers.TypedDataDomain;\n types: Record<string, Array<{ name: string; type: string }>>;\n primaryType: string;\n message: Record<string, unknown>;\n };\n\n // ethers v6 signTypedData does not take primaryType -- it infers it\n // from the types object (the type not listed as a field of another type).\n // We pass domain, types (without EIP712Domain), and the message value.\n const { domain, types, message } = parsed;\n\n // Remove EIP712Domain from types if present (ethers handles it via domain)\n const cleanTypes = { ...types };\n delete cleanTypes['EIP712Domain'];\n\n const signature = await this.wallet.signTypedData(domain, cleanTypes, message);\n const sig = ethers.Signature.from(signature);\n\n return {\n signature,\n v: sig.v,\n r: sig.r,\n s: sig.s,\n };\n }\n\n /**\n * Sign a serialized EVM transaction.\n *\n * Uses the raw private key via ethers.Wallet.signTransaction().\n * Used by AdvancedEscrowClient for on-chain operations (release,\n * refund, charge) when constructed with a SigningWalletAdapter.\n *\n * @param unsignedTx - Hex-encoded unsigned transaction (ethers serialized)\n * @returns Hex-encoded signed raw transaction, ready for broadcast\n */\n async signTransaction(unsignedTx: string): Promise<string> {\n const tx = ethers.Transaction.from(unsignedTx);\n return this.wallet.signTransaction(tx);\n }\n\n /**\n * Sign an EIP-3009 ReceiveWithAuthorization for USDC.\n *\n * @param params - EIP-3009 parameters\n * @returns Signed authorization ready for facilitator relay\n */\n async signEIP3009(params: EIP3009Params): Promise<EIP3009Authorization> {\n const chain = getChainByName(params.network);\n if (!chain) {\n throw new X402Error(`Unsupported network: ${params.network}`, 'CHAIN_NOT_SUPPORTED');\n }\n\n if (chain.networkType !== 'evm') {\n throw new X402Error(\n `EIP-3009 is only supported on EVM chains. ${params.network} is ${chain.networkType}.`,\n 'CHAIN_NOT_SUPPORTED',\n );\n }\n\n const chainId = params.chainId ?? chain.chainId;\n const usdcAddress = params.usdcContract ?? chain.usdc.address;\n const from = this.wallet.address;\n const to = ethers.getAddress(params.to);\n const value = ethers.parseUnits(params.amountUsdc.toString(), chain.usdc.decimals);\n const validAfter = params.validAfter ?? 0;\n const validBefore = params.validBefore ?? Math.floor(Date.now() / 1000) + 300;\n\n // Generate random 32-byte nonce\n const nonce = ethers.hexlify(ethers.randomBytes(32));\n\n // EIP-712 domain (matches USDC contract's domain separator)\n const domain: ethers.TypedDataDomain = {\n name: chain.usdc.name,\n version: chain.usdc.version,\n chainId,\n verifyingContract: usdcAddress,\n };\n\n // EIP-712 types for TransferWithAuthorization (ERC-3009)\n const types = {\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 };\n\n // Message to sign\n const message = {\n from,\n to,\n value,\n validAfter,\n validBefore,\n nonce,\n };\n\n // Sign the EIP-712 typed data\n let signature: string;\n try {\n signature = await this.wallet.signTypedData(domain, types, message);\n } catch (error: unknown) {\n throw new X402Error(\n `Failed to sign EIP-3009 authorization: ${error instanceof Error ? error.message : 'Unknown error'}`,\n 'PAYMENT_FAILED',\n error,\n );\n }\n\n const sig = ethers.Signature.from(signature);\n\n return {\n from,\n to,\n value: value.toString(),\n validAfter: validAfter.toString(),\n validBefore: validBefore.toString(),\n nonce,\n v: sig.v,\n r: sig.r,\n s: sig.s,\n signature,\n };\n }\n}\n","/**\n * uvd-x402-sdk - OWSWalletAdapter\n *\n * SigningWalletAdapter implementation using the Open Wallet Standard (OWS).\n * Delegates all signing to an OWS wallet instance, which manages key\n * security (encrypted vault, hardware isolation, etc.).\n *\n * Requires `@open-wallet-standard/core` as an optional peer dependency.\n * If the package is not installed, the adapter throws a helpful error\n * at construction time.\n *\n * @example\n * ```ts\n * import { OWSWalletAdapter } from 'uvd-x402-sdk';\n *\n * // The OWS wallet object must implement signMessage and signTypedData\n * const wallet = new OWSWalletAdapter(owsWallet);\n * const auth = await wallet.signEIP3009({\n * to: '0xRecipient',\n * amountUsdc: 0.50,\n * network: 'base',\n * });\n * ```\n */\n\nimport { ethers } from 'ethers';\nimport { getChainByName } from '../chains';\nimport { X402Error } from '../types';\nimport type {\n SigningWalletAdapter,\n EIP3009Params,\n EIP3009Authorization,\n} from '../wallet';\n\n// ============================================================================\n// OWS WALLET INTERFACE (minimal subset we need)\n// ============================================================================\n\n/**\n * Minimal OWS wallet interface for signing operations.\n *\n * This mirrors the subset of the Open Wallet Standard that we use,\n * avoiding a hard compile-time dependency on @open-wallet-standard/core.\n * Any object that satisfies this shape can be passed to OWSWalletAdapter.\n */\nexport interface OWSWallet {\n /** Get wallet accounts (at least one EVM account expected) */\n accounts: ReadonlyArray<{\n /** EVM address (0x...) */\n address: string;\n /** Chain identifiers this account supports */\n chains?: ReadonlyArray<string>;\n }>;\n\n /** Sign a personal message (EIP-191) */\n signMessage(params: {\n account: { address: string };\n message: string | Uint8Array;\n }): Promise<{ signature: string }>;\n\n /** Sign EIP-712 typed data */\n signTypedData(params: {\n account: { address: string };\n domain: Record<string, unknown>;\n types: Record<string, Array<{ name: string; type: string }>>;\n primaryType: string;\n message: Record<string, unknown>;\n }): Promise<{ signature: string }>;\n\n /** Sign a serialized EVM transaction (hex-encoded) */\n signTransaction(params: {\n account: { address: string };\n transaction: string;\n chainId: string;\n }): Promise<{ signedTransaction: string }>;\n}\n\n// ============================================================================\n// OWS WALLET ADAPTER\n// ============================================================================\n\n/**\n * OWSWalletAdapter -- SigningWalletAdapter backed by an Open Wallet Standard wallet.\n */\nexport class OWSWalletAdapter implements SigningWalletAdapter {\n private readonly owsWallet: OWSWallet;\n private readonly address: string;\n\n /**\n * Create an OWSWalletAdapter.\n *\n * @param owsWallet - An object implementing the OWSWallet interface\n * (typically from @open-wallet-standard/core or a compatible provider)\n * @param accountIndex - Which account to use if the wallet has multiple (default: 0)\n * @throws {X402Error} if the wallet has no accounts\n */\n constructor(owsWallet: OWSWallet, accountIndex = 0) {\n if (!owsWallet || !owsWallet.accounts || owsWallet.accounts.length === 0) {\n throw new X402Error(\n 'OWS wallet has no accounts. Create or import a wallet first.',\n 'WALLET_NOT_CONNECTED',\n );\n }\n\n const account = owsWallet.accounts[accountIndex];\n if (!account) {\n throw new X402Error(\n `OWS wallet account index ${accountIndex} does not exist. Wallet has ${owsWallet.accounts.length} account(s).`,\n 'WALLET_NOT_CONNECTED',\n );\n }\n\n this.owsWallet = owsWallet;\n this.address = ethers.getAddress(account.address);\n }\n\n /**\n * Get the checksummed EVM wallet address.\n */\n getAddress(): string {\n return this.address;\n }\n\n /**\n * Sign a message using EIP-191 personal_sign.\n *\n * @param message - The message string to sign\n * @returns Hex-encoded signature\n */\n async signMessage(message: string): Promise<string> {\n try {\n const result = await this.owsWallet.signMessage({\n account: { address: this.address },\n message,\n });\n return result.signature;\n } catch (error: unknown) {\n throw new X402Error(\n `OWS signMessage failed: ${error instanceof Error ? error.message : 'Unknown error'}`,\n 'PAYMENT_FAILED',\n error,\n );\n }\n }\n\n /**\n * Sign EIP-712 typed structured data.\n *\n * @param typedData - JSON string with `domain`, `types`, `primaryType`, and `message` fields\n * @returns Object with signature and v/r/s components\n */\n async signTypedData(typedData: string): Promise<{\n signature: string;\n v: number;\n r: string;\n s: string;\n }> {\n const parsed = JSON.parse(typedData) as {\n domain: Record<string, unknown>;\n types: Record<string, Array<{ name: string; type: string }>>;\n primaryType: string;\n message: Record<string, unknown>;\n };\n\n try {\n const result = await this.owsWallet.signTypedData({\n account: { address: this.address },\n domain: parsed.domain,\n types: parsed.types,\n primaryType: parsed.primaryType,\n message: parsed.message,\n });\n\n const sig = ethers.Signature.from(result.signature);\n\n return {\n signature: result.signature,\n v: sig.v,\n r: sig.r,\n s: sig.s,\n };\n } catch (error: unknown) {\n throw new X402Error(\n `OWS signTypedData failed: ${error instanceof Error ? error.message : 'Unknown error'}`,\n 'PAYMENT_FAILED',\n error,\n );\n }\n }\n\n /**\n * Sign a serialized EVM transaction.\n *\n * Delegates to the OWS wallet's signTransaction method.\n * Used by AdvancedEscrowClient for on-chain operations (release,\n * refund, charge) where the wallet signs instead of a raw private key.\n *\n * @param unsignedTx - Hex-encoded unsigned transaction\n * @returns Hex-encoded signed raw transaction\n */\n async signTransaction(unsignedTx: string): Promise<string> {\n try {\n const result = await this.owsWallet.signTransaction({\n account: { address: this.address },\n transaction: unsignedTx,\n chainId: '1', // chainId is embedded in the serialized TX; this is a hint\n });\n return result.signedTransaction;\n } catch (error: unknown) {\n throw new X402Error(\n `OWS signTransaction failed: ${error instanceof Error ? error.message : 'Unknown error'}`,\n 'PAYMENT_FAILED',\n error,\n );\n }\n }\n\n /**\n * Sign an EIP-3009 ReceiveWithAuthorization for USDC.\n *\n * @param params - EIP-3009 parameters\n * @returns Signed authorization ready for facilitator relay\n */\n async signEIP3009(params: EIP3009Params): Promise<EIP3009Authorization> {\n const chain = getChainByName(params.network);\n if (!chain) {\n throw new X402Error(`Unsupported network: ${params.network}`, 'CHAIN_NOT_SUPPORTED');\n }\n\n if (chain.networkType !== 'evm') {\n throw new X402Error(\n `EIP-3009 is only supported on EVM chains. ${params.network} is ${chain.networkType}.`,\n 'CHAIN_NOT_SUPPORTED',\n );\n }\n\n const chainId = params.chainId ?? chain.chainId;\n const usdcAddress = params.usdcContract ?? chain.usdc.address;\n const from = this.address;\n const to = ethers.getAddress(params.to);\n const value = ethers.parseUnits(params.amountUsdc.toString(), chain.usdc.decimals);\n const validAfter = params.validAfter ?? 0;\n const validBefore = params.validBefore ?? Math.floor(Date.now() / 1000) + 300;\n\n // Generate random 32-byte nonce\n const nonce = ethers.hexlify(ethers.randomBytes(32));\n\n // EIP-712 domain\n const domain: Record<string, unknown> = {\n name: chain.usdc.name,\n version: chain.usdc.version,\n chainId,\n verifyingContract: usdcAddress,\n };\n\n // EIP-712 types for TransferWithAuthorization (ERC-3009)\n const types = {\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 };\n\n // Message to sign\n const message: Record<string, unknown> = {\n from,\n to,\n value: value.toString(),\n validAfter: validAfter.toString(),\n validBefore: validBefore.toString(),\n nonce,\n };\n\n let signatureResult: { signature: string };\n try {\n signatureResult = await this.owsWallet.signTypedData({\n account: { address: this.address },\n domain,\n types,\n primaryType: 'TransferWithAuthorization',\n message,\n });\n } catch (error: unknown) {\n throw new X402Error(\n `OWS signEIP3009 failed: ${error instanceof Error ? error.message : 'Unknown error'}`,\n 'PAYMENT_FAILED',\n error,\n );\n }\n\n const sig = ethers.Signature.from(signatureResult.signature);\n\n return {\n from,\n to,\n value: value.toString(),\n validAfter: validAfter.toString(),\n validBefore: validBefore.toString(),\n nonce,\n v: sig.v,\n r: sig.r,\n s: sig.s,\n signature: signatureResult.signature,\n };\n }\n}\n","/**\n * Facilitator Configuration\n *\n * This module contains the known facilitator addresses for each chain.\n * The SDK uses these automatically so users don't need to configure them.\n *\n * The facilitator (https://facilitator.ultravioletadao.xyz) has wallets\n * on each supported blockchain for:\n * - EVM: Signing EIP-3009 transferWithAuthorization transactions\n * - Solana: Paying transaction fees (fee payer)\n * - Algorand: Signing fee transactions in atomic groups\n * - Stellar: Signing authorization entries\n * - NEAR: Acting as relayer for meta-transactions\n * - Sui: Sponsoring transactions (paying gas via sponsored txs)\n * - XRPL: Submitting pre-signed Payment blobs (paying the network fee)\n */\n\n/**\n * Default facilitator URL\n */\nexport const DEFAULT_FACILITATOR_URL = 'https://facilitator.ultravioletadao.xyz';\n\n/**\n * Facilitator wallet addresses by chain type\n *\n * These are the public addresses of the facilitator's wallets.\n * The facilitator uses these to pay fees and sign transactions.\n */\nexport const FACILITATOR_ADDRESSES = {\n // ============================================\n // EVM Chains\n // ============================================\n /**\n * EVM facilitator address (mainnet)\n * Used for: Submitting EIP-3009 transferWithAuthorization transactions\n * Note: Same address across all EVM mainnet chains\n */\n evm: '0x103040545AC5031A11E8C03dd11324C7333a13C7',\n\n /**\n * EVM facilitator address (testnet)\n * Used for: All EVM testnet chains\n */\n 'evm-testnet': '0x34033041a5944B8F10f8E4D8496Bfb84f1A293A8',\n\n // ============================================\n // Solana\n // ============================================\n /**\n * Solana facilitator address (mainnet)\n * Used for: Paying transaction fees on Solana\n */\n solana: 'F742C4VfFLQ9zRQyithoj5229ZgtX2WqKCSFKgH2EThq',\n\n /**\n * Solana facilitator address (devnet)\n */\n 'solana-devnet': '6xNPewUdKRbEZDReQdpyfNUdgNg8QRc8Mt263T5GZSRv',\n\n // ============================================\n // Fogo (uses same addresses as Solana)\n // ============================================\n /**\n * Fogo facilitator address (mainnet)\n */\n fogo: 'F742C4VfFLQ9zRQyithoj5229ZgtX2WqKCSFKgH2EThq',\n\n /**\n * Fogo facilitator address (testnet)\n */\n 'fogo-testnet': '6xNPewUdKRbEZDReQdpyfNUdgNg8QRc8Mt263T5GZSRv',\n\n // ============================================\n // NEAR\n // ============================================\n /**\n * NEAR facilitator address (mainnet)\n * Used for: Relaying meta-transactions\n */\n near: 'uvd-facilitator.near',\n\n /**\n * NEAR facilitator address (testnet)\n */\n 'near-testnet': 'uvd-facilitator.testnet',\n\n // ============================================\n // Stellar\n // ============================================\n /**\n * Stellar facilitator address (mainnet)\n * Used for: Signing soroban authorization entries\n */\n stellar: 'GCHPGXJT2WFFRFCA5TV4G4E3PMMXLNIDUH27PKDYA4QJ2XGYZWGFZNHB',\n\n /**\n * Stellar facilitator address (testnet)\n */\n 'stellar-testnet': 'GBBFZMLUJEZVI32EN4XA2KPP445XIBTMTRBLYWFIL556RDTHS2OWFQ2Z',\n\n // ============================================\n // Algorand\n // ============================================\n /**\n * Algorand facilitator address (mainnet)\n * Used for: Signing Transaction 0 (fee tx) in atomic groups\n */\n algorand: 'KIMS5H6QLCUDL65L5UBTOXDPWLMTS7N3AAC3I6B2NCONEI5QIVK7LH2C2I',\n\n /**\n * Algorand facilitator address (testnet)\n */\n 'algorand-testnet': '5DPPDQNYUPCTXRZWRYSF3WPYU6RKAUR25F3YG4EKXQRHV5AUAI62H5GXL4',\n\n // ============================================\n // Sui\n // ============================================\n /**\n * Sui facilitator address (mainnet)\n * Used for: Sponsoring transactions (paying gas)\n */\n sui: '0xe7bbf2b13f7d72714760aa16e024fa1b35a978793f9893d0568a4fbf356a764a',\n\n /**\n * Sui facilitator address (testnet)\n */\n 'sui-testnet': '0xabbd16a2fab2a502c9cfe835195a6fc7d70bfc27cffb40b8b286b52a97006e67',\n\n // ============================================\n // XRPL (XRP Ledger)\n // ============================================\n /**\n * XRPL facilitator address (mainnet)\n * Used for: Submitting pre-signed Payment blobs and paying the network fee\n */\n xrpl: 'rfADKkVXBNqK3z72tVSS3LVzAR3psYkonp',\n\n // Native Hedera sponsors (canonical ledger IDs and input aliases).\n 'hedera:mainnet': '0.0.10868300',\n 'hedera:testnet': '0.0.10576385',\n hedera: '0.0.10868300',\n 'hedera-testnet': '0.0.10576385',\n\n /**\n * XRPL facilitator address (testnet)\n */\n 'xrpl-testnet': 'rGhTioKAFHe75KgVnQtacRiKFuPv28Wbwk',\n} as const;\n\n/**\n * Get the facilitator address for a specific chain\n *\n * @param chainName - The chain name (e.g., 'algorand', 'solana', 'base')\n * @param networkType - The network type (e.g., 'evm', 'svm', 'algorand')\n * @returns The facilitator address for that chain, or undefined if not supported\n */\nexport function getFacilitatorAddress(\n chainName: string,\n networkType?: string\n): string | undefined {\n // Check for exact chain match first\n const exactMatch = FACILITATOR_ADDRESSES[chainName as keyof typeof FACILITATOR_ADDRESSES];\n if (exactMatch) {\n return exactMatch;\n }\n\n // Fall back to network type\n if (networkType === 'evm') {\n return FACILITATOR_ADDRESSES.evm;\n }\n if (networkType === 'svm' || networkType === 'solana') {\n return FACILITATOR_ADDRESSES.solana;\n }\n if (networkType === 'algorand') {\n return FACILITATOR_ADDRESSES.algorand;\n }\n if (networkType === 'stellar') {\n return FACILITATOR_ADDRESSES.stellar;\n }\n if (networkType === 'near') {\n return FACILITATOR_ADDRESSES.near;\n }\n if (networkType === 'sui') {\n return FACILITATOR_ADDRESSES.sui;\n }\n if (networkType === 'xrpl') {\n return FACILITATOR_ADDRESSES.xrpl;\n }\n\n return undefined;\n}\n\n/**\n * Type for facilitator addresses\n */\nexport type FacilitatorAddresses = typeof FACILITATOR_ADDRESSES;\n","/**\n * Live traffic stream client (`GET /events`, Server-Sent Events).\n *\n * The facilitator emits one event per operation it handles, so you can render or\n * react to live traffic without polling and without scraping logs.\n *\n * @example\n * ```ts\n * import { streamTrafficEvents } from '@ultravioletadao/x402-sdk';\n *\n * for await (const event of streamTrafficEvents()) {\n * console.log(event.kind, event.network, event.ok, event.tx);\n * }\n * ```\n *\n * @example Only settlements on the chains you care about. The facilitator has NO\n * server-side filter by network, so this is applied client-side.\n * ```ts\n * const stream = streamTrafficEvents({\n * networks: ['base', 'polygon'],\n * kinds: ['settle'],\n * });\n * for await (const event of stream) console.log(event.tx);\n * ```\n *\n * Three properties of this stream decide how you should use it:\n *\n * **It is lossy by design.** The facilitator will never slow down or fail a\n * payment to keep an observer in sync, so an event you were not connected for is\n * simply gone. Treat it as a live hint and use the chain as the source of truth.\n * Absence of events is NOT evidence that nothing happened.\n *\n * **Failed operations are not published.** Only operations that resolved emit an\n * event, so `ok: false` means \"resolved and came back negative\", never \"blew up\".\n * A stream that looks healthy is not proof that the rail is.\n *\n * **Admission is bounded.** The endpoint is public and unauthenticated, so it\n * sheds with HTTP 503 + `Retry-After` once too many subscribers are connected,\n * and returns 404 when the operator disabled it.\n */\n\nimport { DEFAULT_FACILITATOR_URL } from './facilitator';\n\n/** Operations the facilitator publishes. */\nexport type TrafficEventKind = 'verify' | 'settle';\n\n/** Operations the facilitator publishes, as a value. */\nexport const EVENT_KINDS: readonly TrafficEventKind[] = ['verify', 'settle'] as const;\n\n/**\n * The stream sends a `:keepalive` comment on this cadence, so any read timeout\n * you add must comfortably exceed it or you will kill healthy connections on an\n * idle rail.\n */\nexport const KEEPALIVE_INTERVAL_MS = 15_000;\n\n/**\n * One facilitator operation, as seen by an observer.\n *\n * Optional fields are *omitted* by the facilitator rather than sent as null, and\n * they are all absent when the operator runs the stream in `minimal` detail\n * mode. Never assume `payer` or `amount` is present.\n */\nexport interface TrafficEvent {\n /** Unix epoch **milliseconds**, UTC. Note: milliseconds, not seconds. */\n ts: number;\n kind: TrafficEventKind | string;\n /**\n * The facilitator's canonical network slug, the same one `/supported` uses.\n *\n * Beware: this is the *canonical* name, which is not always the alias you are\n * allowed to send. `skale` is accepted on the way in, but this field always\n * says `skale-base`. Match on the canonical form or you will silently drop\n * every event for that chain.\n */\n network: string;\n /** Resolved successfully? False means resolved-negative, not errored. */\n ok: boolean;\n payer?: string;\n /** Present on `settle`, absent on `verify` — nothing settled yet. */\n tx?: string;\n amount?: string;\n asset?: string;\n /**\n * The protected endpoint being bought.\n *\n * Answers \"what was paid for\", which the amount alone never does — two\n * 1-USDC settles are indistinguishable without it.\n */\n resource?: string;\n /** The seller receiving the payment. */\n payTo?: string;\n /** Human-readable description the seller advertised. */\n description?: string;\n /** Payment scheme: `exact`, `escrow`, `commerce`, `upto`. */\n scheme?: string;\n /**\n * Why the operation failed, as a BOUNDED CATEGORY — never the error text.\n *\n * Present only on operations that errored, and only where the operator set\n * `X402_EVENTS_PUBLISH_FAILURES=true`. A closed set (`contract_revert`,\n * `invalid_signature`, `insufficient_funds`, `invalid_timing`,\n * `blocked_address`, …, `other`) precisely so it can never carry an address\n * or an RPC URL.\n *\n * Note the distinction it makes visible: `ok: false` with no `error` means the\n * operation RESOLVED and came back negative; `error` set means it blew up.\n * Before this existed the second case produced no event at all.\n */\n error?: string;\n}\n\n/** Raised when the stream cannot be opened. Carries the HTTP status. */\nexport class TrafficStreamError extends Error {\n readonly status: number;\n /** Seconds to wait before retrying, when the server said so (503). */\n readonly retryAfter?: number;\n\n constructor(message: string, status: number, retryAfter?: number) {\n super(message);\n this.name = 'TrafficStreamError';\n this.status = status;\n this.retryAfter = retryAfter;\n }\n}\n\nexport interface StreamTrafficEventsOptions {\n /** Facilitator to subscribe to. Defaults to the Ultravioleta DAO facilitator. */\n facilitatorUrl?: string;\n /**\n * Only yield events for these networks. Applied client-side — the facilitator\n * has no per-network filter, so every event still crosses the wire. Match the\n * canonical slug (`skale-base`, not `skale`).\n */\n networks?: string[];\n /** Only yield these operations. */\n kinds?: TrafficEventKind[];\n /** Abort the stream. Without one, iteration ends only when the server closes. */\n signal?: AbortSignal;\n /** Extra headers, for a deployment that gates the stream behind authorization. */\n headers?: Record<string, string>;\n}\n\n/** One decoded SSE frame: the event name and its raw data payload. */\nexport interface SSEFrame {\n event: string;\n data: string;\n}\n\n/**\n * Incremental Server-Sent Events parser.\n *\n * Kept separate from the network layer so the framing can be tested without a\n * socket — which matters, because the case that breaks in production is an idle\n * rail sending nothing but keepalive comments for minutes.\n */\nexport class SSEParser {\n private buffer = '';\n private eventName = '';\n private dataLines: string[] = [];\n\n /** Feed a chunk of the response body; get back whatever frames completed. */\n push(chunk: string): SSEFrame[] {\n this.buffer += chunk;\n const frames: SSEFrame[] = [];\n\n let newlineIndex: number;\n while ((newlineIndex = this.buffer.indexOf('\\n')) !== -1) {\n const line = this.buffer.slice(0, newlineIndex).replace(/\\r$/, '');\n this.buffer = this.buffer.slice(newlineIndex + 1);\n\n if (line === '') {\n // Blank line dispatches. A dispatch with no data is a no-op per spec.\n if (this.dataLines.length > 0) {\n frames.push({\n event: this.eventName || 'message',\n data: this.dataLines.join('\\n'),\n });\n }\n this.eventName = '';\n this.dataLines = [];\n continue;\n }\n\n if (line.startsWith(':')) {\n // Comment. This is what a keepalive looks like — deliberately silent.\n continue;\n }\n\n const colon = line.indexOf(':');\n const field = colon === -1 ? line : line.slice(0, colon);\n let value = colon === -1 ? '' : line.slice(colon + 1);\n // A single leading space after the colon is framing, not value.\n if (value.startsWith(' ')) value = value.slice(1);\n\n if (field === 'event') this.eventName = value;\n else if (field === 'data') this.dataLines.push(value);\n // id / retry: accepted and ignored, so a future facilitator that starts\n // sending them does not break this parser.\n }\n\n return frames;\n }\n}\n\n/**\n * Decode one SSE frame into a {@link TrafficEvent}.\n *\n * Returns null for anything malformed: a single bad message must never tear down\n * a long-lived stream — the connection is worth more than the message.\n */\nexport function parseTrafficEvent(frame: SSEFrame): TrafficEvent | null {\n let payload: unknown;\n try {\n payload = JSON.parse(frame.data);\n } catch {\n return null;\n }\n if (typeof payload !== 'object' || payload === null || Array.isArray(payload)) {\n return null;\n }\n\n const raw = payload as Record<string, unknown>;\n // The SSE event name is authoritative for `kind`; the body carries it too and\n // they agree, but the framing is the contract.\n const kind = (raw.kind as string) || frame.event;\n\n if (typeof raw.ts !== 'number' || typeof raw.network !== 'string' || typeof raw.ok !== 'boolean') {\n return null;\n }\n\n const event: TrafficEvent = {\n ts: raw.ts,\n kind,\n network: raw.network,\n ok: raw.ok,\n };\n if (typeof raw.payer === 'string') event.payer = raw.payer;\n if (typeof raw.tx === 'string') event.tx = raw.tx;\n if (typeof raw.amount === 'string') event.amount = raw.amount;\n if (typeof raw.asset === 'string') event.asset = raw.asset;\n if (typeof raw.resource === 'string') event.resource = raw.resource;\n if (typeof raw.payTo === 'string') event.payTo = raw.payTo;\n if (typeof raw.description === 'string') event.description = raw.description;\n if (typeof raw.scheme === 'string') event.scheme = raw.scheme;\n if (typeof raw.error === 'string') event.error = raw.error;\n return event;\n}\n\n/** Does this event pass the caller's client-side filters? */\nexport function matchesFilters(\n event: TrafficEvent,\n options: Pick<StreamTrafficEventsOptions, 'networks' | 'kinds'>\n): boolean {\n if (options.kinds && options.kinds.length > 0) {\n if (!options.kinds.some((k) => k.toLowerCase() === event.kind.toLowerCase())) return false;\n }\n if (options.networks && options.networks.length > 0) {\n if (!options.networks.some((n) => n.toLowerCase() === event.network.toLowerCase())) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * Subscribe to the facilitator's live traffic stream.\n *\n * Works in Node 18+ and in browsers: it uses `fetch` and the response body\n * stream rather than `EventSource`, so it also works where custom headers are\n * needed (`EventSource` cannot send them).\n *\n * Iteration ends when the server closes the connection or the `signal` aborts.\n * It does NOT reconnect on its own — reconnect policy belongs to the caller, who\n * is the only one who knows whether a gap matters.\n *\n * @throws {TrafficStreamError} 404 when the operator disabled the stream, 503\n * with `retryAfter` when it is at subscriber capacity.\n */\nexport async function* streamTrafficEvents(\n options: StreamTrafficEventsOptions = {}\n): AsyncGenerator<TrafficEvent, void, undefined> {\n const baseUrl = (options.facilitatorUrl || DEFAULT_FACILITATOR_URL).replace(/\\/$/, '');\n const response = await fetch(`${baseUrl}/events`, {\n method: 'GET',\n headers: { Accept: 'text/event-stream', ...(options.headers || {}) },\n signal: options.signal,\n });\n\n if (!response.ok) {\n const body = await response.text().catch(() => '');\n if (response.status === 404) {\n throw new TrafficStreamError(\n `GET /events is disabled on this facilitator (operator set X402_EVENTS_ENABLED=false): ${body}`,\n 404\n );\n }\n if (response.status === 503) {\n const header = response.headers.get('retry-after');\n const retryAfter = header ? Number(header) : undefined;\n throw new TrafficStreamError(\n `GET /events is at subscriber capacity; retry after ${header ?? 'unknown'}s. ` +\n `This is admission control, not an outage.`,\n 503,\n Number.isFinite(retryAfter) ? retryAfter : undefined\n );\n }\n throw new TrafficStreamError(`GET /events failed: ${response.status} - ${body}`, response.status);\n }\n\n if (!response.body) {\n throw new TrafficStreamError('GET /events returned no body to stream', response.status);\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n const parser = new SSEParser();\n\n try {\n for (;;) {\n const { done, value } = await reader.read();\n if (done) return;\n for (const frame of parser.push(decoder.decode(value, { stream: true }))) {\n const event = parseTrafficEvent(frame);\n if (event && matchesFilters(event, options)) yield event;\n }\n }\n } finally {\n // Releasing the lock lets the caller's `break` actually close the socket\n // instead of leaking a half-read response.\n reader.releaseLock();\n }\n}\n","/**\n * uvd-x402-sdk - ERC-8128 HTTP Message Signature Signer\n *\n * Signs HTTP requests per ERC-8128 (Signed HTTP Requests with Ethereum,\n * RFC 9421 profile) so agents can authenticate against APIs that reject\n * API keys and only accept wallet signing (e.g. Execution Market, where\n * `EM_API_KEYS_ENABLED=false` in production).\n *\n * Flow:\n * 1. Fetch a fresh single-use nonce from the server (`fetchNonce`)\n * 2. Build the RFC 9421 signature base from request components\n * 3. Sign with EIP-191 personal_sign\n * 4. Produce `Signature` + `Signature-Input` (+ `Content-Digest`) headers\n *\n * Wire format: pinned by the F3-1 golden vectors (`src/erc8128.vectors.json`)\n * — `alg=\"eip191\"` always emitted, keyid ALWAYS lowercase, params in the\n * order `created;expires;nonce;keyid;alg`. Byte-equality against the vectors\n * is enforced in `src/erc8128.test.ts`.\n *\n * Three signing entry points:\n * - {@link signRequest} — raw private key (ethers Wallet), for scripts /\n * bots that hold the key in env.\n * - {@link signRequestWithWallet} — any {@link SigningWalletAdapter}\n * (EnvKeyAdapter, OWSWalletAdapter, custom); only `getAddress()` and\n * `signMessage()` are used, the key never leaves the adapter.\n * - {@link signRequestWithSigner} — callback-based, for browser wallets or\n * out-of-process signers that expose a bare EIP-191 personal_sign.\n *\n * @example Sign a single request\n * ```typescript\n * import { signRequest, fetchNonce } from 'uvd-x402-sdk';\n *\n * const nonce = await fetchNonce('https://api.execution.market');\n * const headers = await signRequest({\n * privateKey: process.env.WALLET_PRIVATE_KEY!,\n * method: 'POST',\n * url: 'https://api.execution.market/api/v1/tasks',\n * body: '{\"title\": \"test\"}',\n * nonce,\n * chainId: 8453,\n * });\n * // headers = { Signature: '...', 'Signature-Input': '...', 'Content-Digest': '...' }\n * ```\n *\n * @example Auto-signing fetch wrapper\n * ```typescript\n * import { createSignedFetch, EnvKeyAdapter } from 'uvd-x402-sdk';\n *\n * const signedFetch = createSignedFetch({\n * wallet: new EnvKeyAdapter(), // or privateKey: '...'\n * apiBase: 'https://api.execution.market',\n * });\n *\n * const resp = await signedFetch('/api/v1/tasks', {\n * method: 'POST',\n * body: JSON.stringify({ title: 'test' }),\n * });\n * ```\n *\n * Reference:\n * - ERC-8128: https://eip.tools/eip/8128\n * - RFC 9421: https://www.rfc-editor.org/rfc/rfc9421\n * - ERC-191: https://eips.ethereum.org/EIPS/eip-191\n */\n\nimport { ethers } from 'ethers';\nimport { X402Error } from './types';\nimport type { SigningWalletAdapter } from './wallet';\n\n/** Default label for ERC-8128 signatures */\nconst DEFAULT_LABEL = 'eth';\n\n/** Signature algorithm parameter — pinned by F3-1 (always emitted) */\nconst ALG = 'eip191';\n\n/** Default validity window (seconds) — server policy typically caps at 300 */\nconst DEFAULT_VALIDITY_SEC = 300;\n\n/** Default EVM chain ID for the keyid (Base mainnet, the production auth chain) */\nconst DEFAULT_CHAIN_ID = 8453;\n\n/**\n * Request components shared by every ERC-8128 signing entry point.\n */\nexport interface ERC8128RequestOptions {\n /** HTTP method (GET, POST, etc.) */\n method: string;\n /** Full URL of the request (authority + path + query are covered) */\n url: string;\n /**\n * Request body (for POST/PUT/PATCH). Omit for bodyless requests.\n * Must be byte-identical to what is sent on the wire — the\n * `Content-Digest` covers it.\n */\n body?: string;\n /** Single-use nonce from the server. Required by most servers. */\n nonce?: string;\n /** EVM chain ID for the keyid (default: 8453 = Base) */\n chainId?: number;\n /** Signature label (default: \"eth\") */\n label?: string;\n /** Signature validity window in seconds (default: 300) */\n validitySec?: number;\n}\n\nexport interface SignRequestOptions extends ERC8128RequestOptions {\n /** Hex-encoded private key (with or without 0x prefix) */\n privateKey: string;\n}\n\nexport interface SignRequestWithSignerOptions extends ERC8128RequestOptions {\n /** Signer address (any case — lowercased for the keyid per F3-1) */\n address: string;\n /**\n * EIP-191 personal_sign callback over the RFC 9421 signature base.\n * Must return the 65-byte signature (r||s||v) as 0x-prefixed hex.\n * The private key never leaves the signer (OWS vault, browser wallet).\n */\n signMessage: (signatureBase: string) => Promise<string> | string;\n}\n\nexport interface SignatureHeaders {\n Signature: string;\n 'Signature-Input': string;\n 'Content-Digest'?: string;\n}\n\n/**\n * Configuration for {@link createSignedFetch}. Provide exactly one signer:\n * a raw `privateKey` or a `wallet` adapter.\n */\nexport interface CreateSignedFetchConfig {\n /** Origin of the API (e.g. \"https://api.execution.market\") */\n apiBase: string;\n /** EVM chain ID for the keyid (default: 8453 = Base) */\n chainId?: number;\n /** Hex-encoded private key (with or without 0x prefix) */\n privateKey?: string;\n /** SigningWalletAdapter — the key never leaves the adapter */\n wallet?: SigningWalletAdapter;\n}\n\n/**\n * Sign an HTTP request per ERC-8128 with a raw private key.\n *\n * Thin wrapper over {@link signRequestWithSigner} using an ethers Wallet.\n *\n * @returns Headers to merge into the request (Signature, Signature-Input, Content-Digest).\n */\nexport async function signRequest(options: SignRequestOptions): Promise<SignatureHeaders> {\n const key = options.privateKey.startsWith('0x')\n ? options.privateKey\n : `0x${options.privateKey}`;\n const wallet = new ethers.Wallet(key);\n return signRequestWithSigner({\n address: wallet.address,\n signMessage: (signatureBase) => wallet.signMessage(signatureBase),\n method: options.method,\n url: options.url,\n body: options.body,\n nonce: options.nonce,\n chainId: options.chainId,\n label: options.label,\n validitySec: options.validitySec,\n });\n}\n\n/**\n * Sign an HTTP request per ERC-8128 with a {@link SigningWalletAdapter}.\n *\n * Only `getAddress()` and `signMessage()` (EIP-191 personal_sign) are used —\n * the private key never leaves the adapter. Works with EnvKeyAdapter,\n * OWSWalletAdapter, or any custom adapter.\n *\n * @returns Headers to merge into the request (Signature, Signature-Input, Content-Digest).\n */\nexport async function signRequestWithWallet(\n wallet: SigningWalletAdapter,\n options: ERC8128RequestOptions\n): Promise<SignatureHeaders> {\n return signRequestWithSigner({\n ...options,\n address: wallet.getAddress(),\n signMessage: (signatureBase) => wallet.signMessage(signatureBase),\n });\n}\n\n/**\n * Sign an HTTP request per ERC-8128 with a signing callback.\n *\n * For signers that never expose the raw key (OWS vault, browser wallets):\n * the callback receives the RFC 9421 signature base and returns the EIP-191\n * personal_sign signature as 0x-hex.\n *\n * @returns Headers to merge into the request (Signature, Signature-Input, Content-Digest).\n */\nexport async function signRequestWithSigner(\n options: SignRequestWithSignerOptions\n): Promise<SignatureHeaders> {\n const {\n address: rawAddress,\n signMessage,\n method,\n url,\n body,\n nonce,\n chainId = DEFAULT_CHAIN_ID,\n label = DEFAULT_LABEL,\n validitySec = DEFAULT_VALIDITY_SEC,\n } = options;\n\n // CRITICAL: lowercase — checksummed keyid caused the v9.x silent-auth INC.\n const address = rawAddress.toLowerCase();\n\n const parsed = new URL(url);\n const authority = parsed.host;\n const path = parsed.pathname || '/';\n const query = parsed.search || undefined; // includes '?' prefix\n\n const now = Math.floor(Date.now() / 1000);\n const created = now;\n const expires = now + validitySec;\n\n const keyid = `erc8128:${chainId}:${address}`;\n\n // Determine covered components\n const covered: string[] = ['@method', '@authority', '@path'];\n if (query) {\n covered.push('@query');\n }\n\n const headers: SignatureHeaders = {\n Signature: '',\n 'Signature-Input': '',\n };\n\n if (body !== undefined) {\n const digest = computeContentDigest(body);\n headers['Content-Digest'] = digest;\n covered.push('content-digest');\n }\n\n // Build signature base\n const sigBase = buildSignatureBase({\n method,\n authority,\n path,\n query,\n contentDigest: headers['Content-Digest'],\n covered,\n created,\n expires,\n nonce,\n keyid,\n });\n\n // EIP-191 personal_sign via the callback — the key stays in the signer\n const sigHex = await signMessage(sigBase);\n\n // Encode signature as base64 (RFC 8941 byte sequence)\n const sigBytes = ethers.getBytes(sigHex.startsWith('0x') ? sigHex : `0x${sigHex}`);\n const sigB64 = ethers.encodeBase64(sigBytes);\n\n // Build headers\n const sigParams = buildSignatureParams({ covered, created, expires, nonce, keyid });\n\n headers.Signature = `${label}=:${sigB64}:`;\n headers['Signature-Input'] = `${label}=${sigParams}`;\n\n return headers;\n}\n\n/**\n * Fetch a fresh single-use nonce from the server.\n *\n * @param apiBase - Origin of the API (e.g. \"https://api.execution.market\")\n * — the `/api/v1/auth/erc8128/nonce` path is appended here.\n * @param timeoutMs - Request timeout in milliseconds (default: 10000).\n * @returns The nonce value (single-use, short TTL — fetch one per request).\n */\nexport async function fetchNonce(apiBase: string, timeoutMs = 10000): Promise<string> {\n const url = `${apiBase.replace(/\\/$/, '')}/api/v1/auth/erc8128/nonce`;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n\n try {\n const resp = await fetch(url, { signal: controller.signal });\n if (!resp.ok) {\n throw new Error(`Failed to fetch nonce: ${resp.status} ${resp.statusText}`);\n }\n const data = (await resp.json()) as { nonce: string };\n return data.nonce;\n } finally {\n clearTimeout(timer);\n }\n}\n\n/**\n * Create a fetch wrapper that auto-signs requests with ERC-8128\n * (nonce fetch + signature headers on every call).\n *\n * @example\n * ```typescript\n * const signedFetch = createSignedFetch({\n * wallet: new EnvKeyAdapter(), // or privateKey: '...'\n * apiBase: 'https://api.execution.market',\n * chainId: 8453,\n * });\n *\n * const resp = await signedFetch('/api/v1/tasks', {\n * method: 'POST',\n * body: JSON.stringify({ title: 'test' }),\n * });\n * ```\n */\nexport function createSignedFetch(config: CreateSignedFetchConfig) {\n const { apiBase, chainId, privateKey, wallet } = config;\n\n if (!privateKey && !wallet) {\n throw new X402Error(\n 'createSignedFetch requires a signer: pass privateKey or wallet.',\n 'WALLET_NOT_CONNECTED'\n );\n }\n\n return async (path: string, init?: RequestInit): Promise<Response> => {\n const url = `${apiBase.replace(/\\/$/, '')}${path}`;\n const method = (init?.method || 'GET').toUpperCase();\n const body = init?.body ? String(init.body) : undefined;\n\n // Fresh single-use nonce per request\n const nonce = await fetchNonce(apiBase);\n\n // Sign request\n const requestOptions: ERC8128RequestOptions = { method, url, body, nonce, chainId };\n const sigHeaders = wallet\n ? await signRequestWithWallet(wallet, requestOptions)\n : await signRequest({ ...requestOptions, privateKey: privateKey! });\n\n // Merge headers\n const headers = new Headers(init?.headers);\n headers.set('Signature', sigHeaders.Signature);\n headers.set('Signature-Input', sigHeaders['Signature-Input']);\n if (sigHeaders['Content-Digest']) {\n headers.set('Content-Digest', sigHeaders['Content-Digest']);\n }\n if (body) {\n headers.set('Content-Type', headers.get('Content-Type') || 'application/json');\n }\n\n return fetch(url, { ...init, headers, method });\n };\n}\n\n// ---------------------------------------------------------------------------\n// Signature-base construction (exported: browser / out-of-process signers\n// build the exact same base and sign it elsewhere)\n// ---------------------------------------------------------------------------\n\nfunction computeContentDigest(body: string): string {\n const hash = ethers.sha256(ethers.toUtf8Bytes(body));\n // hash is 0x-prefixed hex, convert to raw bytes then base64\n const b64 = ethers.encodeBase64(ethers.getBytes(hash));\n return `sha-256=:${b64}:`;\n}\n\nexport interface SignatureBaseParams {\n method: string;\n authority: string;\n path: string;\n query?: string;\n contentDigest?: string;\n covered: string[];\n created: number;\n expires: number;\n nonce?: string;\n keyid: string;\n}\n\n/**\n * Build the RFC 9421 signature base — the exact string that gets EIP-191\n * personal_signed. Exported so external signers (OWS, browser) can reproduce\n * it byte-for-byte; pinned by the F3-1 golden vectors.\n */\nexport function buildSignatureBase(params: SignatureBaseParams): string {\n const lines: string[] = [];\n\n for (const component of params.covered) {\n switch (component) {\n case '@method':\n lines.push(`\"@method\": ${params.method.toUpperCase()}`);\n break;\n case '@authority':\n lines.push(`\"@authority\": ${params.authority}`);\n break;\n case '@path':\n lines.push(`\"@path\": ${params.path}`);\n break;\n case '@query':\n lines.push(`\"@query\": ${params.query || '?'}`);\n break;\n case 'content-digest':\n lines.push(`\"content-digest\": ${params.contentDigest || ''}`);\n break;\n }\n }\n\n const sigParams = buildSignatureParams({\n covered: params.covered,\n created: params.created,\n expires: params.expires,\n nonce: params.nonce,\n keyid: params.keyid,\n });\n lines.push(`\"@signature-params\": ${sigParams}`);\n\n return lines.join('\\n');\n}\n\nexport interface SignatureParamsInput {\n covered: string[];\n created: number;\n expires: number;\n nonce?: string;\n keyid: string;\n}\n\n/**\n * Build the `@signature-params` value per RFC 9421, in the pinned order\n * `created;expires;nonce;keyid;alg` (F3-1).\n */\nexport function buildSignatureParams(params: SignatureParamsInput): string {\n const compStr = params.covered.map((c) => `\"${c}\"`).join(' ');\n const parts: string[] = [`(${compStr})`];\n parts.push(`created=${params.created}`);\n parts.push(`expires=${params.expires}`);\n if (params.nonce) {\n parts.push(`nonce=\"${params.nonce}\"`);\n }\n parts.push(`keyid=\"${params.keyid}\"`);\n parts.push(`alg=\"${ALG}\"`);\n return parts.join(';');\n}\n","/**\n * uvd-x402-sdk - Escrow Pre-Auth Builder (sign-on-assignment)\n *\n * Builds and signs the EIP-3009 `ReceiveWithAuthorization` that locks a\n * bounty in the x402r AuthCaptureEscrow, and packs it into the raw-JSON\n * `X-Payment-Auth` wrapper the Ultravioleta Facilitator's `/settle` expects.\n * Used by marketplaces built on the escrow rail (e.g. Execution Market's\n * universal escrow, ADR-002).\n *\n * >>> PROTOCOL CONSTRAINT <<<\n * The EIP-3009 nonce is `AuthCaptureEscrow.getHash(paymentInfo)` which\n * INCLUDES the receiver — the escrow signature can only be created AT\n * ASSIGNMENT, when the worker/payee is known. Never design flows that sign\n * an escrow auth before the receiver is chosen (\"stored pre-auth with late\n * receiver fill\" is on-chain unsound).\n *\n * Fail-loud policy: an incomplete network config, an unknown tier, a bounty\n * outside the on-chain deposit limit, a `maxFeeBps` that cannot cover the\n * operator's static fee, or a USDC domain that contradicts\n * {@link VERIFIED_USDC_DOMAINS} all throw instead of falling back — a silent\n * fallback would sign an EIP-3009 authorization with the WRONG EIP-712\n * domain (chainId + verifyingContract): a mismatched, wallet-draining auth.\n *\n * Wire format is pinned by golden vectors (`src/escrow-preauth.vectors.json`):\n * payer-zeroed raw-keccak nonce (`keccak(chainId, escrow,\n * keccak(PAYMENT_INFO_TYPEHASH, paymentInfo tuple with payer=0))`),\n * `ReceiveWithAuthorization` typed data, raw JSON (NOT base64) wrapper.\n * Byte-parity with the production references is enforced in\n * `src/escrow-preauth.test.ts`.\n *\n * @example Sign the escrow lock at assignment time\n * ```typescript\n * import { buildEscrowPreAuth, EnvKeyAdapter } from 'uvd-x402-sdk';\n *\n * // Server-published escrow config (e.g. GET /api/v1/h2a/payment-config\n * // on Execution Market — escrow_networks[network]).\n * const paymentAuth = await buildEscrowPreAuth(new EnvKeyAdapter(), {\n * networkConfig: config.escrow.networks.base,\n * payerWallet: '0xPublisher...',\n * workerWallet: '0xWorker...', // committed by the nonce\n * bountyAtomic: '100000', // $0.10 in 6-decimal USDC\n * reviewDeadlineSec: taskDeadlineEpoch,\n * });\n * // Send as the X-Payment-Auth header (raw JSON, NOT base64).\n * ```\n *\n * Reference implementations (kept in byte-parity via the shared vectors):\n * - Python: `em_plugin_sdk.escrow_signing.build_escrow_pre_auth`\n * (production reference, derived from `uvd_x402_sdk.advanced_escrow`)\n * - Browser (viem): Execution Market `dashboard/src/services/h2aSigning.ts`\n */\n\nimport { ethers } from 'ethers';\nimport { getChainByName } from './chains';\nimport { X402Error } from './types';\nimport {\n needsAccountWrap,\n replaySafeTypedData,\n resolveDelegation,\n wrapSignature,\n type DelegationResolver,\n} from './erc7702.js';\n\nconst ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';\n\nconst USDC_DECIMALS = 6;\n\n/** AuthCaptureEscrow deposit condition: $100 max per deposit. */\nexport const ESCROW_DEPOSIT_LIMIT_USD = 100;\n\n/**\n * StaticFeeCalculator: canonical 13% flat fee. The signed maxFeeBps MUST\n * cover it or the on-chain authorize reverts (`FeeBoundsIncompatible`) — the\n * guard runs on the way IN, so a bound that is too low never opens the escrow\n * at all. It is not a way to pay less.\n *\n * This is a CEILING TO PLAN AGAINST, not a reading of any one deployment. The\n * operator fee is an immutable of each PaymentOperator instance, chosen from\n * `OperatorConfig.feeCalculator` when the factory deploys it, so two operators\n * on the same chain can charge differently and neither is knowable from here.\n *\n * Measured 2026-09-05: every `operator` address in {@link ESCROW_CONTRACTS} that\n * answered is the PaymentOperatorFactory, not a deployed operator — it exposes\n * `ESCROW()` and `operators(bytes32)` and reverts on `FEE_CALCULATOR()`,\n * `FEE_RECIPIENT()` and `release(...)`. Confirmed on Base mainnet, Base Sepolia\n * and Arbitrum, and matched by x402-rs `docs/X402R_MULTICHAIN_DEPLOYMENT.md`,\n * which labels those same addresses \"PaymentOperatorFactory\".\n *\n * cast call 0x3D0837fF8Ea36F417261577b9BA568400A840260 \\\n * \"ESCROW()(address)\" --rpc-url https://mainnet.base.org\n * # 0xb9488351E48b23D798f24e8174514F28B741Eb4f (factory immutable)\n * cast call 0x3D0837fF8Ea36F417261577b9BA568400A840260 \\\n * \"FEE_CALCULATOR()(address)\" --rpc-url https://mainnet.base.org\n * # execution reverted (operator-only getter)\n *\n * So read the fee off the operator you were actually given — the marketplace\n * publishes it in {@link EscrowNetworkConfig} — and pass `max_fee_bps` when it\n * differs. This constant is only the default bound.\n */\nexport const OPERATOR_FEE_BPS = 1300;\n\n/**\n * Hard cap the shared ProtocolFeeConfig puts on the PROTOCOL's slice, mirrored\n * from `ProtocolFeeConfig.MAX_PROTOCOL_FEE_BPS` (x402-rs\n * `contracts/src/plugins/fees/ProtocolFeeConfig.sol`). `getProtocolFeeBps`\n * clamps to it, so no deployment can ever charge more than this on top of the\n * operator's own fee.\n *\n * Measured on Base mainnet 2026-09-05 against the ProtocolFeeConfig the SDK\n * ships for chain 8453 (`0x59314674BAbb1a24Eb2704468a9cCdD50668a1C6`):\n *\n * cast call 0x59314674BAbb1a24Eb2704468a9cCdD50668a1C6 \\\n * \"MAX_PROTOCOL_FEE_BPS()(uint256)\" --rpc-url https://mainnet.base.org\n * # 500\n * cast call 0x59314674BAbb1a24Eb2704468a9cCdD50668a1C6 \\\n * \"calculator()(address)\" --rpc-url https://mainnet.base.org\n * # 0x0000000000000000000000000000000000000000 -> protocol fee is 0 today\n */\nexport const MAX_PROTOCOL_FEE_BPS = 500;\n\n/**\n * Fee-bound defaults for optional config keys only — never for the domain.\n *\n * `PaymentOperator` charges `protocolFee + operatorFee` and compares that SUM\n * against the signed `maxFeeBps` (`_calculateFees`, then the guard in\n * `authorize`/`charge`). So the only bound guaranteed never to revert is the\n * canonical operator fee plus the protocol's hard cap — derived here rather\n * than re-typed, so the two can never drift apart.\n */\nexport const DEFAULT_MIN_FEE_BPS = 0;\nexport const DEFAULT_MAX_FEE_BPS = OPERATOR_FEE_BPS + MAX_PROTOCOL_FEE_BPS;\n\n/**\n * EIP-712 type for the escrow flow. The token collector pulls the funds, so\n * the scheme is ReceiveWithAuthorization (not TransferWithAuthorization).\n */\nconst RECEIVE_WITH_AUTHORIZATION_TYPES = {\n ReceiveWithAuthorization: [\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};\n\n/**\n * ABI type of the paymentInfo tuple — mirrors AdvancedEscrowClient /\n * em_plugin_sdk.escrow_signing (unnamed components, positional encoding).\n */\nconst PAYMENT_INFO_TUPLE =\n 'tuple(address,address,address,address,uint120,uint48,uint48,uint48,uint16,uint16,address,uint256)';\n\n/** Per-tier expiry windows in seconds, relative to now() at signing. */\nexport interface EscrowTierWindows {\n pre: number;\n auth: number;\n refund: number;\n}\n\n/** Canonical fallback — mirrors uvd_x402_sdk TIER_TIMINGS. */\nexport const ESCROW_TIER_WINDOWS: Record<string, EscrowTierWindows> = {\n micro: { pre: 3600, auth: 7200, refund: 86400 },\n standard: { pre: 7200, auth: 86400, refund: 604800 },\n};\n\n/**\n * Human review windows. Agents approve in seconds, so the short SDK tier\n * windows (micro auth = 2h) work for them. A HUMAN publisher reviews on\n * their own schedule — if authorizationExpiry passes before approval, the\n * on-chain release REVERTS (AfterAuthorizationExpiry). So release/refund\n * windows are extended to comfortably outlast the deadline + review buffer.\n */\nexport const REVIEW_WINDOW_SEC = 7 * 24 * 3600; // >=7 days to approve after the deadline\nexport const REFUND_WINDOW_SEC = 7 * 24 * 3600; // +7 days to refund after that\n\n/**\n * One network's escrow parameters, as published by the marketplace server\n * (e.g. Execution Market's `GET /api/v1/h2a/payment-config` →\n * `escrow_networks[network]`). Snake_case on purpose: pass the server's\n * JSON straight through so the SDK builds the paymentInfo EXACTLY like the\n * production reference.\n */\nexport interface EscrowNetworkConfig {\n chain_id: number;\n operator: string;\n escrow: string;\n token_collector: string;\n usdc: string;\n usdc_domain_name: string;\n usdc_domain_version: string;\n /** 32-byte hex PAYMENT_INFO_TYPEHASH (with or without 0x prefix). */\n payment_info_typehash: string;\n /** Server-published tier windows; falls back to ESCROW_TIER_WINDOWS. */\n tiers?: Record<string, EscrowTierWindows>;\n min_fee_bps?: number;\n max_fee_bps?: number;\n}\n\n/** paymentInfo exactly as serialized in the X-Payment-Auth wrapper. */\nexport interface EscrowPaymentInfo {\n operator: string;\n receiver: string;\n token: string;\n /** Atomic units, as string (uint120 on-chain). */\n maxAmount: string;\n preApprovalExpiry: number;\n authorizationExpiry: number;\n refundExpiry: number;\n minFeeBps: number;\n maxFeeBps: number;\n feeReceiver: string;\n /** 32-byte hex. */\n salt: string;\n}\n\n/**\n * USDC EIP-712 domains VERIFIED ON-CHAIN, per chain ID.\n *\n * `usdc_domain_name` / `usdc_domain_version` arrive with the server's config,\n * and they ARE the domain the authorization is signed under: a wrong pair\n * produces an authorization that never settles. For a chain in this table,\n * {@link buildEscrowPreAuth} refuses a config whose pair differs. A chain that\n * is not in the table is signed exactly as before.\n *\n * Only chains whose domain this SDK checked against the token's own\n * `DOMAIN_SEPARATOR()` are listed: Arc and Arc Testnet\n * (`src/fixtures/arc-escrow-d.rpc.json`, pinned by\n * `src/backend/escrow-arc-d.test.ts`). The values come from the chain\n * registry (`src/chains`), not typed again here. Mirrors the refusal policy of\n * the Python SDK's `escrow_signing.VERIFIED_USDC_DOMAINS`.\n */\nexport const VERIFIED_USDC_DOMAINS: Record<number, { name: string; version: string }> = Object.fromEntries(\n (['arc', 'arc-testnet'] as const).map((network) => {\n const chain = getChainByName(network);\n if (!chain) throw new Error(`The chain registry has no '${network}'.`);\n return [chain.chainId, { name: chain.usdc.name, version: chain.usdc.version }];\n })\n);\n\nconst REQUIRED_NETWORK_KEYS: Array<keyof EscrowNetworkConfig> = [\n 'chain_id',\n 'operator',\n 'escrow',\n 'token_collector',\n 'usdc',\n 'usdc_domain_name',\n 'usdc_domain_version',\n 'payment_info_typehash',\n];\n\nfunction hex32(value: string): string {\n return value.startsWith('0x') ? value : `0x${value}`;\n}\n\n/** 32 random bytes as 0x-hex (WebCrypto when available, ethers otherwise). */\nfunction randomSalt(): string {\n const webCrypto = (globalThis as { crypto?: Crypto }).crypto;\n if (webCrypto?.getRandomValues) {\n const bytes = new Uint8Array(32);\n webCrypto.getRandomValues(bytes);\n return ethers.hexlify(bytes);\n }\n return ethers.hexlify(ethers.randomBytes(32));\n}\n\n/**\n * Compute the escrow EIP-3009 nonce = `AuthCaptureEscrow.getHash(paymentInfo)`.\n *\n * `keccak(chainId, escrow, keccak(PAYMENT_INFO_TYPEHASH, paymentInfo tuple\n * with payer=0))` — the payer slot is zeroed for the payer-agnostic hash;\n * the RECEIVER is part of the hash, which is why the signature commits to\n * the chosen worker. Port of `AdvancedEscrowClient._compute_nonce` /\n * `em_plugin_sdk.escrow_signing.compute_escrow_nonce`.\n *\n * @param chainId - EVM chain id.\n * @param escrowAddress - AuthCaptureEscrow contract on that chain.\n * @param paymentInfoTypehash - 32-byte hex typehash from the server config.\n * @param pi - paymentInfo exactly as serialized on the wire.\n * @returns 32-byte hex nonce (0x-prefixed, lowercase).\n */\nexport function computeEscrowNonce(\n chainId: number,\n escrowAddress: string,\n paymentInfoTypehash: string,\n pi: EscrowPaymentInfo\n): string {\n const coder = ethers.AbiCoder.defaultAbiCoder();\n\n const piTuple = [\n ethers.getAddress(pi.operator),\n ZERO_ADDRESS, // payer = 0 for the payer-agnostic hash\n ethers.getAddress(pi.receiver),\n ethers.getAddress(pi.token),\n BigInt(pi.maxAmount), // uint120\n pi.preApprovalExpiry, // uint48\n pi.authorizationExpiry, // uint48\n pi.refundExpiry, // uint48\n pi.minFeeBps, // uint16\n pi.maxFeeBps, // uint16\n ethers.getAddress(pi.feeReceiver),\n BigInt(hex32(pi.salt)), // uint256\n ];\n\n const piHash = ethers.keccak256(\n coder.encode(['bytes32', PAYMENT_INFO_TUPLE], [hex32(paymentInfoTypehash), piTuple])\n );\n return ethers.keccak256(\n coder.encode(\n ['uint256', 'address', 'bytes32'],\n [chainId, ethers.getAddress(escrowAddress), piHash]\n )\n );\n}\n\n/**\n * Minimal signer for {@link buildEscrowPreAuth}: EIP-712 typed-data signing\n * over the full typed-data JSON string (`domain`, `types`, `primaryType`,\n * `message`) — the same contract as `SigningWalletAdapter.signTypedData`,\n * so every adapter (EnvKeyAdapter, OWSWalletAdapter, custom) satisfies it\n * structurally. Browser wallets can wrap their own signTypedData in this\n * shape; the key never leaves the signer.\n */\nexport interface EscrowPreAuthSigner {\n signTypedData(typedData: string): Promise<{ signature: string }>;\n}\n\nexport interface EscrowPreAuthParams {\n /** Network escrow config as published by the marketplace server. */\n networkConfig: EscrowNetworkConfig;\n /**\n * Publisher wallet (payer). Not checked against the signer's address —\n * payer binding is enforced on-chain and by the backend, not here.\n */\n payerWallet: string;\n /** Chosen worker's wallet (escrow receiver — committed by the nonce). */\n workerWallet: string;\n /** Bounty in atomic units (6-decimal USDC). */\n bountyAtomic: string | bigint;\n /** Expiry tier; windows come from config when present. Default 'micro'. */\n tier?: string;\n /**\n * Task deadline (epoch seconds). The release/refund windows are extended\n * to outlast it + a review buffer so a human publisher can still approve\n * after the worker delivers. When omitted, falls back to now()-based\n * windows.\n */\n reviewDeadlineSec?: number;\n /**\n * On-chain deposit limit in USD (AuthCaptureEscrow deposit condition).\n * Default {@link ESCROW_DEPOSIT_LIMIT_USD}; override only when the server\n * publishes a different limit.\n */\n depositLimitUsd?: number;\n /**\n * How to find out whether `payerWallet` is EIP-7702-delegated, and to what.\n *\n * Optional, and its absence is honest rather than convenient: with no resolver\n * the verdict is UNKNOWN and this function signs the ordinary way, exactly as\n * it did before. Pass one — {@link rpcDelegationResolver} or your own — as soon\n * as your payers can be delegated accounts, because a delegated payer signing\n * the wrong dialect produces an authorization that **cannot settle on-chain**\n * and only fails at lock time.\n *\n * When a resolver IS supplied and it reaches no verdict, this throws instead of\n * guessing: an unreadable chain is not a \"not delegated\" answer.\n */\n delegationResolver?: DelegationResolver;\n}\n\n/**\n * Build + sign the escrow lock authorization AT ASSIGNMENT time and return\n * the raw JSON string for the `X-Payment-Auth` header (NOT base64 — the\n * backend relays it verbatim to the Facilitator `/settle`). Mirror of\n * `AdvancedEscrowClient.authorize()`'s /settle payload and of\n * `em_plugin_sdk.escrow_signing.build_escrow_pre_auth`.\n *\n * @throws {X402Error} `INVALID_CONFIG` on an incomplete network config,\n * unknown tier, a `maxFeeBps` that cannot cover the operator's static\n * fee, or a USDC domain that differs from {@link VERIFIED_USDC_DOMAINS};\n * `INVALID_AMOUNT` on a bounty outside (0, deposit limit].\n */\nexport async function buildEscrowPreAuth(\n wallet: EscrowPreAuthSigner,\n params: EscrowPreAuthParams\n): Promise<string> {\n const cfg = params.networkConfig;\n\n const missing = REQUIRED_NETWORK_KEYS.filter((key) => !cfg[key]);\n if (missing.length > 0) {\n throw new X402Error(\n `Incomplete escrow network config (missing ${missing.join(', ')}) — ` +\n 'refusing to sign an EIP-3009 authorization with a mismatched domain.',\n 'INVALID_CONFIG'\n );\n }\n\n const verified = VERIFIED_USDC_DOMAINS[cfg.chain_id];\n if (\n verified &&\n (cfg.usdc_domain_name !== verified.name || cfg.usdc_domain_version !== verified.version)\n ) {\n throw new X402Error(\n `The escrow config gives chain ${cfg.chain_id} the USDC domain ` +\n `'${cfg.usdc_domain_name}' / '${cfg.usdc_domain_version}', but the token's on-chain ` +\n `domain is '${verified.name}' / '${verified.version}' — refusing to sign an ` +\n 'authorization that could never settle.',\n 'INVALID_CONFIG'\n );\n }\n\n const maxAmount = BigInt(params.bountyAtomic);\n if (maxAmount <= 0n) {\n throw new X402Error(\n `Bounty must be positive, got ${maxAmount} atomic units`,\n 'INVALID_AMOUNT'\n );\n }\n const depositLimitUsd = params.depositLimitUsd ?? ESCROW_DEPOSIT_LIMIT_USD;\n const depositLimitAtomic = BigInt(Math.round(depositLimitUsd * 10 ** USDC_DECIMALS));\n if (maxAmount > depositLimitAtomic) {\n throw new X402Error(\n `Bounty ${maxAmount} atomic units exceeds the on-chain escrow deposit ` +\n `limit ($${depositLimitUsd}).`,\n 'INVALID_AMOUNT'\n );\n }\n\n const minFeeBps = cfg.min_fee_bps ?? DEFAULT_MIN_FEE_BPS;\n const maxFeeBps = cfg.max_fee_bps ?? DEFAULT_MAX_FEE_BPS;\n if (maxFeeBps < OPERATOR_FEE_BPS) {\n throw new X402Error(\n `maxFeeBps=${maxFeeBps} cannot cover the operator's ${OPERATOR_FEE_BPS} ` +\n 'bps static fee — the on-chain release would revert.',\n 'INVALID_CONFIG'\n );\n }\n\n const tierKey = params.tier ?? 'micro';\n const windows = cfg.tiers?.[tierKey] ?? ESCROW_TIER_WINDOWS[tierKey];\n if (!windows) {\n const known = [...new Set([...Object.keys(cfg.tiers ?? {}), ...Object.keys(ESCROW_TIER_WINDOWS)])].sort();\n throw new X402Error(\n `Unknown escrow tier '${tierKey}' — known tiers: ${known.join(', ')}`,\n 'INVALID_CONFIG'\n );\n }\n\n const now = Math.floor(Date.now() / 1000);\n\n // The release window must outlast the human review. Base it on the task\n // deadline (the worker delivers near it) plus a generous buffer, and never\n // shorter than the SDK tier window. preApprovalExpiry stays short — the\n // lock executes immediately at assignment.\n const reviewBase = Math.max(now, params.reviewDeadlineSec ?? now);\n const authExpiry = Math.max(now + windows.auth, reviewBase + REVIEW_WINDOW_SEC);\n const refundExpiry = Math.max(now + windows.refund, authExpiry + REFUND_WINDOW_SEC);\n\n const paymentInfo: EscrowPaymentInfo = {\n operator: ethers.getAddress(cfg.operator),\n receiver: ethers.getAddress(params.workerWallet),\n token: ethers.getAddress(cfg.usdc),\n maxAmount: maxAmount.toString(),\n preApprovalExpiry: now + windows.pre,\n authorizationExpiry: authExpiry,\n refundExpiry: refundExpiry,\n minFeeBps: minFeeBps,\n maxFeeBps: maxFeeBps,\n feeReceiver: ethers.getAddress(cfg.operator),\n salt: randomSalt(),\n };\n\n const nonce = computeEscrowNonce(\n cfg.chain_id,\n cfg.escrow,\n cfg.payment_info_typehash,\n paymentInfo\n );\n\n const payer = ethers.getAddress(params.payerWallet);\n const tokenCollector = ethers.getAddress(cfg.token_collector);\n\n // String-valued message fields: the typed data travels as JSON to the\n // adapter (SigningWalletAdapter.signTypedData contract), and ethers\n // accepts decimal strings for uint256 / 0x-hex for bytes32.\n const typedData = {\n domain: {\n name: cfg.usdc_domain_name,\n version: cfg.usdc_domain_version,\n chainId: cfg.chain_id,\n verifyingContract: ethers.getAddress(cfg.usdc),\n },\n types: RECEIVE_WITH_AUTHORIZATION_TYPES,\n primaryType: 'ReceiveWithAuthorization',\n message: {\n from: payer,\n to: tokenCollector,\n value: maxAmount.toString(),\n validAfter: '0',\n validBefore: String(paymentInfo.preApprovalExpiry),\n nonce: nonce,\n },\n };\n\n // ── EIP-7702: a DELEGATED payer cannot settle a raw ECDSA authorization ──\n //\n // Once the payer's EOA carries code, USDC validates via ERC-1271 only and raw\n // ECDSA reverts (0x151d90fe) — the lock fails on-chain. Measured in production\n // 2026-07-31: 14 of 14 delegated payers failed; the one plain EOA locked fine.\n //\n // THREE STATES, and the third is the one that matters: an UNKNOWN delegation is\n // NOT \"not delegated\". Collapsing it to false is exactly how the original bug\n // survived eight days — signing raw for an account that can never settle it,\n // silently.\n //\n // AND THE DIALECT DEPENDS ON THE TARGET. \"Delegated\" is not one signature\n // scheme: the account-envelope wrap is Alchemy-SMA-specific. A delegate that\n // validates plain ECDSA through ERC-1271 — Execution Market's FeedbackDelegate,\n // which every account that has rated through the facilitator's rail is pointed\n // at — needs the ORDINARY signature. Wrapping it is as unsettleable as signing\n // raw for an SMA.\n const { delegated, target } = await resolveDelegation(\n payer,\n `eip155:${cfg.chain_id}`,\n params.delegationResolver\n );\n if (delegated === null && params.delegationResolver) {\n throw new X402Error(\n `Could not determine whether ${payer} is EIP-7702-delegated on chain ` +\n `${cfg.chain_id} (the resolver gave no verdict) — refusing to sign an ` +\n 'escrow authorization blindly: the wrong dialect is unsettleable ' +\n 'on-chain and the failure only shows up at lock time. Retry when the ' +\n 'chain is readable.',\n 'INVALID_CONFIG'\n );\n }\n\n let signature: string;\n if (delegated && (needsAccountWrap(target) || target === null)) {\n // SMA-wrap: the known Alchemy account, OR a legacy boolean-only resolver that\n // could not name the target — for which we keep the conservative behaviour\n // rather than silently changing what such callers got. A resolver that\n // returns the target lands any non-SMA delegate in the plain branch below.\n const innerDigest = ethers.TypedDataEncoder.hash(\n typedData.domain,\n typedData.types,\n typedData.message\n );\n const replaySafe = replaySafeTypedData(innerDigest, cfg.chain_id, payer);\n const wrapped = await wallet.signTypedData(\n JSON.stringify({ ...replaySafe, primaryType: 'ReplaySafeHash' })\n );\n if (!wrapped?.signature) {\n throw new X402Error(\n 'The wallet returned no signature for the replay-safe wrap — refusing ' +\n 'to build an unsettleable authorization.',\n 'INVALID_CONFIG'\n );\n }\n signature = wrapSignature(wrapped.signature);\n } else {\n // Plain EOA, unknown-with-no-resolver, or a delegate that takes ordinary\n // ECDSA (FeedbackDelegate and the standard 1271 smart-EOA pattern).\n signature = (await wallet.signTypedData(JSON.stringify(typedData))).signature;\n }\n\n // Raw JSON (NOT base64): the backend relays this verbatim to the\n // Facilitator /settle after validating payer/amount/receiver.\n return JSON.stringify({\n x402Version: 2,\n scheme: 'escrow',\n payload: {\n authorization: {\n from: payer,\n to: tokenCollector,\n value: maxAmount.toString(),\n validAfter: '0',\n validBefore: String(paymentInfo.preApprovalExpiry),\n nonce: nonce,\n },\n signature: signature,\n paymentInfo: paymentInfo,\n },\n paymentRequirements: {\n scheme: 'escrow',\n network: `eip155:${cfg.chain_id}`,\n },\n });\n}\n","/**\n * EIP-7702: make a DELEGATED EOA's EIP-3009 signature settle again.\n *\n * **THE PROBLEM.** A gasless-wallet provider's first sponsored operation on a\n * chain may delegate the user's EOA (EIP-7702) to a smart-account\n * implementation — Alchemy's `SemiModularAccount7702` (`0x69007702…`) is the one\n * seen in the wild. From then on the address HAS code, so Circle's USDC (and any\n * `SignatureChecker` consumer) verifies signatures via **ERC-1271 only**. A raw\n * ECDSA authorization, however perfect, is rejected: `0x151d90fe`. The account is\n * not broken and the signature is not wrong — they simply no longer speak the\n * same dialect.\n *\n * Consequence for anything x402: a delegated payer's `transferWithAuthorization`\n * / `receiveWithAuthorization` becomes **unsettleable on-chain**, so direct x402\n * payments AND marketplace escrow locks both fail. Measured in production\n * 2026-07-31: 14 of 14 delegated agents failed their escrow lock; the one\n * non-delegated agent locked fine. The failure is silent in the worst way — the\n * sellers looked broken and they were correct.\n *\n * **THE FIX** (verified on-chain; the wallet provider needs to change nothing).\n * That account's `isValidSignature` DOES accept the EOA's own ECDSA — it just\n * wants it in the account's envelope. Two steps, both provable against the\n * verified source (`SemiModularAccountBase._exec1271Validation` +\n * `SparseCalldataSegmentLib`):\n *\n * 1. The account does not check `hash` directly; it checks a REPLAY-SAFE hash =\n * EIP-712 over the account's OWN domain\n * `EIP712Domain(uint256 chainId, address verifyingContract=account)` with\n * struct `ReplaySafeHash(bytes32 hash)`. Sign THAT, not the transfer digest.\n * 2. Wrap the 65-byte signature with the account's fallback-validation locator:\n * `0x00 00000000` (validation type 0, entity id 0 = FALLBACK_VALIDATION_ID)\n * `FF` (RESERVED_VALIDATION_DATA_INDEX, the final segment) `00`\n * (SignatureType.EOA).\n *\n * Because step 1 is still an ordinary typed-data signature, a REMOTE signer (a\n * delegated agentic wallet) can produce it: the private key is never needed\n * locally.\n *\n * **THE WRAP IS DELEGATE-SPECIFIC, NOT \"delegated == wrap\".** This is the part\n * that bit us on 2026-08-25, and it is why this module exists in TypeScript at\n * all: the moment a worker rates an agent through the facilitator's EIP-7702\n * feedback rail, their EOA becomes delegated to Execution Market's\n * `FeedbackDelegate` — which validates PLAIN ECDSA\n * (`ECDSA.recover(hash, sig) == address(this)`). Wrapping that signature makes it\n * invalid, so *the act of rating would break the rater's next payment*. Same\n * silent-at-lock-time failure the wrap was built to fix, now caused by\n * over-applying it.\n *\n * **DETECTION IS INJECTABLE, ON PURPOSE.** Knowing whether an address is\n * delegated needs one `eth_getCode` — a chain read, and this SDK does not own an\n * RPC policy. So detection is a callable you pass in ({@link DelegationResolver}).\n * {@link rpcDelegationResolver} ships a default over `fetch`; a caller with its\n * own endpoints, proxy or rotation passes its own.\n *\n * **THE THIRD STATE IS LOAD-BEARING.** A resolver returns `true` / `false` /\n * **`null` = could not tell**. `null` must never collapse to \"not delegated\":\n * that is exactly how the original bug survived eight days — the resolver failed,\n * returned nothing, and the caller's `if (delegated)` read it as falsy and signed\n * raw. **An unreadable answer is not a negative answer.**\n *\n * Port of `uvd_x402_sdk.erc7702` (Python). Keep the two in step: they are the\n * same protocol seen from two languages, and a divergence here is a signature\n * that cannot settle.\n */\n\n/** EIP-7702 delegation designator. */\nexport const DELEGATE_PREFIX = 'ef0100';\n\n/**\n * Delegate targets whose ERC-1271 needs the account-envelope wrap.\n *\n * Only a known Alchemy SMA implementation needs it. Every other delegate signs\n * PLAIN (the standard 1271 \"smart-EOA\" pattern accepts the EOA's own ECDSA), and\n * if some exotic future delegate needs a third dialect it fails VISIBLY at lock\n * time — never silently.\n *\n * Notably NOT here: Execution Market's `FeedbackDelegate` (all nine deploys). An\n * account that has rated through the facilitator's rail is delegated to it and\n * must sign plain.\n */\nexport const SMA_WRAP_TARGETS: readonly string[] = [\n '0x69007702764179f14f51cdce752f4f775d74e139', // Alchemy SemiModularAccount7702\n];\n\n/**\n * `true` only when this delegate target needs the account-envelope wrap.\n *\n * A plain EOA (`target` null/undefined) and any other delegate — FeedbackDelegate,\n * a standard 1271 smart-EOA — do NOT: they take the ordinary ECDSA signature.\n */\nexport function needsAccountWrap(target: string | null | undefined): boolean {\n return !!target && SMA_WRAP_TARGETS.includes(target.toLowerCase());\n}\n\n/**\n * Account fallback-validation locator + final-segment marker + EOA signature type.\n *\n * - `0x00 00000000` — validation type 0, entity id 0 (FALLBACK_VALIDATION_LOOKUP_KEY)\n * - `0xFF` — RESERVED_VALIDATION_DATA_INDEX (getFinalSegment)\n * - `0x00` — SignatureType.EOA\n */\nconst WRAP_PREFIX = '00000000' + '00' + 'ff' + '00';\n\n/**\n * The delegate target this EOA's EIP-7702 code points at, or `null`.\n *\n * `null` for a plain EOA, for non-7702 code, and for anything unparseable — the\n * caller confirms the implementation before applying the wrap.\n */\nexport function delegateTarget(code: string | null | undefined): string | null {\n if (!code) return null;\n const h = (code.startsWith('0x') ? code.slice(2) : code).toLowerCase();\n if (!h.startsWith(DELEGATE_PREFIX) || h.length < 46) return null;\n return `0x${h.slice(6, 46)}`;\n}\n\n/** Wrap a 65-byte ECDSA signature in the account's fallback-EOA envelope. */\nexport function wrapSignature(innerSignature: string): string {\n const s = innerSignature.startsWith('0x') ? innerSignature.slice(2) : innerSignature;\n return `0x${WRAP_PREFIX}${s}`;\n}\n\n/**\n * The typed data whose signature the delegated account accepts.\n *\n * The domain is the ACCOUNT's own — `chainId` + `verifyingContract=account`, the\n * two fields its typehash declares — and the struct is\n * `ReplaySafeHash(bytes32 hash)` over the inner EIP-3009 digest. Signing THIS,\n * not the digest, is what validates.\n */\nexport function replaySafeTypedData(\n innerDigest: string,\n chainId: number,\n account: string\n): { domain: Record<string, unknown>; types: Record<string, unknown>; message: Record<string, unknown> } {\n return {\n domain: { chainId, verifyingContract: account },\n types: { ReplaySafeHash: [{ name: 'hash', type: 'bytes32' }] },\n message: { hash: innerDigest },\n };\n}\n\n/**\n * `(address, network) -> target | true | false | null`.\n *\n * Four answers, richer than a boolean on purpose: a resolver MAY return the\n * delegate **target address** (a string) instead of just `true` — that is what\n * lets the caller pick the right signing dialect (SMA wrap vs plain). `true` =\n * delegated, target unknown; `false` = not delegated; `null` = UNKNOWN\n * (unreadable chain), never \"no\".\n */\nexport type DelegationResolver = (\n address: string,\n network: string\n) => Promise<string | boolean | null> | (string | boolean | null);\n\n/**\n * A default resolver over plain JSON-RPC `eth_getCode`, using `fetch`.\n *\n * Rotates through `urls` and returns `null` when **every** endpoint failed: an\n * unreadable chain is not a \"not delegated\" verdict.\n *\n * A caller with its own RPC policy (a signed proxy, paid endpoints, per-chain\n * routing) should pass its own resolver instead; that is the whole point of the\n * injection.\n */\nexport function rpcDelegationResolver(\n urls: string | string[],\n timeoutMs = 6000\n): DelegationResolver {\n const endpoints = typeof urls === 'string' ? [urls] : [...urls];\n\n return async (address: string): Promise<string | boolean | null> => {\n const addr = (address || '').trim();\n if (!addr || endpoints.length === 0) return null;\n\n for (const url of endpoints) {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n try {\n const res = await fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n jsonrpc: '2.0',\n id: 1,\n method: 'eth_getCode',\n params: [addr.toLowerCase(), 'latest'],\n }),\n signal: controller.signal,\n });\n clearTimeout(timer);\n if (!res.ok) continue;\n const code = (await res.json())?.result;\n if (typeof code === 'string' && code.startsWith('0x')) {\n // Return the TARGET when delegated, so the caller can pick the signing\n // dialect; `false` for a plain EOA (readable, no delegation).\n return delegateTarget(code) ?? false;\n }\n } catch {\n clearTimeout(timer);\n // Rotate to the next endpoint. Exhausting them all is UNKNOWN, below.\n }\n }\n return null;\n };\n}\n\n/** `{ delegated, target }` for one address on one network. */\nexport interface DelegationVerdict {\n /** `null` = UNKNOWN. Never treat it as `false`. */\n delegated: boolean | null;\n /** The delegate implementation, when the resolver could name it. */\n target: string | null;\n}\n\n/**\n * Resolve one address's delegation on one network.\n *\n * - `{delegated: null, target: null}` — unknown (no resolver, or an unreadable\n * chain). NEVER \"no\".\n * - `{delegated: false, target: null}` — a plain EOA.\n * - `{delegated: true, target: '0x…'}` — delegated, and we know to WHAT (pick the\n * dialect from it).\n * - `{delegated: true, target: null}` — delegated, target unknown (a legacy\n * boolean-only resolver).\n */\nexport async function resolveDelegation(\n address: string,\n network: string,\n resolver?: DelegationResolver\n): Promise<DelegationVerdict> {\n if (!resolver) return { delegated: null, target: null };\n\n let v: string | boolean | null;\n try {\n v = await resolver(address, network);\n } catch {\n // A broken resolver is UNKNOWN, not a negative.\n return { delegated: null, target: null };\n }\n\n if (typeof v === 'string') {\n const t = v.trim();\n // Only a real 20-byte address counts as a target. A non-address string is\n // garbage, and garbage is UNKNOWN — never a verdict we sign on.\n if (/^0x[0-9a-fA-F]{40}$/.test(t)) return { delegated: true, target: t };\n return { delegated: null, target: null };\n }\n if (typeof v === 'boolean') return { delegated: v, target: null };\n return { delegated: null, target: null };\n}\n\n/**\n * `true` / `false` / `null` (**unknown**) for one address on one network.\n *\n * Without a resolver the answer is `null`, never `false`: \"nobody asked\" and \"the\n * address is a plain EOA\" are different facts and only one of them is safe to\n * sign on.\n */\nexport async function isDelegated(\n address: string,\n network: string,\n resolver?: DelegationResolver\n): Promise<boolean | null> {\n return (await resolveDelegation(address, network, resolver)).delegated;\n}\n","/**\n * uvd-x402-sdk - Signed lifecycle orders for `release` / `refundInEscrow`.\n *\n * Both actions move money that is ALREADY escrowed, so neither carries an\n * ERC-3009 signature: there is no transfer left to authorize. That left the\n * other half of the question open — who is entitled to ask for the move —\n * and the de-facto answer was \"whoever calls\". On 2026-08-30 a third party\n * probed exactly that: five calls with a fabricated `paymentInfo`, two of\n * them mined, gas spent.\n *\n * This module is the client half of the answer: an EIP-712 order signed by\n * the party the action belongs to, hung off `payload.lifecycleAuth`.\n *\n * >>> THE SIGNER IS INJECTED <<<\n * The SDK never reaches for a key on its own. Any adapter that can sign\n * typed data works — `EnvKeyAdapter` (server / CLI), `OWSWalletAdapter`, a\n * wagmi/viem wallet client in the browser ({@link wagmiLifecycleSigner}), a\n * KMS. In H2A/H2H the PAYER signs in their own browser with the same wallet\n * they paid with, and the marketplace merely transports the block.\n *\n * >>> TWO SHAPES, ONE ORDER <<<\n * `buildLifecycleAuth` does the whole ceremony in one call: it mints the\n * nonce and the deadline, signs through the injected adapter, and returns the\n * block. That is the server and the `wagmi` paths.\n *\n * A publisher's browser cannot use it. There the backend assembles the\n * document — nonce and deadline included — the browser signs whatever it was\n * handed, and gives back a signature and nothing else. That is\n * {@link buildLifecycleTypedData} on one side and\n * {@link lifecycleAuthFromSignature} on the other, and it produces the SAME\n * bytes as the one-call path for the same nonce and deadline, pinned in\n * `src/lifecycle-auth.test.ts`.\n *\n * Source of truth for the format is the facilitator, `x402-rs`\n * `src/payment_operator/lifecycle_auth.rs` (PR #21). The Python twin is\n * `uvd_x402_sdk.escrow_signing.build_lifecycle_auth` (0.78.0); the two must\n * produce byte-identical signatures, pinned here by the shared vector in\n * `src/lifecycle-auth.test.ts`.\n *\n * Facilitator rollout is by `ESCROW_LIFECYCLE_AUTH`: `off` (default, the\n * order is not looked at), `log` (verify when present, log the verdict,\n * never reject) and `enforce`. That is why `lifecycleSigner` is OPTIONAL\n * everywhere: without one, the request goes out byte-for-byte as before.\n *\n * @example Server-side (EnvKeyAdapter)\n * ```typescript\n * import { buildLifecycleAuth, EnvKeyAdapter } from 'uvd-x402-sdk';\n *\n * const auth = await buildLifecycleAuth({\n * action: 'release',\n * paymentInfo: pi, // the SAME camelCase object that is sent\n * payer: payerAddress, // payload.payer — NOT inside paymentInfo\n * amount: '1000000', // the SAME as payload.amount\n * chainId: 8453,\n * wallet: new EnvKeyAdapter(),\n * });\n * // -> payload.lifecycleAuth = auth\n * ```\n */\n\nimport { ethers } from 'ethers';\nimport { X402Error } from './types';\n\n// ============================================================================\n// CONSTANTS — mirrored from lifecycle_auth.rs, do not \"clean up\"\n// ============================================================================\n\n/**\n * EIP-712 domain. `chainId` is the payment network's; there is NO\n * `verifyingContract` because `paymentInfo.operator` already rides inside the\n * signed struct. Copied from `lifecycle_auth.rs:69-70` (DOMAIN_NAME /\n * DOMAIN_VERSION).\n */\nexport const LIFECYCLE_DOMAIN_NAME = 'x402 escrow lifecycle';\nexport const LIFECYCLE_DOMAIN_VERSION = '1';\n\n/**\n * The facilitator's `deadline` ceiling: 900 s (`lifecycle_auth.rs:64`,\n * `DEFAULT_MAX_DEADLINE_SECS`). A leaked order is not a standing permission.\n */\nexport const LIFECYCLE_MAX_DEADLINE_SECS = 900;\n\n/**\n * What we sign by default, leaving 300 s of headroom under the ceiling.\n * Signing the full 900 s is an order that a facilitator clock five seconds\n * behind already reads as `deadline_too_far`: the margin is not cosmetic, it\n * is what separates a valid order from a rejection the caller cannot explain.\n */\nexport const LIFECYCLE_DEFAULT_DEADLINE_SECS = 600;\n\n/** The two wire values, which are also what enters the signature. */\nexport const LIFECYCLE_ACTIONS = ['release', 'refundInEscrow'] as const;\n\nexport type LifecycleAction = (typeof LIFECYCLE_ACTIONS)[number];\n\n/**\n * The EIP-712 types. `PaymentInfo` is the AuthCaptureEscrow type string\n * VERBATIM — the same one this SDK already types for ERC-3009. The field\n * ORDER is part of the type hash: reordering it invalidates every order ever\n * issued. Exact mirror of `lifecycle_auth.rs:73-99`.\n */\nexport const LIFECYCLE_ORDER_TYPES: Record<string, Array<{ name: string; type: string }>> = {\n LifecycleOrder: [\n { name: 'action', type: 'string' },\n { name: 'amount', type: 'uint256' },\n { name: 'deadline', type: 'uint256' },\n { name: 'nonce', type: 'bytes32' },\n { name: 'paymentInfo', type: 'PaymentInfo' },\n ],\n PaymentInfo: [\n { name: 'operator', type: 'address' },\n { name: 'payer', type: 'address' },\n { name: 'receiver', type: 'address' },\n { name: 'token', type: 'address' },\n { name: 'maxAmount', type: 'uint120' },\n { name: 'preApprovalExpiry', type: 'uint48' },\n { name: 'authorizationExpiry', type: 'uint48' },\n { name: 'refundExpiry', type: 'uint48' },\n { name: 'minFeeBps', type: 'uint16' },\n { name: 'maxFeeBps', type: 'uint16' },\n { name: 'feeReceiver', type: 'address' },\n { name: 'salt', type: 'uint256' },\n ],\n};\n\n/**\n * The 11 keys the wire `paymentInfo` MUST carry. `payer` is not among them:\n * it travels as a sibling (`payload.payer`), not inside paymentInfo — that is\n * how the facilitator assembles it (`ContractPaymentInfo::from_lifecycle_payload`,\n * `types.rs:275-290`).\n */\nconst LIFECYCLE_PI_KEYS = [\n 'operator',\n 'receiver',\n 'token',\n 'maxAmount',\n 'preApprovalExpiry',\n 'authorizationExpiry',\n 'refundExpiry',\n 'minFeeBps',\n 'maxFeeBps',\n 'feeReceiver',\n 'salt',\n] as const;\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\n/** The wire `paymentInfo` of a lifecycle request (camelCase, `salt` in hex). */\nexport interface LifecyclePaymentInfo {\n operator: string;\n receiver: string;\n token: string;\n /** Atomic units (uint120 on-chain). */\n maxAmount: string | number | bigint;\n preApprovalExpiry: number | string;\n authorizationExpiry: number | string;\n refundExpiry: number | string;\n minFeeBps: number | string;\n maxFeeBps: number | string;\n feeReceiver: string;\n /** 32-byte hex on the wire; uint256 in the signature. */\n salt: string | number | bigint;\n}\n\n/**\n * Minimal signer for {@link buildLifecycleAuth}: an address plus EIP-712\n * typed-data signing over the full typed-data JSON string. This is the same\n * contract as `SigningWalletAdapter`, so `EnvKeyAdapter` and\n * `OWSWalletAdapter` satisfy it structurally, and a browser wallet only has\n * to wrap its own `signTypedData` in this shape — the key never leaves it.\n */\nexport interface LifecycleSigner {\n /** The EVM address that will be claimed as `lifecycleAuth.signer`. */\n getAddress(): string;\n /** Sign the full EIP-712 JSON (`domain`, `types`, `primaryType`, `message`). */\n signTypedData(typedData: string): Promise<{ signature: string }>;\n}\n\n/** The block that goes in `payload.lifecycleAuth`. */\nexport interface LifecycleAuth {\n /** Who claims to have signed. Checked against the recovered address. */\n signer: string;\n /** Unix seconds after which the order is dead. */\n deadline: number;\n /** 32-byte hex replay guard, consumed by the facilitator on success. */\n nonce: string;\n /** 65-byte EIP-712 signature over the `LifecycleOrder`. */\n signature: string;\n}\n\nexport interface LifecycleTypedDataParams {\n /** `'release'` or `'refundInEscrow'`. */\n action: LifecycleAction;\n /**\n * The paymentInfo EXACTLY as it is serialized on the wire. This same object\n * is signed, which is what keeps the two ends from drifting.\n */\n paymentInfo: LifecyclePaymentInfo;\n /** The escrow's payer — travels as `payload.payer`, not inside paymentInfo. */\n payer: string;\n /** Atomic amount, the SAME one as `payload.amount`. */\n amount: string | number | bigint;\n /** EVM chain id of the payment network. */\n chainId: number;\n /**\n * Unix seconds after which the order is dead. Default: `now + 600`, which\n * leaves 300 s of headroom under the facilitator's 900 s ceiling.\n */\n deadline?: number;\n /**\n * 32 bytes, hex. Default: a fresh random one. Distinct PER ORDER — the\n * facilitator consumes it on acceptance.\n */\n nonce?: string;\n /** Unix seconds, for the `deadline` default and for tests. Default: the clock. */\n now?: number;\n}\n\n/**\n * The EIP-712 document itself: what {@link buildLifecycleTypedData} returns and\n * what {@link lifecycleAuthFromSignature} reads back.\n *\n * Named because it is a WIRE type in the split flow: a backend builds it,\n * ships it to a browser as JSON, and the browser hands it to `signTypedData`.\n * `types` carries no `EIP712Domain` entry — ethers and viem both derive that\n * one, and including it makes ethers throw `ambiguous primary types`.\n */\nexport interface LifecycleTypedData {\n domain: { name: string; version: string; chainId: number };\n types: Record<string, Array<{ name: string; type: string }>>;\n primaryType: 'LifecycleOrder';\n message: Record<string, unknown>;\n}\n\nexport interface BuildLifecycleAuthParams extends LifecycleTypedDataParams {\n /**\n * The signer. Must be the payer, the receiver or the operator owner\n * depending on the action — see the table in the module docblock.\n */\n wallet: LifecycleSigner;\n}\n\n// ============================================================================\n// COERCIONS — each one is a rejection the caller cannot see\n// ============================================================================\n\n/**\n * `salt` is bytes32 on the wire and uint256 in the signature.\n *\n * The facilitator converts it with `U256::from_be_bytes` (`types.rs:288`):\n * the wire hex enters the signed struct as an INTEGER. Signing it as a\n * string yields a different digest and a mute `bad_signature` whose only\n * symptom is that no order ever verifies.\n */\nfunction saltToBigInt(salt: unknown): bigint {\n if (typeof salt === 'bigint') return salt;\n if (typeof salt === 'number') {\n if (!Number.isInteger(salt) || salt < 0) {\n throw new X402Error(`paymentInfo.salt invalid: ${String(salt)}`, 'INVALID_CONFIG');\n }\n return BigInt(salt);\n }\n if (typeof salt === 'string') {\n const trimmed = salt.trim();\n // A bare hex string with no 0x is still hex here: that is how the wire\n // carries it in some payloads, and reading it as decimal would sign a\n // different struct than the one that is sent.\n const hex = trimmed.startsWith('0x') || trimmed.startsWith('0X') ? trimmed : `0x${trimmed}`;\n try {\n return BigInt(hex);\n } catch {\n throw new X402Error(`paymentInfo.salt invalid: ${salt}`, 'INVALID_CONFIG');\n }\n }\n throw new X402Error(`paymentInfo.salt invalid: ${String(salt)}`, 'INVALID_CONFIG');\n}\n\n/** 32-byte hex, lowercase, 0x-prefixed — or a throw naming the real length. */\nfunction nonceToBytes32(nonce: unknown): string {\n if (typeof nonce !== 'string') {\n throw new X402Error(`lifecycleAuth.nonce invalid: ${String(nonce)}`, 'INVALID_CONFIG');\n }\n const raw = nonce.startsWith('0x') || nonce.startsWith('0X') ? nonce.slice(2) : nonce;\n if (!/^[0-9a-fA-F]*$/.test(raw)) {\n throw new X402Error(`lifecycleAuth.nonce is not hex: ${nonce}`, 'INVALID_CONFIG');\n }\n if (raw.length !== 64) {\n throw new X402Error(\n `lifecycleAuth.nonce must be 32 bytes, got ${raw.length / 2}`,\n 'INVALID_CONFIG'\n );\n }\n return `0x${raw.toLowerCase()}`;\n}\n\n/** 32 random bytes as 0x-hex (WebCrypto when available, ethers otherwise). */\nfunction randomNonce(): string {\n const webCrypto = (globalThis as { crypto?: Crypto }).crypto;\n if (webCrypto?.getRandomValues) {\n const bytes = new Uint8Array(32);\n webCrypto.getRandomValues(bytes);\n return ethers.hexlify(bytes);\n }\n return ethers.hexlify(ethers.randomBytes(32));\n}\n\n/**\n * The two values that must be IDENTICAL in the signed document and in the\n * `lifecycleAuth` block, resolved in ONE place so the two entry points cannot\n * drift. {@link buildLifecycleAuth} needs them before signing; the split\n * browser flow reads them back out of the document it built.\n */\nfunction resolveOrderTiming(params: { deadline?: number; nonce?: string; now?: number }): {\n nowSec: number;\n deadline: number;\n nonce: string;\n} {\n const nowSec = params.now === undefined ? Math.floor(Date.now() / 1000) : Math.floor(params.now);\n return {\n nowSec,\n deadline:\n params.deadline === undefined\n ? nowSec + LIFECYCLE_DEFAULT_DEADLINE_SECS\n : Math.floor(params.deadline),\n nonce: params.nonce === undefined ? randomNonce() : params.nonce,\n };\n}\n\nfunction toUintString(value: unknown, field: string): string {\n let n: bigint;\n try {\n n = typeof value === 'bigint' ? value : BigInt(value as string | number);\n } catch {\n throw new X402Error(`${field} must be a non-negative integer, got ${String(value)}`, 'INVALID_CONFIG');\n }\n if (n < 0n) {\n throw new X402Error(`${field} must be a non-negative integer, got ${String(value)}`, 'INVALID_CONFIG');\n }\n return n.toString();\n}\n\n// ============================================================================\n// TYPED DATA\n// ============================================================================\n\n/**\n * The exact EIP-712 document a lifecycle order signs.\n *\n * Kept separate from {@link buildLifecycleAuth} because it is the useful\n * seam: it is what the Python twin mirrors, what a test can poke field by\n * field to confirm the signature stops verifying, and — the reason it is\n * PUBLIC — what a backend hands to a browser that signs.\n *\n * {@link buildLifecycleAuth} cannot serve that browser: it takes an injected\n * `WalletAdapter` and mints its own nonce and deadline, while a publisher\n * signs a document the backend already assembled and hands back only a\n * signature. Build it here, ship it, and reassemble the wire block with\n * {@link lifecycleAuthFromSignature} — which reads `deadline` and `nonce`\n * back out of this same document, so the two cannot disagree.\n *\n * @example The split flow, backend half\n * ```typescript\n * const typedData = buildLifecycleTypedData({\n * action: 'release',\n * paymentInfo: pi, // the SAME object that will be sent\n * payer, // payload.payer\n * amount, // the SAME as payload.amount\n * chainId: 8453,\n * }); // deadline -> now + 600, nonce -> 32 fresh bytes\n * // -> res.json({ typedData }) ... the browser signs it and posts back a signature\n * const lifecycleAuth = lifecycleAuthFromSignature(typedData, signature, payer);\n * ```\n *\n * @throws {X402Error} `INVALID_CONFIG` on an unknown action or a paymentInfo\n * missing a field; `INVALID_AMOUNT` on a negative amount. Nothing IN THE\n * SIGNED STRUCT is defaulted: an invented field is a signature over a\n * different struct than the one that is sent, i.e. a rejection the caller\n * cannot diagnose. `deadline` and `nonce` are the exception because they\n * exist nowhere else — they are born here and read back from the document.\n */\nexport function buildLifecycleTypedData(params: LifecycleTypedDataParams): LifecycleTypedData {\n const { action, paymentInfo, payer, amount, chainId } = params;\n const { deadline, nonce } = resolveOrderTiming(params);\n\n if (!LIFECYCLE_ACTIONS.includes(action)) {\n throw new X402Error(\n `unknown lifecycle action ${String(action)}; the facilitator only signs ${LIFECYCLE_ACTIONS.join(', ')}`,\n 'INVALID_CONFIG'\n );\n }\n\n let amountBig: bigint;\n try {\n amountBig = typeof amount === 'bigint' ? amount : BigInt(amount);\n } catch {\n throw new X402Error(`amount must be an integer >= 0, got ${String(amount)}`, 'INVALID_AMOUNT');\n }\n if (amountBig < 0n) {\n throw new X402Error(`amount must be an integer >= 0, got ${String(amount)}`, 'INVALID_AMOUNT');\n }\n\n const pi = (paymentInfo ?? {}) as unknown as Record<string, unknown>;\n const missing = LIFECYCLE_PI_KEYS.filter((k) => pi[k] === undefined);\n if (missing.length > 0) {\n throw new X402Error(\n `paymentInfo is missing fields that enter the signature: ${missing.join(', ')}. ` +\n 'The paymentInfo that is SENT is the one that is signed; defaulting a field would ' +\n 'sign a different struct than the one that reaches the facilitator.',\n 'INVALID_CONFIG'\n );\n }\n\n return {\n domain: {\n name: LIFECYCLE_DOMAIN_NAME,\n version: LIFECYCLE_DOMAIN_VERSION,\n chainId: Number(chainId),\n },\n types: LIFECYCLE_ORDER_TYPES,\n primaryType: 'LifecycleOrder',\n message: {\n action,\n amount: amountBig.toString(),\n deadline: toUintString(deadline, 'deadline'),\n nonce: nonceToBytes32(nonce),\n paymentInfo: {\n operator: ethers.getAddress(paymentInfo.operator),\n payer: ethers.getAddress(payer),\n receiver: ethers.getAddress(paymentInfo.receiver),\n token: ethers.getAddress(paymentInfo.token),\n maxAmount: toUintString(paymentInfo.maxAmount, 'paymentInfo.maxAmount'),\n preApprovalExpiry: toUintString(paymentInfo.preApprovalExpiry, 'paymentInfo.preApprovalExpiry'),\n authorizationExpiry: toUintString(\n paymentInfo.authorizationExpiry,\n 'paymentInfo.authorizationExpiry'\n ),\n refundExpiry: toUintString(paymentInfo.refundExpiry, 'paymentInfo.refundExpiry'),\n minFeeBps: toUintString(paymentInfo.minFeeBps, 'paymentInfo.minFeeBps'),\n maxFeeBps: toUintString(paymentInfo.maxFeeBps, 'paymentInfo.maxFeeBps'),\n feeReceiver: ethers.getAddress(paymentInfo.feeReceiver),\n // uint256 in the signature, bytes32 on the wire — see saltToBigInt.\n salt: saltToBigInt(paymentInfo.salt).toString(),\n },\n },\n };\n}\n\n// ============================================================================\n// THE ORDER\n// ============================================================================\n\n/**\n * Sign the order and return the complete `payload.lifecycleAuth` block.\n *\n * This is the first link of enforce: the facilitator already verifies these\n * orders in `log` mode and measured ZERO signatures across 17 days of traffic\n * (2,953 release/refund, 22 payers, 9 networks) — the field did not exist and\n * nobody sent it. Under `enforce` today, 100% would be rejected.\n *\n * The signer is INJECTED; the SDK does not read keys from the environment.\n *\n * @throws {X402Error} `INVALID_CONFIG` if the deadline has already passed or\n * sits past the facilitator's 900 s ceiling. It fails HERE and not there:\n * an out-of-window order is an `expired` / `deadline_too_far` that under\n * `enforce` is stuck money, and the caller has no log to see it in.\n */\nexport async function buildLifecycleAuth(\n params: BuildLifecycleAuthParams\n): Promise<LifecycleAuth> {\n const { wallet, ...rest } = params;\n\n const { nowSec, deadline: dl, nonce: nonceHex } = resolveOrderTiming(params);\n\n if (dl < nowSec) {\n throw new X402Error(\n `deadline ${dl} is in the past (now ${nowSec}): the facilitator discards it as \\`expired\\``,\n 'INVALID_CONFIG'\n );\n }\n if (dl - nowSec > LIFECYCLE_MAX_DEADLINE_SECS) {\n throw new X402Error(\n `deadline ${dl} is ${dl - nowSec} s ahead and the facilitator's ceiling is ` +\n `${LIFECYCLE_MAX_DEADLINE_SECS} s (\\`deadline_too_far\\`): a leaked order cannot be a ` +\n 'standing permission',\n 'INVALID_CONFIG'\n );\n }\n\n const typed = buildLifecycleTypedData({ ...rest, deadline: dl, nonce: nonceHex });\n const signed = await wallet.signTypedData(JSON.stringify(typed));\n\n return {\n signer: wallet.getAddress(),\n deadline: dl,\n nonce: nonceToBytes32(nonceHex),\n signature: signed.signature,\n };\n}\n\n/**\n * Reassemble `payload.lifecycleAuth` from a document that was signed\n * ELSEWHERE — the other half of the split flow.\n *\n * `buildLifecycleAuth` owns the whole ceremony: it mints the nonce and the\n * deadline, signs, and returns the block. A publisher's browser owns none of\n * that. It receives a document the backend already assembled and gives back\n * one string. This is the seam where that string becomes a wire block.\n *\n * `deadline` and `nonce` are NOT parameters: they are read out of\n * `typedData.message`, which is the document that was actually hashed. Taking\n * them from the caller would let the block claim a nonce the signature never\n * committed to — a `bad_signature` the caller cannot see, because both halves\n * look right on their own.\n *\n * The signature is NOT recovered here. This SDK's payers include ERC-7702\n * delegated accounts and contract wallets that validate through ERC-1271\n * (`src/erc7702.ts:8`), whose signatures do not ecrecover to their address;\n * `ethers.verifyTypedData` would reject the good ones. Recovery — and the\n * role check that goes with it — is the facilitator's, against the chain.\n *\n * @param typedData - what {@link buildLifecycleTypedData} returned, unmodified.\n * @param signature - the 0x-hex the wallet gave back (`signTypedData`).\n * @param signer - the address that signed, claimed in the block and checked\n * against the recovered one by the facilitator.\n *\n * @throws {X402Error} `INVALID_CONFIG` if the document is not a\n * `LifecycleOrder` for this domain, if the signature is not hex, or if the\n * signer is not an address.\n *\n * @example The browser half\n * ```typescript\n * const signature = await walletClient.signTypedData({\n * domain: typedData.domain,\n * types: typedData.types,\n * primaryType: typedData.primaryType,\n * message: typedData.message,\n * });\n * const lifecycleAuth = lifecycleAuthFromSignature(typedData, signature, address);\n * ```\n */\nexport function lifecycleAuthFromSignature(\n typedData: LifecycleTypedData,\n signature: string,\n signer: string\n): LifecycleAuth {\n const td = (typedData ?? {}) as Partial<LifecycleTypedData>;\n const message = (td.message ?? {}) as Record<string, unknown>;\n\n // A payment's typed data would sail through the shape checks below and\n // produce a block over the wrong struct entirely, so the document is\n // identified before anything is read out of it.\n if (td.primaryType !== 'LifecycleOrder') {\n throw new X402Error(\n `typedData.primaryType must be LifecycleOrder, got ${String(td.primaryType)}: ` +\n 'pass the document buildLifecycleTypedData returned, unmodified',\n 'INVALID_CONFIG'\n );\n }\n const domain = (td.domain ?? {}) as Record<string, unknown>;\n if (\n domain.name !== LIFECYCLE_DOMAIN_NAME ||\n String(domain.version) !== LIFECYCLE_DOMAIN_VERSION\n ) {\n throw new X402Error(\n `typedData.domain must be ${LIFECYCLE_DOMAIN_NAME} v${LIFECYCLE_DOMAIN_VERSION}, got ` +\n `${String(domain.name)} v${String(domain.version)}`,\n 'INVALID_CONFIG'\n );\n }\n if (message.deadline === undefined || message.nonce === undefined) {\n throw new X402Error(\n 'typedData.message carries no deadline/nonce: the wire block reads them from the ' +\n 'document that was signed, it does not invent them',\n 'INVALID_CONFIG'\n );\n }\n\n // uint256 in the signature, a JSON number on the wire. The facilitator's\n // block is typed `u64`, so a deadline that lost precision here is an\n // `expired` on an order whose signature is perfectly good.\n const deadlineBig = BigInt(toUintString(message.deadline, 'typedData.message.deadline'));\n if (deadlineBig > BigInt(Number.MAX_SAFE_INTEGER)) {\n throw new X402Error(\n `typedData.message.deadline ${deadlineBig} does not fit a JSON number`,\n 'INVALID_CONFIG'\n );\n }\n\n if (typeof signature !== 'string' || !/^0x[0-9a-fA-F]+$/.test(signature) ||\n signature.length % 2 !== 0) {\n throw new X402Error(\n `signature must be 0x-prefixed hex, got ${String(signature)}`,\n 'INVALID_CONFIG'\n );\n }\n\n let checksummed: string;\n try {\n checksummed = ethers.getAddress(signer);\n } catch {\n throw new X402Error(`signer is not an EVM address: ${String(signer)}`, 'INVALID_CONFIG');\n }\n\n return {\n signer: checksummed,\n deadline: Number(deadlineBig),\n nonce: nonceToBytes32(message.nonce),\n signature,\n };\n}\n\n// ============================================================================\n// BROWSER SIGNERS\n// ============================================================================\n\n/**\n * Minimal wagmi/viem wallet client: what {@link wagmiLifecycleSigner} needs.\n *\n * Deliberately narrower than this SDK's payment `WalletClient`: a lifecycle\n * domain has NO `verifyingContract`, so a client typed to require one cannot\n * sign these orders.\n */\nexport interface WagmiLifecycleWalletClient {\n account?: { address: string } | null;\n signTypedData(args: {\n domain: Record<string, unknown>;\n types: Record<string, Array<{ name: string; type: string }>>;\n primaryType: string;\n message: Record<string, unknown>;\n }): Promise<string>;\n}\n\n/**\n * Wrap a wagmi/viem wallet client as a {@link LifecycleSigner}, so the PAYER\n * signs the order in their own browser with the same wallet they paid with,\n * and the marketplace only transports the block.\n *\n * @param walletClient - from `useWalletClient()` (wagmi) or `createWalletClient` (viem).\n * @param address - the signing account; defaults to `walletClient.account.address`.\n *\n * @example\n * ```typescript\n * const { data: walletClient } = useWalletClient();\n * const auth = await buildLifecycleAuth({\n * action: 'release',\n * paymentInfo: pi,\n * payer: address,\n * amount: task.bountyAtomic,\n * chainId: 8453,\n * wallet: wagmiLifecycleSigner(walletClient!),\n * });\n * await fetch('/api/tasks/x/approve', {\n * method: 'POST',\n * body: JSON.stringify({ lifecycleAuth: auth }),\n * });\n * ```\n */\nexport function wagmiLifecycleSigner(\n walletClient: WagmiLifecycleWalletClient,\n address?: string\n): LifecycleSigner {\n const account = address ?? walletClient.account?.address;\n if (!account) {\n throw new X402Error(\n 'wagmiLifecycleSigner needs an account: pass one, or connect the wallet client first',\n 'INVALID_CONFIG'\n );\n }\n const checksummed = ethers.getAddress(account);\n return {\n getAddress: () => checksummed,\n async signTypedData(typedData: string) {\n const parsed = JSON.parse(typedData) as {\n domain: Record<string, unknown>;\n types: Record<string, Array<{ name: string; type: string }>>;\n primaryType: string;\n message: Record<string, unknown>;\n };\n const signature = await walletClient.signTypedData({\n domain: parsed.domain,\n types: parsed.types,\n primaryType: parsed.primaryType,\n message: parsed.message,\n });\n return { signature };\n },\n };\n}\n","/** Native Hedera x402 v2/exact. Signing is offline; only the facilitator submits. */\nimport { formatUnits, parseUnits } from 'ethers';\nimport type { ChainConfig, PaymentInfo, TokenType, WalletAdapter, X402Version } from '../../types';\nimport { encodeBase64Json } from '../../utils/base64';\n\nexport const HEDERA_NETWORKS = {\n 'hedera:mainnet': { usdc: '0.0.456858', feePayer: '0.0.10868300', mirror: 'https://mainnet-public.mirrornode.hedera.com' },\n 'hedera:testnet': { usdc: '0.0.429274', feePayer: '0.0.10576385', mirror: 'https://testnet.mirrornode.hedera.com' },\n} as const;\nexport type HederaNetwork = keyof typeof HEDERA_NETWORKS;\n/** Historical identifier; HBAR is for network fees, not supported payments. */\nexport const HBAR_ASSET = '0.0.0';\nconst MAX_AMOUNT = (1n << 63n) - 1n;\n\nexport interface HederaRequirements {\n scheme: 'exact'; network: HederaNetwork; asset: string; amount: string;\n payTo: string; maxTimeoutSeconds: number; extra: { feePayer: string };\n}\nexport interface HederaPaymentPayload {\n x402Version: 2; accepted: HederaRequirements;\n resource?: { url: string; description?: string; mimeType?: string };\n payload: { transaction: string };\n}\nfunction account(value: unknown): string {\n if (typeof value !== 'string' || !/^0\\.0\\.[1-9][0-9]*$/.test(value) || BigInt(value.split('.')[2]) > MAX_AMOUNT) {\n throw new Error('Hedera accounts must be canonical numeric IDs: 0.0.123');\n }\n return value;\n}\nfunction networkInfo(network: string) {\n if (!Object.hasOwn(HEDERA_NETWORKS, network)) throw new Error('Expected hedera:mainnet or hedera:testnet');\n return HEDERA_NETWORKS[network as HederaNetwork];\n}\n/** Validate the entire offer before any signing or network call. */\nexport function validateHederaRequirements(input: unknown): HederaRequirements {\n if (!input || typeof input !== 'object') throw new Error('Hedera requirements must be an object');\n const r = input as HederaRequirements;\n const fields = ['scheme', 'network', 'asset', 'amount', 'payTo', 'maxTimeoutSeconds', 'extra'];\n if (Object.keys(r).length !== fields.length || fields.some(k => !Object.hasOwn(r, k)) || r.scheme !== 'exact') {\n throw new Error('Hedera requires exact v2 requirements without extensions');\n }\n const info = networkInfo(r.network);\n if (r.asset !== info.usdc) throw new Error('Hedera payments support native USDC only; HBAR is for network fees');\n if (typeof r.amount !== 'string' || !/^[1-9][0-9]*$/.test(r.amount) || r.amount.length > 19 || BigInt(r.amount) > MAX_AMOUNT) {\n throw new Error('amount must be a positive canonical atomic integer string within int64');\n }\n if (!Number.isInteger(r.maxTimeoutSeconds) || r.maxTimeoutSeconds < 15 || r.maxTimeoutSeconds > 180) {\n throw new Error('Hedera maxTimeoutSeconds must be 15..180');\n }\n if (!r.extra || Object.keys(r.extra).length !== 1 || !Object.hasOwn(r.extra, 'feePayer')) {\n throw new Error('Hedera extra must contain only feePayer');\n }\n account(r.extra.feePayer); account(r.payTo);\n if (r.payTo === r.extra.feePayer) throw new Error('The fee payer must be distinct from the merchant');\n return { ...r, extra: { ...r.extra } };\n}\n/** Native USDC amounts have 6 decimals. HBAR is used only for network fees. */\nexport function buildHederaRequirements(options: {\n network: HederaNetwork; payTo: string; amountAtomic: string; asset?: 'usdc' | string;\n feePayer?: string; maxTimeoutSeconds?: number;\n}): HederaRequirements {\n const info = networkInfo(options.network);\n return validateHederaRequirements({\n scheme: 'exact', network: options.network,\n asset: !options.asset || options.asset === 'usdc' ? info.usdc : options.asset,\n amount: options.amountAtomic, payTo: options.payTo, maxTimeoutSeconds: options.maxTimeoutSeconds ?? 180,\n extra: { feePayer: options.feePayer ?? info.feePayer },\n });\n}\n/** Merchant /verify or /settle body. Pass the merchant's OWN offer, never the buyer's price. */\nexport function buildHederaRequest(paymentPayload: HederaPaymentPayload, requirements: HederaRequirements) {\n const r = validateHederaRequirements(requirements);\n const p = paymentPayload;\n const accepted = validateHederaRequirements(p.accepted);\n if (p.x402Version !== 2 || Object.keys(p).some(k => !['x402Version', 'accepted', 'resource', 'payload'].includes(k)) ||\n Object.keys(r).some(k => k === 'extra' ? r.extra.feePayer !== accepted.extra.feePayer : r[k as keyof HederaRequirements] !== accepted[k as keyof HederaRequirements])) {\n throw new Error('Hedera requires v2 and an exact accepted echo without extensions');\n }\n if (!p.payload || Object.keys(p.payload).length !== 1 || typeof p.payload.transaction !== 'string') {\n throw new Error('Hedera payload must contain only transaction');\n }\n return { x402Version: 2 as const, paymentPayload: p, paymentRequirements: r };\n}\n\n/** Native buyer adapter. The optional @hiero-ledger/sdk peer is loaded only when used. */\nexport class HederaProvider implements WalletAdapter {\n readonly id = 'hedera-native';\n readonly name = 'Hedera Native';\n readonly networkType = 'hedera' as const;\n readonly network: HederaNetwork;\n readonly accountId: string;\n readonly feePayer: string;\n private privateKey: string;\n private connected = false;\n\n constructor(options: { accountId: string; privateKey: string; network: HederaNetwork; feePayer?: string }) {\n const info = networkInfo(options.network);\n this.network = options.network;\n this.accountId = account(options.accountId);\n this.feePayer = account(options.feePayer ?? info.feePayer);\n if (this.accountId === this.feePayer) throw new Error('Buyer and fee payer must be distinct');\n this.privateKey = options.privateKey;\n // Keep key material out of JSON.stringify(provider), including diagnostic logs.\n Object.defineProperty(this, 'privateKey', { enumerable: false });\n }\n isAvailable(): boolean { return true; }\n async connect(chainName = this.network): Promise<string> {\n if (chainName !== this.network) throw new Error('Provider is bound to another Hedera ledger');\n await this.key();\n this.connected = true;\n return this.accountId;\n }\n async disconnect(): Promise<void> { this.connected = false; }\n getAddress(): string | null { return this.connected ? this.accountId : null; }\n\n private async key() {\n let sdk: typeof import('@hiero-ledger/sdk');\n try { sdk = await import('@hiero-ledger/sdk'); }\n catch { throw new Error('Install @hiero-ledger/sdk to sign native Hedera payments'); }\n try { return { sdk, key: sdk.PrivateKey.fromStringDer(this.privateKey) }; }\n catch { throw new Error('Invalid Hedera DER private key (value redacted)'); }\n }\n async createPaymentPayload(accepted: HederaRequirements, resource?: HederaPaymentPayload['resource']): Promise<HederaPaymentPayload> {\n const r = validateHederaRequirements(accepted);\n if (r.network !== this.network || r.extra.feePayer !== this.feePayer) throw new Error(\"Offer does not match the signer's ledger and trusted fee payer\");\n if (r.payTo === this.accountId) throw new Error('Buyer and merchant must be distinct');\n const { sdk, key } = await this.key();\n const tx = new sdk.TransferTransaction()\n .setTransactionId(sdk.TransactionId.generate(this.feePayer))\n .setNodeAccountIds(['0.0.3', '0.0.4', this.network === 'hedera:mainnet' ? '0.0.7' : '0.0.5'].map(n => sdk.AccountId.fromString(n)))\n .setTransactionValidDuration(r.maxTimeoutSeconds)\n .setMaxTransactionFee(sdk.Hbar.fromTinybars('100000000'))\n .setRegenerateTransactionId(false);\n tx.addTokenTransfer(r.asset, this.accountId, '-' + r.amount).addTokenTransfer(r.asset, r.payTo, r.amount);\n await tx.freeze().sign(key);\n // Browser-safe encoding; protobuf TransactionList, NOT a single Transaction.\n let binary = '';\n for (const byte of tx.toBytes()) binary += String.fromCharCode(byte);\n const p: HederaPaymentPayload = { x402Version: 2, accepted: r, payload: { transaction: btoa(binary) } };\n if (resource) p.resource = { ...resource };\n return p;\n }\n async signPayment(paymentInfo: PaymentInfo, chain: ChainConfig): Promise<string> {\n if (!this.connected) throw new Error('Hedera wallet is not connected');\n if (chain.name !== this.network || paymentInfo.x402Version === 1) throw new Error('Hedera requires this ledger and x402 v2');\n if (paymentInfo.extensions && Object.keys(paymentInfo.extensions).length) throw new Error('Hedera extensions are unsupported');\n if (!paymentInfo.accepted) throw new Error('Hedera signing requires the exact accepted offer from the 402');\n const r = validateHederaRequirements(paymentInfo.accepted);\n const tokenType = paymentInfo.tokenType ?? 'usdc';\n const asset = tokenType === 'usdc' ? networkInfo(this.network).usdc : '';\n if (r.asset !== asset || r.payTo !== paymentInfo.recipient || parseUnits(paymentInfo.amount, 6).toString() !== r.amount) {\n throw new Error('Offer does not match the approved recipient, asset and amount');\n }\n return JSON.stringify(await this.createPaymentPayload(r, paymentInfo.resource));\n }\n encodePaymentHeader(payload: string, chain: ChainConfig, version: X402Version = 2): string {\n if (version !== 2 || chain.name !== this.network) throw new Error('Hedera supports only x402 v2 on the bound ledger');\n const p = JSON.parse(payload) as HederaPaymentPayload;\n buildHederaRequest(p, p.accepted);\n return encodeBase64Json(p);\n }\n async getBalance(chain: ChainConfig, tokenType: TokenType = 'usdc'): Promise<string> {\n if (chain.name !== this.network) throw new Error('Provider is bound to another Hedera ledger');\n const info = networkInfo(this.network);\n if (!['usdc', 'hbar'].includes(tokenType)) throw new Error('Unsupported Hedera token');\n const path = tokenType === 'hbar' ? '' : `/tokens?token.id=${info.usdc}`;\n const response = await fetch(`${info.mirror}/api/v1/accounts/${this.accountId}${path}`, { signal: AbortSignal.timeout(15000) });\n if (!response.ok) throw new Error(`Hedera balance HTTP ${response.status}`);\n const data = await response.json();\n const amount = tokenType === 'hbar' ? data.balance?.balance : data.tokens?.[0]?.balance ?? 0;\n if (!Number.isSafeInteger(amount) || amount < 0) throw new Error('Mirror returned an unsafe balance');\n return formatUnits(BigInt(amount), tokenType === 'hbar' ? 8 : 6);\n }\n}\nexport default HederaProvider;\n","import { parseFacilitatorReceipt, receiptFromErrorBody, mergePaymentResponseHeaders, validatePurchaseContext, type FacilitatorReceipt } from \"../receipts\";\nimport { bytesToHex, randomBytes } from '@noble/hashes/utils';\nexport * from \"../receipts\";\nimport { parseUnits } from 'ethers';\nimport { buildHederaRequirements, type HederaNetwork } from '../providers/hedera';\n/**\n * uvd-x402-sdk - Backend Utilities\n *\n * Server-side utilities for building x402 payment APIs.\n * These utilities help backend developers:\n * - Build verify/settle requests for the facilitator\n * - Parse X-PAYMENT headers from incoming requests\n * - Configure CORS for x402 payment flows\n * - Create atomic payment handlers\n * - Discover and register resources via Bazaar Discovery API\n * - Manage escrow payments with refund and dispute resolution\n *\n * @example Basic payment flow\n * ```ts\n * import {\n * parsePaymentHeader,\n * FacilitatorClient,\n * X402_CORS_HEADERS,\n * } from 'uvd-x402-sdk/backend';\n *\n * // Parse payment from request header\n * const payment = parsePaymentHeader(req.headers['x-payment']);\n *\n * // Verify with facilitator\n * const client = new FacilitatorClient();\n * const verifyResult = await client.verify(payment, paymentRequirements);\n *\n * // If valid, provide service then settle\n * const settleResult = await client.settle(payment, paymentRequirements);\n * ```\n *\n * @example Escrow payment with refund support\n * ```ts\n * import { EscrowClient } from 'uvd-x402-sdk/backend';\n *\n * const escrow = new EscrowClient();\n *\n * // Hold payment in escrow\n * const escrowPayment = await escrow.createEscrow({\n * paymentHeader: req.headers['x-payment'],\n * requirements: paymentRequirements,\n * escrowDuration: 86400, // 24 hours\n * });\n *\n * // After service delivered, release to recipient\n * await escrow.release(escrowPayment.id);\n *\n * // Or if service failed, request refund\n * await escrow.requestRefund({\n * escrowId: escrowPayment.id,\n * reason: 'Service not delivered',\n * });\n * ```\n *\n * @example Resource discovery\n * ```ts\n * import { BazaarClient } from 'uvd-x402-sdk/backend';\n *\n * const bazaar = new BazaarClient();\n * const resources = await bazaar.discover({\n * category: 'ai',\n * network: 'base',\n * maxPrice: '0.10',\n * });\n * ```\n */\n\nimport type {\n X402Header,\n X402PayloadData,\n X402Version,\n} from '../types';\nimport { decodeX402Header, chainToCAIP2, parseNetworkIdentifier } from '../utils';\nimport {\n REVIEW_WINDOW_SEC,\n REFUND_WINDOW_SEC,\n DEFAULT_MIN_FEE_BPS,\n DEFAULT_MAX_FEE_BPS,\n OPERATOR_FEE_BPS,\n} from '../escrow-preauth';\nimport { buildLifecycleAuth } from '../lifecycle-auth';\nimport type {\n LifecycleAction,\n LifecycleAuth,\n LifecyclePaymentInfo,\n LifecycleSigner,\n} from '../lifecycle-auth';\nimport { X402Error } from '../types';\nimport { getChainByName, isUsdPegged, usdConversionError } from '../chains';\nimport {\n AUTHORIZATION_ALREADY_SETTLED,\n AUTHORIZATION_IN_FLIGHT,\n DEFAULT_RETRY_AFTER_SECONDS,\n SETTLEMENT_UNCONFIRMED,\n carryFailureFields,\n isAuthorizationAlreadyUsed,\n isAuthorizationInFlight,\n isReplayableLeaseReason,\n facilitatorFetch,\n failureFields,\n parseFacilitatorErrorBody,\n readFacilitatorError,\n} from './facilitator-error';\nimport type { FacilitatorErrorInfo, FacilitatorFailureFields } from './facilitator-error';\n\n// A facilitator refusal is DATA, not prose. `402` and `503` say opposite things\n// and this file used to answer both with `success: false` plus a sentence --\n// see ./facilitator-error.ts for why that costs the buyer a second payment.\nexport {\n AMBIGUOUS_LEASE_REASONS,\n AUTHORIZATION_ALREADY_SETTLED,\n AUTHORIZATION_IN_FLIGHT,\n DEFAULT_FACILITATOR_RETRIES,\n DEFAULT_RETRY_AFTER_SECONDS,\n MAX_RETRY_AFTER_SECONDS,\n RECEIPT_REQUEST_CONFLICT,\n REPLAYABLE_LEASE_REASONS,\n SETTLEMENT_UNCONFIRMED,\n WRITER_LEASE_REASONS,\n carryFailureFields,\n facilitatorFetch,\n isAmbiguousLeaseReason,\n isAuthorizationAlreadyUsed,\n isAuthorizationInFlight,\n isReplayableLeaseReason,\n isSettlementUnconfirmed,\n parseFacilitatorErrorBody,\n parseRetryAfterSeconds,\n readFacilitatorError,\n} from './facilitator-error';\nexport type {\n AdmittedAuthorizationCode,\n FacilitatorErrorInfo,\n FacilitatorFailureFields,\n FacilitatorFetchOptions,\n ParsedFacilitatorErrorBody,\n WriterLeaseReason,\n} from './facilitator-error';\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\n/**\n * Payment requirements sent to the facilitator\n */\nexport interface PaymentRequirements {\n /** Payment scheme */\n scheme: 'exact' | 'escrow' | 'commerce';\n /** Network name (v1) or CAIP-2 identifier (v2) */\n network: string;\n /** Maximum amount required in atomic units (e.g., \"1000000\" for 1 USDC) */\n maxAmountRequired: string;\n /** Resource URL being paid for */\n resource: string;\n /** Description of what's being paid for */\n description: string;\n /** MIME type of the resource */\n mimeType: string;\n /** Recipient address for payment */\n payTo: string;\n /** Maximum timeout in seconds */\n maxTimeoutSeconds: number;\n /** Token contract address */\n asset: string;\n /** Optional output schema for the resource */\n outputSchema?: unknown;\n /** Optional extra data */\n extra?: unknown;\n}\n\n/**\n * Verify request body for the facilitator /verify endpoint -- the **v1**\n * envelope. {@link VerifyRequestV2} is the other one.\n */\nexport interface VerifyRequest {\n /**\n * Always `1`: this marker names the ENVELOPE, and this envelope is v1.\n *\n * Narrowed from `X402Version` on 2026-09-04. A `VerifyRequest` carrying `2`\n * was always an uninhabitable value -- a body declaring v2 while shaped as\n * v1 -- and typing it as `1 | 2` is what let the payer's marker be copied in\n * here. The payer's version lives in `paymentPayload.x402Version`, which is\n * still the full union.\n */\n x402Version: 1;\n paymentPayload: X402Header;\n paymentRequirements: PaymentRequirements;\n}\n\n/**\n * Settle request body for the facilitator /settle endpoint -- the **v1**\n * envelope. {@link SettleRequestV2} is the other one.\n */\nexport interface SettleRequest {\n /** Always `1` -- see {@link VerifyRequest.x402Version}. */\n x402Version: 1;\n paymentPayload: X402Header;\n paymentRequirements: PaymentRequirements;\n}\n\n/**\n * Verify response from the facilitator\n */\nexport interface VerifyResponse extends FacilitatorFailureFields {\n receipt?: FacilitatorReceipt | null;\n isValid: boolean;\n /**\n * Why the payment is not valid.\n *\n * Read `retryable` before showing this to anyone. When `retryable` is true the\n * facilitator reached NO VERDICT -- it did not reject the payment, so this\n * string is a transport diagnosis, not a rejection, and re-signing on it makes\n * the buyer pay twice.\n */\n invalidReason?: string;\n payer?: string;\n network?: string;\n /**\n * The `Idempotency-Key` this verification carried. Settle the same payment\n * with it (`settle(..., { idempotencyKey })`) so both calls present one\n * purchase binding. Merchant-private: never forward it to the buyer.\n */\n idempotencyKey?: string;\n}\n\n/**\n * Settle response from the facilitator\n */\nexport interface SettleResponse extends FacilitatorFailureFields {\n receipt?: FacilitatorReceipt | null;\n success: boolean;\n transactionHash?: string;\n network?: string;\n /**\n * Transport-level failure (unreachable facilitator, non-2xx, timeout).\n *\n * `success: false` with `retryable: true` is NOT a rejected payment. The\n * authorization is untouched and the same one must be resent; treating it as\n * a refusal and asking for a new signature charges the buyer twice.\n */\n error?: string;\n /**\n * The facilitator's own reason when it settled nothing — e.g. a transfer that\n * mined and reverted. Distinct from `error` above, which is this client\n * failing to ask; this one is the facilitator answering \"no\".\n */\n errorReason?: string;\n /** The address the facilitator confirmed as the payer. */\n payer?: string;\n /**\n * Settlement proof, present when the ERC-8004 extension asked for it.\n *\n * Typed here rather than only on {@link SettleResponseWithProof} because\n * `settle()` returns it whenever the facilitator sends it, and it is what\n * DX402's `anchorEvidence` needs to reach `verified: true`.\n */\n proofOfPayment?: ProofOfPayment;\n /**\n * The facilitator answered `Idempotent-Replayed: true`: this is its stored\n * answer to an EARLIER settle of this authorization, and no new money moved.\n *\n * It is this caller's own purchase only when the call carried the binding\n * that admitted it -- the same `idempotencyKey`, or the same\n * `X-UVD-Purchase` context. A settle made with a fresh key and no context\n * cannot have admitted anything before, so this client, `verifyAndSettle`\n * and both middlewares answer such a replay as\n * {@link AUTHORIZATION_ALREADY_SETTLED} (or {@link AUTHORIZATION_IN_FLIGHT})\n * instead of a success: the resource must not be served again. Facilitators\n * from 2.39.0 refuse that resend with the same codes themselves.\n */\n replayed?: boolean;\n /**\n * The `Idempotency-Key` this settle carried. After a lost response, resend\n * the same payment with it to receive the original answer instead of a\n * `409`. Merchant-private: never forward it to the buyer.\n */\n idempotencyKey?: string;\n}\n\n/**\n * Options for building payment requirements\n */\nexport interface PaymentRequirementsOptions {\n /** Amount in human-readable format (e.g., \"1.00\") */\n amount: string;\n /** Recipient address */\n recipient: string;\n /** Resource URL being protected */\n resource: string;\n /** Chain name (e.g., \"base\") */\n chainName?: string;\n /** Description of the resource */\n description?: string;\n /** MIME type of the resource */\n mimeType?: string;\n /** Timeout in seconds (default: 300) */\n timeoutSeconds?: number;\n /** x402 version to use */\n x402Version?: X402Version;\n}\n\n/**\n * x402 payment option advertised in a 402 response.\n *\n * The SDK keeps the response shape richer than the minimal protocol fields so\n * servers can preserve settlement-critical metadata such as payTo and extra.\n */\nexport interface PaymentAcceptance {\n network: string;\n asset: string;\n amount: string;\n /**\n * Payment scheme. REQUIRED by the facilitator's v2 `PaymentRequirementsV2`.\n *\n * Optional here only so existing callers keep compiling — when it is absent,\n * `buildRequirementFromAcceptance` defaults it to `'exact'`. Do not treat its\n * optionality as \"the facilitator does not need it\": an accepts[] entry that\n * reaches a v2 client without a scheme is unpayable.\n */\n scheme?: string;\n payTo?: string;\n facilitator?: string;\n resource?: string;\n description?: string;\n mimeType?: string;\n maxTimeoutSeconds?: number;\n outputSchema?: unknown;\n extra?: unknown;\n}\n\n/**\n * Verified payment context attached by server middleware.\n */\nexport interface VerifiedPaymentState {\n payment: X402Header;\n requirements: PaymentRequirements;\n verifyResult: VerifyResponse;\n /**\n * Settles once; later calls return the same result. A facilitator replay that\n * this request did not bind (no `X-UVD-Purchase`) comes back as\n * {@link AUTHORIZATION_ALREADY_SETTLED} or {@link AUTHORIZATION_IN_FLIGHT},\n * never as a success, so a replayed X-PAYMENT is not served twice. The\n * receipt headers are added only while the response has not been sent.\n */\n settle: () => Promise<SettleResponse>;\n /** The key sent on this payment's `/verify` and `/settle`. Merchant-private. */\n idempotencyKey?: string;\n}\n\n/**\n * Shared server middleware options.\n */\nexport interface PaymentMiddlewareOptions extends FacilitatorClientOptions {\n /** Alias for baseUrl to keep middleware options ergonomic */\n facilitatorUrl?: string;\n /**\n * Settlement behavior after verification.\n * - manual: verify only; caller settles explicitly\n * - before-handler: settle immediately before calling next()\n */\n settlementStrategy?: 'manual' | 'before-handler';\n}\n\n/**\n * Custom resolver for selecting the correct payment requirement when multiple\n * accepts are advertised.\n */\nexport type PaymentRequirementResolver = (\n payment: X402Header,\n requirements: PaymentRequirements[]\n) => PaymentRequirements | null | Promise<PaymentRequirements | null>;\n\n// ============================================================================\n// HEADER PARSING\n// ============================================================================\n\n/**\n * Parse X-PAYMENT or PAYMENT-SIGNATURE header value\n *\n * @param headerValue - Base64-encoded header value (or undefined/null)\n * @returns Parsed x402 header object, or null if invalid\n *\n * @example\n * ```ts\n * // Express.js\n * const payment = parsePaymentHeader(req.headers['x-payment']);\n * if (!payment) {\n * return res.status(400).json({ error: 'Invalid payment header' });\n * }\n * ```\n */\nexport function parsePaymentHeader(\n headerValue: string | undefined | null\n): X402Header | null {\n if (!headerValue) {\n return null;\n }\n\n try {\n return decodeX402Header(headerValue);\n } catch {\n return null;\n }\n}\n\n/**\n * Extract payment header from request headers object\n *\n * Checks both X-PAYMENT and PAYMENT-SIGNATURE headers.\n *\n * @param headers - Request headers object (case-insensitive)\n * @returns Parsed x402 header object, or null if not found/invalid\n *\n * @example\n * ```ts\n * const payment = extractPaymentFromHeaders(req.headers);\n * ```\n */\nexport function extractPaymentFromHeaders(\n headers: Record<string, string | string[] | undefined>\n): X402Header | null {\n // Normalize header keys to lowercase\n const normalizedHeaders: Record<string, string> = {};\n for (const [key, value] of Object.entries(headers)) {\n if (typeof value === 'string') {\n normalizedHeaders[key.toLowerCase()] = value;\n } else if (Array.isArray(value) && value.length > 0) {\n normalizedHeaders[key.toLowerCase()] = value[0];\n }\n }\n\n // Try X-PAYMENT first, then PAYMENT-SIGNATURE\n const headerValue =\n normalizedHeaders['x-payment'] ||\n normalizedHeaders['payment-signature'];\n\n return parsePaymentHeader(headerValue);\n}\n\n// ============================================================================\n// REQUEST BUILDERS\n// ============================================================================\n\n/**\n * Build payment requirements for the facilitator\n *\n * @param options - Payment requirements options\n * @returns PaymentRequirements object ready for verify/settle\n *\n * @example\n * ```ts\n * const requirements = buildPaymentRequirements({\n * amount: '1.00',\n * recipient: '0x1234...',\n * resource: 'https://api.example.com/premium-data',\n * chainName: 'base',\n * });\n * ```\n */\nexport function buildPaymentRequirements(\n options: PaymentRequirementsOptions\n): PaymentRequirements {\n const {\n amount,\n recipient,\n resource,\n chainName = 'base',\n description = 'Payment for resource access',\n mimeType = 'application/json',\n timeoutSeconds = 300,\n x402Version = 1,\n } = options;\n\n const chain = getChainByName(chainName);\n if (!chain) {\n throw new Error(`Unsupported chain: ${chainName}`);\n }\n\n if (chain.networkType === 'hedera') {\n if (options.x402Version !== 2) throw new Error('Native Hedera supports only x402 v2');\n const native = buildHederaRequirements({ network: chain.name as HederaNetwork,\n payTo: recipient, amountAtomic: parseUnits(amount, 6).toString(),\n maxTimeoutSeconds: Math.min(options.timeoutSeconds ?? 180, 180) });\n return { scheme: 'exact', network: native.network, asset: native.asset,\n maxAmountRequired: native.amount, payTo: recipient, resource, description, mimeType,\n maxTimeoutSeconds: native.maxTimeoutSeconds, extra: native.extra };\n }\n\n // Convert amount to atomic units.\n //\n // Scaling by the decimals only turns dollars into base units when one whole\n // unit IS one dollar. On a chain that settles in its own floating native\n // asset it silently prices the call in that asset instead: XRPL registers\n // native XRP under the `usdc` key, so `\"10.00\"` used to bill 10 XRP. Refusing\n // is the only honest answer -- the SDK has no rate and inventing one would\n // charge a number nobody agreed to.\n if (!isUsdPegged(chain.usdc)) {\n throw new Error(usdConversionError(chain.name, chain.usdc));\n }\n const atomicAmount = Math.floor(\n parseFloat(amount) * Math.pow(10, chain.usdc.decimals)\n ).toString();\n\n // Use CAIP-2 for v2, chain name for v1\n const network = x402Version === 2 ? chainToCAIP2(chainName) : chainName;\n\n return {\n scheme: 'exact',\n network,\n maxAmountRequired: atomicAmount,\n resource,\n description,\n mimeType,\n payTo: recipient,\n maxTimeoutSeconds: timeoutSeconds,\n asset: chain.usdc.address,\n };\n}\n\n/**\n * Build a verify request for the facilitator /verify endpoint\n *\n * @param paymentHeader - Parsed x402 payment header\n * @param requirements - Payment requirements\n * @returns VerifyRequest body ready for fetch/axios\n *\n * @example\n * ```ts\n * const payment = parsePaymentHeader(req.headers['x-payment']);\n * const verifyBody = buildVerifyRequest(payment, requirements);\n *\n * const response = await fetch('https://facilitator.uvd.xyz/verify', {\n * method: 'POST',\n * headers: { 'Content-Type': 'application/json' },\n * body: JSON.stringify(verifyBody),\n * });\n * ```\n */\nexport function buildVerifyRequest(\n paymentHeader: X402Header,\n requirements: PaymentRequirements\n): VerifyRequest {\n return {\n // The literal `1` names THIS ENVELOPE, not the payer's header. Echoing\n // `paymentHeader.x402Version` here -- what this did until 2026-09-04 --\n // let a buyer who declared `2` produce a body that says \"2\" while carrying\n // `paymentRequirements`, which is the v1 shape. The facilitator serves it\n // anyway because its envelope enum is untagged and matches on shape, so\n // nothing broke; but it ALREADY picks the hint in its 400 off this marker:\n //\n // \"This body declares `x402Version: 2`. x402 v2 is a JSON object with\n // `paymentPayload`, `resource` and `accepted`...\"\n //\n // So the day that body fails for any other reason, the diagnosis sends the\n // integrator to document the wrong shape. That inversion -- being told to\n // fix the fields when the wrapper is what is wrong -- is what cost two\n // teams a day. The payer's own marker survives untouched inside\n // `paymentPayload`, where it belongs: it describes the payment, not the\n // envelope carrying it.\n x402Version: 1,\n paymentPayload: paymentHeader,\n paymentRequirements: requirements,\n };\n}\n\n/**\n * Build a settle request for the facilitator /settle endpoint\n *\n * @param paymentHeader - Parsed x402 payment header\n * @param requirements - Payment requirements\n * @returns SettleRequest body ready for fetch/axios\n */\n/**\n * Describes the protected resource, as x402 v2 expects it.\n *\n * Note this is an OBJECT in v2. Sending a bare URL string here is the single\n * most common v2 mistake and it fails as an unhelpful \"no variant matched\"\n * deserialization error at the facilitator, naming no field.\n */\nexport interface ResourceInfoV2 {\n url: string;\n description: string;\n mimeType: string;\n}\n\n/**\n * Payment requirements in x402 v2 form.\n *\n * Differences from v1 that actually bite:\n * - `network` is CAIP-2 (`eip155:8453`), NOT a plain name (`base`). Mixing a v1\n * name into a v2 request fails deserialization, and vice versa.\n * - `maxAmountRequired` is renamed to `amount`.\n * - `resource` / `description` / `mimeType` moved out to {@link ResourceInfoV2}.\n */\nexport interface PaymentRequirementsV2 {\n scheme: string;\n /** CAIP-2 chain id, e.g. `eip155:8453`. */\n network: string;\n asset: string;\n amount: string;\n payTo: string;\n maxTimeoutSeconds: number;\n extra?: unknown;\n}\n\n/** The v2 payment payload — note it carries no top-level scheme/network. */\nexport interface PaymentPayloadV2 {\n x402Version: 2;\n resource: ResourceInfoV2;\n accepted: PaymentRequirementsV2;\n payload: X402PayloadData;\n extensions?: Record<string, unknown>;\n}\n\n/**\n * Verify request body in x402 v2 form.\n *\n * There is deliberately NO `paymentRequirements` key: that is the v1 envelope.\n * v2 carries `resource` and `accepted` at the top level instead.\n */\nexport interface VerifyRequestV2 {\n x402Version: 2;\n paymentPayload: PaymentPayloadV2;\n resource: ResourceInfoV2;\n accepted: PaymentRequirementsV2;\n}\n\n/** Settle request body in x402 v2 form. Same shape as {@link VerifyRequestV2}. */\nexport type SettleRequestV2 = VerifyRequestV2;\n\nfunction buildV2Envelope(\n payload: X402PayloadData,\n resource: ResourceInfoV2,\n accepted: PaymentRequirementsV2\n): VerifyRequestV2 {\n return {\n x402Version: 2,\n // The facilitator reads the payload from here; `resource` and `accepted` are\n // repeated at the top level because the v2 envelope declares both.\n paymentPayload: { x402Version: 2, resource, accepted, payload },\n resource,\n accepted,\n };\n}\n\n/**\n * Build a verify request for the facilitator `/verify` endpoint, in **v2** form.\n *\n * Use this whenever your 402 advertises CAIP-2 networks. {@link buildVerifyRequest}\n * emits the v1 envelope `{x402Version, paymentPayload, paymentRequirements}` and\n * cannot express v2 — putting a v2 payload inside it matches no variant at the\n * facilitator and fails with an error that names no field.\n *\n * @example\n * ```ts\n * const body = buildVerifyRequestV2(\n * payment.payload,\n * { url: 'https://api.example.com/thing', description: 'Thing', mimeType: 'application/json' },\n * { scheme: 'exact', network: 'eip155:8453', asset: '0x8335...', amount: '100000',\n * payTo: '0xabc...', maxTimeoutSeconds: 300 }\n * );\n * ```\n */\nexport function buildVerifyRequestV2(\n payload: X402PayloadData,\n resource: ResourceInfoV2,\n accepted: PaymentRequirementsV2\n): VerifyRequestV2 {\n return buildV2Envelope(payload, resource, accepted);\n}\n\n/**\n * Build a settle request for the facilitator `/settle` endpoint, in **v2** form.\n *\n * See {@link buildVerifyRequestV2} — the envelope is identical.\n */\nexport function buildSettleRequestV2(\n payload: X402PayloadData,\n resource: ResourceInfoV2,\n accepted: PaymentRequirementsV2\n): SettleRequestV2 {\n return buildV2Envelope(payload, resource, accepted);\n}\n\nexport function buildSettleRequest(\n paymentHeader: X402Header,\n requirements: PaymentRequirements\n): SettleRequest {\n return {\n // `1` for the same reason as {@link buildVerifyRequest}: it names the\n // envelope, and `/settle` takes the same body as `/verify`.\n x402Version: 1,\n paymentPayload: paymentHeader,\n paymentRequirements: requirements,\n };\n}\n\n// ----------------------------------------------------------------------------\n// CHOOSING THE ENVELOPE\n// ----------------------------------------------------------------------------\n//\n// Everything above emits ONE envelope and makes the caller pick. That is the\n// whole defect: `FacilitatorClient` picked v1 unconditionally, so a seller whose\n// 402 advertised v2 -- which `createHonoMiddleware` does on its own the moment\n// the accepts carry CAIP-2 ids -- could not call the facilitator at all, and\n// every consumer had to port the v2 body by hand. The functions below make the\n// version a decision rather than a constant.\n\n/**\n * Networks are CAIP-2 in v2 (`eip155:8453`) and plain names in v1 (`base`).\n *\n * The colon is the whole test, and it is the same one `create402Response` and\n * `normalizeRequirementForVersion` already use. Note the SDK's XRPL entries\n * carry no CAIP-2 id yet (the facilitator publishes `xrpl:0` / `xrpl:1`, the\n * registry does not), so XRPL stays on v1 here -- see the CHANGELOG for 2.85.0.\n */\nfunction isCaip2Network(network: string | undefined): boolean {\n return typeof network === 'string' && network.includes(':');\n}\n\n/**\n * The network a payment payload is speaking, wherever that payload keeps it.\n *\n * A **v1** header carries `network` at the top level. A **v2** payload does not\n * carry one AT ALL -- look at {@link PaymentPayloadV2}: there is no top-level\n * `network`, because v2 moved the chain id into `accepted`. So reading only\n * `payload.network` threw\n *\n * TypeError: Cannot read properties of undefined (reading 'includes')\n *\n * on exactly the shape {@link resolveEnvelopeVersion} exists to route -- the\n * default `'auto'` was unusable for any caller holding a real v2 payload.\n * Measured in runtime against 2.78.0, and it is why MeshRelay's turnstile and\n * multibrain pin `x402Version` to 1 or 2 rather than use our default.\n *\n * Undefined is a legitimate answer (a JS caller can hand over anything), and it\n * simply means \"this payload contributes no CAIP-2 evidence\".\n */\nfunction networkOfPayload(payload: X402Header | PaymentPayloadV2): string | undefined {\n const top = (payload as { network?: unknown }).network;\n if (typeof top === 'string') return top;\n const accepted = (payload as { accepted?: { network?: unknown } }).accepted;\n return typeof accepted?.network === 'string' ? accepted.network : undefined;\n}\n\n/**\n * Derive the v2 `resource` object from v1-shaped requirements.\n *\n * v2 moved `resource` / `description` / `mimeType` out of the requirements and\n * into an object of their own, and the facilitator requires ALL THREE keys:\n * measured 2026-09-03, a `resource` carrying only `url` is a 400.\n *\n * The `??` defaults are not decoration. `PaymentRequirements` types these as\n * required, but a JavaScript caller can still hand over an object without them,\n * and a missing key does not fail with \"description is missing\" -- it fails with\n * `data did not match any variant of untagged enum VerifyRequestEnvelope`, which\n * names no field. That error is what cost two teams a day.\n */\nexport function toResourceInfoV2(requirements: PaymentRequirements): ResourceInfoV2 {\n return {\n url: requirements.resource,\n description: requirements.description ?? DEFAULT_PAYMENT_DESCRIPTION,\n mimeType: requirements.mimeType ?? DEFAULT_PAYMENT_MIME_TYPE,\n };\n}\n\n/**\n * Derive v2 `accepted` requirements from v1-shaped requirements.\n *\n * Two renames do the damage, and neither is reported by name when it is wrong:\n * - `maxAmountRequired` is spelled `amount` in v2.\n * - `network` must be CAIP-2; a plain name inside a v2 body is a 400.\n *\n * `extra` is carried through when present -- it is where the EIP-712 domain\n * `name`/`version` live for tokens the facilitator does not know by address, so\n * dropping it breaks EURC and the bridged USDCs.\n *\n * @throws If `requirements.network` has NO CAIP-2 form. `chainToCAIP2` answers\n * with the name unchanged when it does not know a chain, and XRPL maps to\n * itself on purpose -- its v1 string IS its network id. Passing that through\n * would put a plain name inside a v2 body, which is a measured 400 (the same\n * `no variant matched` that names no field). Only reachable by PINNING version\n * 2 on such a network; `auto` leaves them on v1, where they work. Failing here\n * names the network and the fix, which a 400 from the facilitator does not.\n */\nexport function toPaymentRequirementsV2(\n requirements: PaymentRequirements\n): PaymentRequirementsV2 {\n const network = isCaip2Network(requirements.network)\n ? requirements.network\n : chainToCAIP2(requirements.network);\n if (!isCaip2Network(network)) {\n throw new Error(\n `Network '${requirements.network}' has no CAIP-2 form, so it cannot travel in ` +\n 'the x402 v2 envelope. Use x402Version: 1 for this network.'\n );\n }\n\n return {\n scheme: requirements.scheme,\n network,\n asset: requirements.asset,\n amount: requirements.maxAmountRequired,\n payTo: requirements.payTo,\n // Required by the facilitator: omitting it is a 400, measured the same day.\n maxTimeoutSeconds: requirements.maxTimeoutSeconds ?? DEFAULT_PAYMENT_TIMEOUT_SECONDS,\n ...(requirements.extra !== undefined ? { extra: requirements.extra } : {}),\n };\n}\n\n/**\n * Decide which envelope this (payment, requirements) pair has to travel in.\n *\n * `requested` wins when it names a version; `'auto'` (the default) reads the\n * wire.\n *\n * **Auto keys off CAIP-2, NOT off `paymentHeader.x402Version`,** and that is a\n * measured decision rather than a stylistic one. The facilitator's envelope enum\n * is untagged: it matches on SHAPE and ignores the version marker.\n *\n * Re-measured against `https://facilitator.ultravioletadao.xyz/verify` on\n * **2026-09-04** with a fabricated signature. The signature never verifies, so\n * every row is an HTTP 400 and the STATUS discriminates nothing -- what does is\n * the error code. `invalid_request_body` means the facilitator could not\n * deserialize the body; `contract_call_failed` means it read the body, resolved\n * the chain and got as far as the on-chain call, i.e. the envelope was fine.\n *\n * | payload network | requirements network | v1 envelope today |\n * |-----------------|----------------------|-------------------|\n * | `base` | `base` | understood |\n * | `base` (header says `x402Version: 2`) | `base` | understood |\n * | `eip155:8453` | `base` | understood |\n * | `base` | `eip155:8453` | understood |\n * | `eip155:8453` | `eip155:8453` | understood |\n *\n * **The last three rows used to be a hard 400** (`unknown variant\n * \\`eip155:8453\\``) when this function was written on 2026-09-03. The\n * facilitator has since taught the v1 envelope to read CAIP-2, so the original\n * argument for this rule -- \"every CAIP-2 combination is already a 400, so\n * upgrading them cannot regress anyone\" -- **is no longer true**. The rule is\n * unchanged; three other reasons hold it up:\n *\n * 1. A CAIP-2 network on the wire means the 402 that produced it advertised v2.\n * Answering in v2 is speaking the protocol the seller announced.\n * 2. v2-with-CAIP-2 is the only shape BOTH generations of the facilitator\n * accept. v1-with-CAIP-2 is a hard 400 on any build older than 2026-09-04,\n * so choosing v1 there is what breaks against a self-hosted or pinned one.\n * 3. The Python SDK resolves the identical rule, so the same wire produces the\n * same body in both SDKs -- pinned by phase 6 of `npm run test:xlang`.\n *\n * And the marker still decides nothing: row 2 above is served correctly today,\n * so upgrading on the strength of it would change a call that works.\n *\n * The negative half of that measurement, without which \"understood\" proves\n * nothing -- the same run, bodies broken on purpose, all three\n * `invalid_request_body`: a v2 body carrying a plain network name, one with\n * `resource` as a bare string, and one with `accepted` removed. A well-formed\n * v2 body with CAIP-2 reached `contract_call_failed` like the rows above.\n */\nexport function resolveEnvelopeVersion(\n paymentHeader: X402Header | PaymentPayloadV2,\n requirements: PaymentRequirements,\n requested: X402Version | 'auto' = 'auto'\n): X402Version {\n if (requirements.network?.startsWith('hedera:') && requested === 1) {\n throw new Error('Native Hedera supports only x402 v2');\n }\n if (requested !== 'auto') {\n return requested;\n }\n\n return isCaip2Network(networkOfPayload(paymentHeader)) ||\n isCaip2Network(requirements.network)\n ? 2\n : 1;\n}\n\n/**\n * Build a `/verify` body in whichever envelope `version` names.\n *\n * The v1 return is byte-for-byte what {@link buildVerifyRequest} produces, so\n * pinning `1` is exactly today's behaviour.\n *\n * @example\n * ```ts\n * const version = resolveEnvelopeVersion(payment, requirements);\n * const body = buildVerifyRequestForVersion(payment, requirements, version);\n * ```\n */\nexport function buildVerifyRequestForVersion(\n paymentHeader: X402Header,\n requirements: PaymentRequirements,\n version: X402Version\n): VerifyRequest | VerifyRequestV2 {\n if (version === 2) {\n return buildVerifyRequestV2(\n paymentHeader.payload,\n toResourceInfoV2(requirements),\n toPaymentRequirementsV2(requirements)\n );\n }\n\n return buildVerifyRequest(paymentHeader, requirements);\n}\n\n/**\n * Build a `/settle` body in whichever envelope `version` names.\n *\n * See {@link buildVerifyRequestForVersion} -- `/settle` takes the same body as\n * `/verify` in both versions.\n */\nexport function buildSettleRequestForVersion(\n paymentHeader: X402Header,\n requirements: PaymentRequirements,\n version: X402Version\n): SettleRequest | SettleRequestV2 {\n if (version === 2) {\n return buildSettleRequestV2(\n paymentHeader.payload,\n toResourceInfoV2(requirements),\n toPaymentRequirementsV2(requirements)\n );\n }\n\n return buildSettleRequest(paymentHeader, requirements);\n}\n\n// ============================================================================\n// CORS CONFIGURATION\n// ============================================================================\n\n/**\n * Recommended CORS headers for x402 payment APIs\n *\n * These headers allow browsers to send payment headers in cross-origin requests.\n */\nexport const X402_CORS_HEADERS = {\n 'Access-Control-Allow-Headers':\n 'Content-Type, X-PAYMENT, PAYMENT-SIGNATURE, X-UVD-Purchase, Authorization',\n 'Access-Control-Expose-Headers':\n 'X-PAYMENT-RESPONSE, PAYMENT-RESPONSE, PAYMENT-REQUIRED',\n 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',\n} as const;\n\n/**\n * All x402 custom header names that should be allowed in CORS\n */\nexport const X402_HEADER_NAMES = [\n 'X-PAYMENT',\n 'PAYMENT-SIGNATURE',\n 'X-PAYMENT-RESPONSE',\n 'PAYMENT-RESPONSE',\n 'PAYMENT-REQUIRED',\n 'X-UVD-Purchase',\n] as const;\n\n/**\n * Get CORS headers with custom origin\n *\n * @param origin - Allowed origin (use '*' for any, or specific domain)\n * @returns Complete CORS headers object\n *\n * @example\n * ```ts\n * // Express.js middleware\n * app.use((req, res, next) => {\n * const corsHeaders = getCorsHeaders('https://myapp.com');\n * Object.entries(corsHeaders).forEach(([key, value]) => {\n * res.setHeader(key, value);\n * });\n * if (req.method === 'OPTIONS') {\n * return res.status(204).end();\n * }\n * next();\n * });\n * ```\n */\nexport function getCorsHeaders(origin: string = '*'): Record<string, string> {\n return {\n 'Access-Control-Allow-Origin': origin,\n ...X402_CORS_HEADERS,\n };\n}\n\n// ============================================================================\n// FACILITATOR CLIENT\n// ============================================================================\n\n/** The header that binds `/verify` and `/settle` of one payment to one purchase. */\nexport const IDEMPOTENCY_KEY_HEADER = 'Idempotency-Key';\n\n/** The header with which the facilitator marks a stored answer, not a new settle. */\nexport const IDEMPOTENT_REPLAYED_HEADER = 'Idempotent-Replayed';\n\n/**\n * A new, unguessable `Idempotency-Key` for ONE payment.\n *\n * Send the same key on that payment's `/verify` and `/settle` and on every\n * retry of either; after a lost response, the key is what earns the\n * facilitator's original answer back. It is random on purpose: a key derived\n * from the X-PAYMENT would be known to anyone holding the payment, and holding\n * the payment is exactly what the facilitator refuses to accept as a binding.\n * Persist it with your order if you need to resume after a restart.\n */\nexport function createIdempotencyKey(): string {\n return `x402-${bytesToHex(randomBytes(32))}`;\n}\n\n/** Throws on a key the facilitator or a header cannot carry. */\nfunction checkIdempotencyKey(key: string): string {\n // `receipt:` is reserved by the facilitator (400 reserved_idempotency_key),\n // and the legacy store uses the key as a table key: keep it short and plain.\n if (typeof key !== 'string' || !/^[\\x21-\\x7e]{1,255}$/.test(key) || key.startsWith('receipt:')) {\n throw new Error('idempotencyKey must be 1-255 visible ASCII characters and must not start with \"receipt:\"');\n }\n return key;\n}\n\n/** Whether the facilitator marked this answer `Idempotent-Replayed: true`. */\nfunction isReplayed(response: { headers?: { get?: (name: string) => string | null } }): boolean {\n try {\n return response?.headers?.get?.(IDEMPOTENT_REPLAYED_HEADER)?.trim().toLowerCase() === 'true';\n } catch {\n return false;\n }\n}\n\n/**\n * A replay that the request did not bind is somebody else's purchase.\n *\n * Only for a settle whose key is fresh and which carried no purchase context:\n * such a call cannot have admitted the authorization, so a replay reached it\n * through possession of the payment alone. Answered the way facilitator 2.39.0\n * answers it -- `authorization_already_settled` / `authorization_in_flight` --\n * without the success artefacts a caller could deliver on. The receipt stays.\n * A replayed rejection is still the original rejection and passes unchanged.\n */\nfunction refuseUnboundReplay(result: SettleResponse): SettleResponse {\n if (!result.replayed) return result;\n const pending = result.receipt?.status === 'pending' || result.receipt?.status === 'unknown'\n || result.errorCode === 'settlement_in_progress';\n if (!result.success && !pending) return result;\n const {\n transactionHash: _tx, proofOfPayment: _proof, paymentId: _id, transaction: _t,\n retryAfterSeconds, ...rest\n } = result;\n if (result.success) {\n return { ...rest, success: false, error: AUTHORIZATION_ALREADY_SETTLED,\n errorCode: AUTHORIZATION_ALREADY_SETTLED, retryable: false, safeToReplay: false };\n }\n return { ...rest, success: false, error: AUTHORIZATION_IN_FLIGHT, errorCode: AUTHORIZATION_IN_FLIGHT,\n retryable: true, safeToReplay: false, retryAfterSeconds: retryAfterSeconds ?? DEFAULT_RETRY_AFTER_SECONDS };\n}\n\n/** Per-call options of {@link FacilitatorClient.verify} and {@link FacilitatorClient.settle}. */\nexport interface FacilitatorCallOptions {\n /** A validated `X-UVD-Purchase` value, forwarded unchanged (see `validatePurchaseContext`). */\n receiptContext?: string;\n /**\n * The payment's `Idempotency-Key` (see {@link createIdempotencyKey}). Pass the\n * SAME key to `verify` and `settle` of one payment and to their retries.\n * Omitted, the call sends a fresh key and reports it back as\n * `result.idempotencyKey`.\n */\n idempotencyKey?: string;\n}\n\n/** Headers of a `/verify` or `/settle` call: the payment's binding travels on both. */\nfunction facilitatorHeaders(idempotencyKey: string, receiptContext?: string): Record<string, string> {\n return {\n 'Content-Type': 'application/json',\n [IDEMPOTENCY_KEY_HEADER]: idempotencyKey,\n ...(receiptContext ? { 'X-UVD-Purchase': receiptContext } : {}),\n };\n}\n\n/**\n * The failure fields of a `/verify` that names an admitted authorization.\n *\n * `/verify` answers these with HTTP 200 and `isValid: false`, so without this\n * they look like a refused signature -- and a 402 asks the buyer to sign again\n * for a purchase that is already paid or being paid.\n */\nfunction admittedVerdict(result: { isValid?: unknown; invalidReason?: unknown }): FacilitatorFailureFields {\n if (result.isValid !== false) return {};\n if (result.invalidReason === AUTHORIZATION_IN_FLIGHT) {\n return { errorCode: AUTHORIZATION_IN_FLIGHT, retryable: true, safeToReplay: false,\n retryAfterSeconds: DEFAULT_RETRY_AFTER_SECONDS };\n }\n if (result.invalidReason === AUTHORIZATION_ALREADY_SETTLED) {\n return { errorCode: AUTHORIZATION_ALREADY_SETTLED, retryable: false, safeToReplay: false };\n }\n return {};\n}\n\n/**\n * Options for the FacilitatorClient\n */\nexport interface FacilitatorClientOptions {\n /** Base URL of the facilitator (default: https://facilitator.ultravioletadao.xyz) */\n baseUrl?: string;\n /**\n * Request timeout in milliseconds (default: auto per network).\n * When not set, the client uses per-network defaults from ESCROW_TIMEOUT_MS\n * (960s for Ethereum L1, 90s for L2s, 30s for others).\n * Set explicitly to override per-network auto-detection.\n */\n timeout?: number;\n /**\n * Extra attempts after the first when the facilitator answers a refusal it\n * proved it did not execute (`safeToReplay`). Default 2; `0` disables.\n *\n * Only ever spent on `429` and on a `503` naming a pre-execution writer-lease\n * reason. An ambiguous `forward_failed` -- whose write may already have landed\n * -- is never replayed here, at any setting.\n */\n retries?: number;\n /**\n * Which envelope to send to `/verify` and `/settle`. Default `'auto'`.\n *\n * `'auto'` reads the wire: CAIP-2 networks get the v2 envelope, plain names\n * get v1. See {@link resolveEnvelopeVersion} for the measurements behind that\n * rule. Pin `1` or `2` to take the decision yourself -- a pin is honoured\n * even when it contradicts the wire, because choosing the version is the\n * point of the option.\n */\n x402Version?: X402Version | 'auto';\n}\n\n/**\n * Client for interacting with the x402 facilitator API\n *\n * @example\n * ```ts\n * const client = new FacilitatorClient();\n *\n * // Verify a payment\n * const verifyResult = await client.verify(paymentHeader, requirements);\n * if (!verifyResult.isValid) {\n * return res.status(402).json({ error: verifyResult.invalidReason });\n * }\n *\n * // Provide the service, then settle\n * const settleResult = await client.settle(paymentHeader, requirements);\n * if (!settleResult.success) {\n * // Handle settlement failure (maybe refund or retry)\n * }\n * ```\n */\nexport class FacilitatorClient {\n private readonly baseUrl: string;\n private readonly timeout: number;\n private readonly explicitTimeout: boolean;\n private readonly retries: number | undefined;\n private readonly x402Version: X402Version | 'auto';\n\n constructor(options: FacilitatorClientOptions = {}) {\n this.baseUrl = options.baseUrl || 'https://facilitator.ultravioletadao.xyz';\n this.explicitTimeout = options.timeout !== undefined;\n this.timeout = options.timeout || 30000;\n this.retries = options.retries;\n this.x402Version = options.x402Version ?? 'auto';\n }\n\n /**\n * Get timeout for a specific network, using per-chain defaults when no explicit timeout was set.\n */\n private getTimeout(network?: string): number {\n if (this.explicitTimeout) return this.timeout;\n if (!network) return this.timeout;\n // Extract chainId from CAIP-2 format (eip155:1) or legacy names\n const match = network.match(/^eip155:(\\d+)$/);\n if (match) {\n const chainId = parseInt(match[1], 10);\n return ESCROW_TIMEOUT_MS[chainId] || this.timeout;\n }\n // Legacy network name mapping for Ethereum\n if (network === 'ethereum' || network === 'ethereum-mainnet') return ESCROW_TIMEOUT_MS[1];\n return this.timeout;\n }\n\n /**\n * Verify a payment with the facilitator\n *\n * Call this before providing the paid resource to validate the payment.\n *\n * An authorization the facilitator already admitted for another request\n * comes back invalid with `errorCode` {@link AUTHORIZATION_ALREADY_SETTLED}\n * (do not serve, do not ask for a new signature) or\n * {@link AUTHORIZATION_IN_FLIGHT} (`retryable`: the same request learns the\n * verdict later). Neither is a rejected payment: never answer them with 402.\n *\n * @param paymentHeader - Parsed x402 payment header\n * @param requirements - Payment requirements\n * @param options - Purchase context and the payment's `idempotencyKey`\n * @returns Verification result\n */\n async verify(\n paymentHeader: X402Header,\n requirements: PaymentRequirements,\n options: FacilitatorCallOptions = {},\n ): Promise<VerifyResponse> {\n const idempotencyKey = checkIdempotencyKey(options.idempotencyKey ?? createIdempotencyKey());\n // Not `buildVerifyRequest` any more. That one only speaks v1, so a seller\n // advertising CAIP-2 -- which this SDK's own Hono middleware does by itself\n // -- could not reach the facilitator at all: the body came back 400 with\n // `unknown variant \\`eip155:8453\\``, and the buyer saw a broken checkout.\n const body = buildVerifyRequestForVersion(\n paymentHeader,\n requirements,\n resolveEnvelopeVersion(paymentHeader, requirements, this.x402Version)\n );\n\n try {\n const { response, error } = await facilitatorFetch(\n `${this.baseUrl}/verify`,\n {\n method: 'POST',\n headers: facilitatorHeaders(idempotencyKey, options.receiptContext),\n body: JSON.stringify(body),\n },\n { timeoutMs: this.timeout, retries: this.retries },\n );\n\n if (error) {\n // `isValid: false` is unavoidable -- nothing was validated -- but it is\n // no longer the whole story. A caller that answers 402 on this without\n // reading `retryable` tells the buyer their payment was REFUSED and\n // asks them to sign another one, for a payment the facilitator never\n // looked at. That is the double-charge this field exists to prevent.\n return {\n isValid: false,\n invalidReason: error.error,\n ...failureFields(error),\n receipt: receiptFromErrorBody(error.body),\n idempotencyKey,\n };\n }\n\n const result = await response.json();\n return { ...result, ...admittedVerdict(result), receipt: parseFacilitatorReceipt(result.receipt), idempotencyKey };\n } catch (error) {\n // A thrown error is a transport failure (timeout, DNS, connection reset).\n // No verdict was reached either, so it is retryable for exactly the same\n // reason a 503 is -- and it used to be reported as an invalid payment.\n return {\n isValid: false,\n invalidReason: error instanceof Error ? error.message : 'Unknown error',\n retryable: true,\n safeToReplay: false,\n retryAfterSeconds: DEFAULT_RETRY_AFTER_SECONDS,\n idempotencyKey,\n };\n }\n }\n\n /**\n * Settle a payment with the facilitator\n *\n * Call this after providing the paid resource to execute the on-chain transfer.\n *\n * Send the `idempotencyKey` the payment was verified with, and the same one\n * on any retry: it is the binding that earns the original answer back after\n * a lost response (`replayed: true`). Without it, or with another one, an\n * authorization already admitted comes back `409`\n * {@link AUTHORIZATION_ALREADY_SETTLED}, {@link AUTHORIZATION_IN_FLIGHT} or\n * {@link RECEIPT_REQUEST_CONFLICT} -- the X-PAYMENT was used; do not serve it\n * again. With no key and no context the call uses a fresh key, so a replay\n * it receives is refused the same way.\n *\n * @param paymentHeader - Parsed x402 payment header\n * @param requirements - Payment requirements\n * @param options - Purchase context and the payment's `idempotencyKey`\n * @returns Settlement result with transaction hash\n */\n async settle(\n paymentHeader: X402Header,\n requirements: PaymentRequirements,\n options: FacilitatorCallOptions = {},\n ): Promise<SettleResponse> {\n // A fresh key with no purchase context binds nothing an earlier settle\n // could have admitted, so any replay this call receives is unbound.\n const unbound = options.idempotencyKey === undefined && !options.receiptContext;\n const idempotencyKey = checkIdempotencyKey(options.idempotencyKey ?? createIdempotencyKey());\n const body = buildSettleRequestForVersion(\n paymentHeader,\n requirements,\n resolveEnvelopeVersion(paymentHeader, requirements, this.x402Version)\n );\n const settleTimeout = this.getTimeout(requirements.network);\n\n try {\n // A `/settle` refusal that the facilitator proved it did not execute is\n // replayed here with the SAME authorization. That is safe twice over: the\n // facilitator refused in its router before signing anything, and the\n // authorization carries a single-use nonce the chain rejects on a real\n // duplicate. What is NOT replayed is `forward_failed` -- the hop to the\n // lease holder died after handing the write over, so the transfer may\n // already be mining.\n const { response, error } = await facilitatorFetch(\n `${this.baseUrl}/settle`,\n {\n method: 'POST',\n // The same init, key included, goes out on every automatic retry.\n headers: facilitatorHeaders(idempotencyKey, options.receiptContext),\n body: JSON.stringify(body),\n },\n { timeoutMs: settleTimeout, retries: this.retries },\n );\n\n if (error) {\n return {\n success: false,\n error: error.error,\n ...failureFields(error),\n receipt: receiptFromErrorBody(error.body),\n idempotencyKey,\n };\n }\n\n const result = await response.json();\n // Read all three spellings. The facilitator's canonical name for this\n // field is `transaction`, and this client used to read only the two\n // camel/snake variants — so it silently returned `undefined` for the\n // most important field a settle produces. A consumer failed closed on\n // that and revoked access to a payment that had already settled\n // on-chain: the money moved, the receipt was unreadable.\n //\n // The server now emits all three, but this fallback stays: it makes the\n // client work against facilitators that have not deployed that yet, and\n // against any that only ever emitted the canonical name.\n const transactionHash =\n result.transaction ?? result.transactionHash ?? result.transaction_hash;\n if (result.success && !transactionHash) {\n // Never let a missing hash pass as a normal success. A caller that\n // gates access on the receipt needs to know the receipt is absent,\n // not infer it from an undefined field.\n console.warn(\n '[x402] settle reported success but carried no transaction hash under ' +\n 'transaction/transactionHash/transaction_hash — treat delivery as unconfirmed'\n );\n }\n const settled: SettleResponse = {\n // Read the facilitator's verdict instead of asserting one.\n //\n // This was the literal `true`, so a settle was reported successful\n // whenever the HTTP call was — and \"the request arrived\" is not \"the\n // money moved\". A payment that MINES AND THEN REVERTS is answered with\n // 200 and `success: false` (x402-rs src/chain/evm.rs:1343, serialised\n // through StatusCode::OK), which is precisely the case a caller most\n // needs to hear about. Every consumer doing `result.success === true`\n // was reading a constant, so a reverted payment was booked as settled\n // and no reconciliation path could ever fire.\n //\n // Absent `success` is treated as NOT successful: a facilitator that\n // does not say it worked has not said it worked.\n success: result.success === true,\n transactionHash,\n network: result.network,\n // Why it failed, when it did. Without this the caller gets `success:\n // false` and no way to tell a reverted transfer from a rejected\n // authorization except by parsing prose.\n errorReason: result.errorReason ?? result.error_reason,\n // The settlement proof, when the facilitator attached one (it does for\n // the ERC-8004 extension). Dropping it here made `verified: true`\n // unreachable for DX402 anchoring through this client: `anchorEvidence`\n // documents proofOfPayment as the only thing that gets there, the\n // facilitator returns it, and this method threw it away — so a seller\n // using the SDK end to end could only ever produce provisional anchors.\n proofOfPayment: result.proofOfPayment ?? result.proof_of_payment,\n payer: result.payer,\n receipt: parseFacilitatorReceipt(result.receipt),\n paymentId: result.paymentId,\n ...(result.receipt?.status === \"unknown\" || result.receipt?.status === \"pending\" ? { retryable: true, safeToReplay: false } : {}),\n // `202 settlement_in_progress` and friends: a 2xx that names its state.\n ...(!result.success && typeof result.error === 'string' && result.error ? { errorCode: result.error } : {}),\n ...(isReplayed(response) ? { replayed: true } : {}),\n idempotencyKey,\n };\n return unbound ? refuseUnboundReplay(settled) : settled;\n } catch (error) {\n // Timeout or connection failure. The write may have landed -- this is the\n // same ambiguity as `forward_failed`, so it is retryable but never\n // replayed automatically. Reconcile on-chain, or by transaction hash,\n // before sending anything again -- with `idempotencyKey`, which is what\n // gets the original answer back.\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error',\n retryable: true,\n safeToReplay: false,\n retryAfterSeconds: DEFAULT_RETRY_AFTER_SECONDS,\n idempotencyKey,\n };\n }\n }\n\n /**\n * Verify and settle atomically\n *\n * Convenience method that verifies first, then settles if valid.\n * Use this for simple payment flows where you don't need custom logic between verify and settle.\n *\n * Both steps carry ONE `Idempotency-Key` (`options.idempotencyKey`, or a\n * fresh one reported back as `idempotencyKey`). With a fresh key and no\n * purchase context, a replay of an earlier settle is not this purchase and\n * comes back `settled: false` with `errorCode`\n * {@link AUTHORIZATION_ALREADY_SETTLED}.\n *\n * @param paymentHeader - Parsed x402 payment header\n * @param requirements - Payment requirements\n * @param options - Purchase context and the payment's `idempotencyKey`\n * @returns Combined result with verify and settle status\n */\n async verifyAndSettle(\n paymentHeader: X402Header,\n requirements: PaymentRequirements,\n options: FacilitatorCallOptions = {},\n ): Promise<\n {\n verified: boolean;\n settled: boolean;\n transactionHash?: string;\n error?: string;\n /** The facilitator answered from its record of an earlier settle. */\n replayed?: boolean;\n /** The key both steps carried. Merchant-private. */\n idempotencyKey: string;\n } & FacilitatorFailureFields\n > {\n const unbound = options.idempotencyKey === undefined && !options.receiptContext;\n const binding = { ...options, idempotencyKey: checkIdempotencyKey(options.idempotencyKey ?? createIdempotencyKey()) };\n const { idempotencyKey } = binding;\n // Verify first\n const verifyResult = await this.verify(paymentHeader, requirements, binding);\n if (!verifyResult.isValid) {\n // Carry the refusal's shape up. Flattening it to `verified: false` here\n // would undo the whole point one level below: the caller could not tell a\n // rejected authorization from a facilitator that never answered.\n return {\n verified: false,\n settled: false,\n error: verifyResult.invalidReason,\n ...carryFailureFields(verifyResult),\n idempotencyKey,\n };\n }\n\n // Settle, under the key the verification carried.\n const answered = await this.settle(paymentHeader, requirements, binding);\n const settleResult = unbound ? refuseUnboundReplay(answered) : answered;\n return {\n verified: true,\n settled: settleResult.success,\n transactionHash: settleResult.transactionHash,\n error: settleResult.error,\n ...carryFailureFields(settleResult),\n ...(settleResult.replayed ? { replayed: true } : {}),\n idempotencyKey,\n };\n }\n\n /**\n * Check if the facilitator is healthy\n *\n * @returns True if the facilitator is responding\n */\n async healthCheck(): Promise<boolean> {\n try {\n const response = await fetch(`${this.baseUrl}/health`, {\n method: 'GET',\n });\n return response.ok;\n } catch {\n return false;\n }\n }\n\n /**\n * Get the facilitator version info\n *\n * @returns Version info (e.g., { version: \"1.37.0\" })\n */\n async getVersion(): Promise<{ version: string; [key: string]: unknown }> {\n const response = await fetch(`${this.baseUrl}/version`, {\n method: 'GET',\n });\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`GET /version failed: ${response.status} - ${errorText}`);\n }\n return await response.json();\n }\n\n /**\n * Get the facilitator's supported networks and payment schemes\n *\n * @returns Supported networks/schemes with 'kinds' array\n *\n * @example\n * ```ts\n * const supported = await client.getSupported();\n * for (const kind of supported.kinds) {\n * console.log(`${kind.network} - ${kind.scheme}`);\n * }\n * ```\n */\n async getSupported(): Promise<{\n kinds: Array<{ network: string; scheme: string; [key: string]: unknown }>;\n [key: string]: unknown;\n }> {\n const response = await fetch(`${this.baseUrl}/supported`, {\n method: 'GET',\n });\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`GET /supported failed: ${response.status} - ${errorText}`);\n }\n return await response.json();\n }\n\n /**\n * Aggregated totals per network and asset (`GET /api/stats`).\n *\n * **An index, not a ledger.** Records are written best-effort AFTER\n * settlement, so an outage loses rows while payments proceed — verify\n * anything that matters against the transaction hash. Counting starts when\n * the operator enabled the store, so earlier operations are UNKNOWN, not\n * zero. And unless `X402_EVENTS_PUBLISH_FAILURES=true`, operations that ERROR\n * are not recorded at all: a 100% success rate means \"no failures were\n * recorded\".\n *\n * `volumeAtomic` is a STRING (u256-shaped; a JS number loses precision above\n * 2^53) and each row carries its own `decimals`. **Use that, never a\n * constant** — USDC is 6 decimals nearly everywhere and 18 on BSC, so scaling\n * by 6 there overstates volume by 10^12. `decimals` is null when the asset is\n * unrecognised; render the atomic value rather than guessing a scale.\n */\n async getStats(): Promise<{\n totals: { settlesOk: number; settlesFailed: number; verifies: number; networks: number };\n byNetworkAndAsset: Array<{\n network: string;\n asset: string;\n settlesOk: number;\n settlesFailed: number;\n verifies: number;\n volumeAtomic: string;\n decimals: number | null;\n lastTs: number;\n }>;\n [key: string]: unknown;\n }> {\n const response = await fetch(`${this.baseUrl}/api/stats`, { method: 'GET' });\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`GET /api/stats failed: ${response.status} - ${errorText}`);\n }\n return await response.json();\n }\n\n /**\n * Recent recorded operations, newest first (`GET /transactions`).\n *\n * There is **no pagination and no cursor**: this returns the newest N,\n * walking back at most 30 days. With 10,000 rows you get the newest 200, not\n * page one of fifty. `limit` is clamped to 200 by the facilitator.\n *\n * `network` matches the canonical slug `/supported` uses, which is not always\n * the alias you may send — `skale` is accepted inbound but records say\n * `skale-base`.\n */\n async getTransactions(options: { limit?: number; network?: string } = {}): Promise<{\n transactions: Array<Record<string, unknown>>;\n count: number;\n [key: string]: unknown;\n }> {\n const params = new URLSearchParams();\n if (options.limit !== undefined) params.set('limit', String(options.limit));\n if (options.network) params.set('network', options.network);\n const query = params.toString();\n const response = await fetch(\n `${this.baseUrl}/transactions${query ? `?${query}` : ''}`,\n { method: 'GET' }\n );\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`GET /transactions failed: ${response.status} - ${errorText}`);\n }\n return await response.json();\n }\n\n /**\n * Get the facilitator's blocked/sanctioned addresses\n *\n * @returns Blacklist info (totalBlocked, loadedAtStartup, addresses)\n *\n * @example\n * ```ts\n * const bl = await client.getBlacklist();\n * console.log(`Blocked: ${bl.totalBlocked} addresses`);\n * ```\n */\n async getBlacklist(): Promise<{\n totalBlocked: number;\n loadedAtStartup: boolean;\n [key: string]: unknown;\n }> {\n const response = await fetch(`${this.baseUrl}/blacklist`, {\n method: 'GET',\n });\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`GET /blacklist failed: ${response.status} - ${errorText}`);\n }\n return await response.json();\n }\n\n /**\n * Negotiate payment requirements with the facilitator via POST /accepts.\n *\n * Sends merchant payment requirements to the facilitator, which matches\n * them against its supported capabilities and returns enriched requirements\n * with facilitator data (feePayer, tokens, escrow configuration).\n *\n * This is used by Faremeter middleware and clients that need to discover\n * what the facilitator can settle before constructing payment authorizations.\n *\n * @param paymentRequirements - List of payment requirement objects\n * @param x402Version - x402 protocol version (default: 2)\n * @returns List of enriched payment requirements with facilitator extras\n *\n * @example\n * ```ts\n * const enriched = await client.accepts([\n * {\n * scheme: 'exact',\n * network: 'base-mainnet',\n * maxAmountRequired: '1000000',\n * resource: 'https://api.example.com/data',\n * payTo: '0xMerchant...',\n * },\n * ]);\n * // enriched[0].extra.feePayer is now set\n * ```\n */\n async accepts(\n paymentRequirements: PaymentRequirements[],\n x402Version: number = 2\n ): Promise<PaymentRequirements[]> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(`${this.baseUrl}/accepts`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n x402Version,\n accepts: paymentRequirements,\n }),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Facilitator /accepts error: ${response.status} - ${errorText}`);\n }\n\n const data = await response.json();\n return data.accepts || [];\n } catch (error) {\n clearTimeout(timeoutId);\n throw error;\n }\n }\n}\n\n// ============================================================================\n// ATOMIC PAYMENT HELPERS\n// ============================================================================\n\n/**\n * Create a 402 Payment Required response\n *\n * @param requirements - Payment requirements\n * @param options - Additional response options\n * @returns Object with status code, headers, and body for the 402 response\n *\n * @example\n * ```ts\n * // Express.js\n * app.get('/premium-data', (req, res) => {\n * const payment = extractPaymentFromHeaders(req.headers);\n *\n * if (!payment) {\n * const { status, headers, body } = create402Response({\n * amount: '1.00',\n * recipient: '0x...',\n * resource: 'https://api.example.com/premium-data',\n * });\n * return res.status(status).set(headers).json(body);\n * }\n *\n * // Verify and serve...\n * });\n * ```\n */\nexport function create402Response(\n requirements: PaymentRequirementsOptions,\n options: {\n accepts?: PaymentAcceptance[];\n } = {}\n): {\n status: 402;\n headers: Record<string, string>;\n body: Record<string, unknown>;\n} {\n const primaryRequirement = buildPaymentRequirements(requirements);\n const version = requirements.x402Version\n || ((options.accepts && options.accepts.length > 0)\n || primaryRequirement.network.includes(':')\n || (options.accepts || []).some((accept) => accept.network.includes(':'))\n ? 2\n : 1);\n const advertisedRequirements = [\n normalizeRequirementForVersion(primaryRequirement, version),\n ...(options.accepts || []).map((accept) =>\n buildRequirementFromAcceptance(accept, primaryRequirement.resource, version, primaryRequirement)\n ),\n ];\n const body = create402ResponseBody(advertisedRequirements[0], advertisedRequirements, version);\n\n return {\n status: 402,\n headers: {\n 'Content-Type': 'application/json',\n ...X402_CORS_HEADERS,\n },\n body,\n };\n}\n\nconst DEFAULT_PAYMENT_DESCRIPTION = 'Payment required';\nconst DEFAULT_PAYMENT_MIME_TYPE = 'application/json';\nconst DEFAULT_PAYMENT_TIMEOUT_SECONDS = 300;\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\nfunction resolveAdvertisedVersion(\n accepts: PaymentAcceptance[],\n requestedVersion?: X402Version | 'auto'\n): X402Version {\n if (requestedVersion && requestedVersion !== 'auto') {\n return requestedVersion;\n }\n\n if (accepts.length > 1 || accepts.some((accept) => accept.network.includes(':'))) {\n return 2;\n }\n\n return 1;\n}\n\nfunction normalizeRequirementForVersion(\n requirements: PaymentRequirements,\n version: X402Version\n): PaymentRequirements {\n return {\n ...requirements,\n network: version === 2\n ? (requirements.network.includes(':') ? requirements.network : chainToCAIP2(requirements.network))\n : (requirements.network.includes(':') ? parseNetworkIdentifier(requirements.network) : requirements.network),\n };\n}\n\nfunction buildRequirementFromAcceptance(\n accept: PaymentAcceptance,\n resource: string,\n version: X402Version,\n defaults?: PaymentRequirements\n): PaymentRequirements {\n const payTo = accept.payTo ?? defaults?.payTo;\n if (!payTo) {\n throw new Error('Payment accepts entries must include payTo');\n }\n\n return normalizeRequirementForVersion({\n // Honour a caller-supplied scheme; 'exact' is the default, not an override.\n // Hardcoding it silently discarded 'escrow' / 'commerce' accepts.\n scheme: (accept.scheme as PaymentRequirements['scheme']) ?? 'exact',\n network: accept.network,\n maxAmountRequired: accept.amount,\n resource: accept.resource ?? defaults?.resource ?? resource,\n description: accept.description ?? defaults?.description ?? DEFAULT_PAYMENT_DESCRIPTION,\n mimeType: accept.mimeType ?? defaults?.mimeType ?? DEFAULT_PAYMENT_MIME_TYPE,\n payTo,\n asset: accept.asset,\n maxTimeoutSeconds: accept.maxTimeoutSeconds ?? defaults?.maxTimeoutSeconds ?? DEFAULT_PAYMENT_TIMEOUT_SECONDS,\n ...(accept.outputSchema !== undefined\n ? { outputSchema: accept.outputSchema }\n : defaults?.outputSchema !== undefined\n ? { outputSchema: defaults.outputSchema }\n : {}),\n ...(accept.extra !== undefined\n ? { extra: accept.extra }\n : defaults?.extra !== undefined\n ? { extra: defaults.extra }\n : {}),\n }, version);\n}\n\nfunction toPaymentAcceptance(\n requirements: PaymentRequirements,\n facilitator?: string\n): PaymentAcceptance {\n return {\n network: requirements.network,\n asset: requirements.asset,\n amount: requirements.maxAmountRequired,\n // scheme is REQUIRED by the facilitator's v2 PaymentRequirementsV2. Dropping it\n // here produced an accepts[] entry that no v2 client could pay: the spec makes\n // the client echo the accept verbatim, so the omission travelled downstream and\n // died in deserialization with an error naming no field.\n scheme: requirements.scheme,\n payTo: requirements.payTo,\n resource: requirements.resource,\n description: requirements.description,\n mimeType: requirements.mimeType,\n maxTimeoutSeconds: requirements.maxTimeoutSeconds,\n ...(facilitator ? { facilitator } : {}),\n ...(requirements.outputSchema !== undefined ? { outputSchema: requirements.outputSchema } : {}),\n ...(requirements.extra !== undefined ? { extra: requirements.extra } : {}),\n };\n}\n\nfunction create402ResponseBody(\n primaryRequirement: PaymentRequirements,\n advertisedRequirements: PaymentRequirements[],\n version: X402Version,\n facilitator?: string\n): Record<string, unknown> {\n const normalizedPrimary = normalizeRequirementForVersion(primaryRequirement, version);\n const normalizedAdvertised = advertisedRequirements.map((requirements) =>\n normalizeRequirementForVersion(requirements, version)\n );\n\n const body: Record<string, unknown> = {\n x402Version: version,\n ...normalizedPrimary,\n };\n\n if (version === 2 && normalizedAdvertised.length > 1) {\n body.accepts = normalizedAdvertised.map((requirements) =>\n toPaymentAcceptance(requirements, facilitator)\n );\n }\n\n return body;\n}\n\nfunction getComparableNetwork(network: string): string {\n return parseNetworkIdentifier(network).toLowerCase();\n}\n\nfunction getPaymentRecipient(payment: X402Header): string | undefined {\n const payload = payment.payload as unknown;\n if (!isObject(payload)) {\n return undefined;\n }\n const authorization = payload.authorization;\n\n if (isObject(authorization) && typeof authorization.to === 'string') {\n return authorization.to.toLowerCase();\n }\n\n if (typeof payload.to === 'string') {\n return payload.to.toLowerCase();\n }\n\n return undefined;\n}\n\nfunction getPaymentAmount(payment: X402Header): string | undefined {\n const payload = payment.payload as unknown;\n if (!isObject(payload)) {\n return undefined;\n }\n const authorization = payload.authorization;\n\n if (isObject(authorization) && typeof authorization.value === 'string') {\n return authorization.value;\n }\n\n if (typeof payload.amount === 'string') {\n return payload.amount;\n }\n\n return undefined;\n}\n\nfunction getPaymentAsset(payment: X402Header): string | undefined {\n const payload = payment.payload as unknown;\n if (!isObject(payload)) {\n return undefined;\n }\n\n if (typeof payload.tokenContract === 'string') {\n return payload.tokenContract.toLowerCase();\n }\n\n return undefined;\n}\n\nasync function resolvePaymentRequirement(\n payment: X402Header,\n requirements: PaymentRequirements[],\n resolver?: PaymentRequirementResolver\n): Promise<{ requirement: PaymentRequirements | null; reason?: string }> {\n const normalizedRequirements = requirements.map((requirements) =>\n normalizeRequirementForVersion(requirements, payment.x402Version)\n );\n\n if (resolver) {\n const resolved = await resolver(payment, normalizedRequirements);\n return {\n requirement: resolved\n ? normalizeRequirementForVersion(resolved, payment.x402Version)\n : null,\n ...(resolved ? {} : { reason: 'Custom requirement resolver did not return a matching requirement.' }),\n };\n }\n\n const networkMatches = normalizedRequirements.filter((requirements) =>\n getComparableNetwork(requirements.network) === getComparableNetwork(payment.network)\n );\n\n if (networkMatches.length === 0) {\n return {\n requirement: null,\n reason: `No advertised payment requirement matched network ${payment.network}.`,\n };\n }\n\n let matches = networkMatches;\n\n const paymentRecipient = getPaymentRecipient(payment);\n if (paymentRecipient) {\n const recipientMatches = matches.filter((requirements) =>\n requirements.payTo.toLowerCase() === paymentRecipient\n );\n if (recipientMatches.length === 0) {\n return {\n requirement: null,\n reason: 'Payment recipient does not match any advertised requirement.',\n };\n }\n matches = recipientMatches;\n }\n\n const paymentAmount = getPaymentAmount(payment);\n if (paymentAmount) {\n const amountMatches = matches.filter((requirements) =>\n requirements.maxAmountRequired === paymentAmount\n );\n if (amountMatches.length === 0) {\n return {\n requirement: null,\n reason: 'Payment amount does not match any advertised requirement.',\n };\n }\n matches = amountMatches;\n }\n\n const paymentAsset = getPaymentAsset(payment);\n if (paymentAsset) {\n const assetMatches = matches.filter((requirements) =>\n requirements.asset.toLowerCase() === paymentAsset\n );\n if (assetMatches.length === 0) {\n return {\n requirement: null,\n reason: 'Payment asset does not match any advertised requirement.',\n };\n }\n matches = assetMatches;\n }\n\n if (matches.length !== 1) {\n return {\n requirement: null,\n reason: 'Payment matched multiple advertised requirements. Advertise unique network/payTo/amount combinations or provide resolveRequirement().',\n };\n }\n\n return { requirement: matches[0] };\n}\n\n/**\n * The settle of ONE merchant request, under the key its verification carried.\n *\n * The key is fresh for this request, so a replay without the buyer's\n * `X-UVD-Purchase` was earned by possession of the X-PAYMENT alone -- a resend,\n * not this purchase -- and is refused (see {@link refuseUnboundReplay}). With a\n * context, the facilitator already checked the buyer's capability, and a\n * replay is how a resumed purchase gets its answer back.\n */\nfunction createVerifiedPaymentState(\n client: FacilitatorClient,\n payment: X402Header,\n requirements: PaymentRequirements,\n verifyResult: VerifyResponse,\n binding: { idempotencyKey: string; receiptContext?: string },\n onSettled?: (result: SettleResponse) => void,\n): VerifiedPaymentState {\n let settlePromise: Promise<SettleResponse> | null = null;\n return {\n payment,\n requirements,\n verifyResult,\n idempotencyKey: binding.idempotencyKey,\n settle: () => {\n if (!settlePromise) {\n settlePromise = client.settle(payment, requirements, binding).then(answer => {\n const result = binding.receiptContext ? answer : refuseUnboundReplay(answer);\n // The payment is settled whatever happens to a header: never let\n // attaching the receipt turn this result into a rejected promise.\n try { onSettled?.(result); } catch (error) {\n console.warn('[x402] settled, but the payment response headers could not be attached:', error);\n }\n return result;\n });\n }\n return settlePromise;\n },\n };\n}\n\n/**\n * The result as propagated to the buyer in `PAYMENT-RESPONSE`: everything but\n * the merchant's `Idempotency-Key`, which is a binding and stays server-side.\n */\nfunction propagatedResult(result: VerifyResponse | SettleResponse): Record<string, unknown> {\n const { idempotencyKey: _key, ...propagated } = result;\n return propagated;\n}\n\n/** The answer to an authorization the facilitator admitted for another request. */\nexport interface PaymentConflictResponse {\n /** `409` when the payment was used; `503` + `Retry-After` while it is in flight. */\n status: 409 | 503;\n headers: Record<string, string>;\n body: {\n error: string;\n /** The facilitator's code, e.g. `authorization_already_settled`. */\n reason?: string;\n retryable: boolean;\n retryAfterSeconds?: number;\n safeToReplay: boolean;\n };\n}\n\n/**\n * Build the answer to a verify or settle that names an admitted authorization,\n * or `null` when the result is something else.\n *\n * - {@link AUTHORIZATION_IN_FLIGHT} -> `503` + `Retry-After`: resend the SAME\n * request (with its `X-UVD-Purchase`, if it had one) to learn the verdict;\n * never sign a new authorization while this one may still settle.\n * - {@link AUTHORIZATION_ALREADY_SETTLED}, {@link RECEIPT_REQUEST_CONFLICT} and\n * any other `409` from the facilitator -> `409`, not retryable: this X-PAYMENT\n * was already used and the purchase is not served again.\n *\n * Never `402` -- the payment was not refused, and a new signature would pay a\n * second time -- and never `500`.\n */\nexport function buildPaymentConflictResponse(\n failure: FacilitatorFailureFields & { error?: string; invalidReason?: string },\n): PaymentConflictResponse | null {\n if (isAuthorizationInFlight(failure)) {\n const { headers, body } = buildUnavailableResponse('Payment authorization in flight', failure);\n return { status: 503, headers, body: { ...body, reason: AUTHORIZATION_IN_FLIGHT } };\n }\n const used = isAuthorizationAlreadyUsed(failure);\n if (!used && failure.status !== 409) return null;\n return {\n status: 409,\n headers: {},\n body: {\n error: used ? 'Payment authorization already used' : 'Payment request conflict',\n reason: failure.errorCode ?? failure.invalidReason ?? failure.error,\n retryable: false,\n safeToReplay: false,\n },\n };\n}\n\n/** The body of a no-verdict refusal. See {@link buildUnavailableResponse}. */\nexport interface UnavailableBody {\n /** Human-readable summary. Never says the payment was rejected. */\n error: string;\n /** The facilitator's own reason, under whichever field it populated. */\n reason?: string;\n /** Always `true` — this response exists to say \"no verdict\", not \"refused\". */\n retryable: true;\n /** Whole seconds to wait, mirroring the `Retry-After` header. */\n retryAfterSeconds: number;\n /**\n * `false` for `forward_failed` and for a bare timeout: the write may already\n * have landed, so the caller must reconcile before resending.\n */\n safeToReplay: boolean;\n}\n\n/** A framework-agnostic HTTP response. See {@link buildUnavailableResponse}. */\nexport interface UnavailableResponse {\n /** Always 503. */\n status: 503;\n /** `Retry-After`, ready to spread onto any framework's header setter. */\n headers: Record<string, string>;\n body: UnavailableBody;\n /** Same value as the header, already clamped to a whole second >= 1. */\n retryAfterSeconds: number;\n}\n\n/**\n * Build the answer to a facilitator refusal that reached NO VERDICT.\n *\n * `verify` returns invalid for two different things: a payment that was\n * REJECTED, and a facilitator that never reached a verdict (`retryable`).\n * Answering `402` in the second case tells the buyer to sign a NEW\n * authorization while the first one is still live and still spendable by the\n * facilitator — so the buyer pays twice. The correct answer is `503` plus\n * `Retry-After`, which asks for the SAME credential again.\n *\n * This returns plain data — status, headers, body — so a handler written\n * without Express (Lambda, Hono, a Next route, Fastify, a bare `Response`) can\n * answer correctly without re-deriving the rule. The Express and Hono\n * middlewares in this SDK both build their reply from it.\n *\n * @param message - Summary for the `error` field, e.g. `'Payment verification unavailable'`\n * @param failure - The facilitator result. Only its failure fields are read.\n *\n * @example Lambda / any framework\n * ```ts\n * const verifyResult = await client.verify(payment, requirements);\n * if (!verifyResult.isValid && verifyResult.retryable) {\n * const r = buildUnavailableResponse('Payment verification unavailable', verifyResult);\n * return { statusCode: r.status, headers: r.headers, body: JSON.stringify(r.body) };\n * }\n * ```\n *\n * @example Web `Response`\n * ```ts\n * const r = buildUnavailableResponse('Payment settlement unavailable', settleResult);\n * return Response.json(r.body, { status: r.status, headers: r.headers });\n * ```\n */\nexport function buildUnavailableResponse(\n message: string,\n failure: FacilitatorFailureFields & { error?: string; invalidReason?: string },\n): UnavailableResponse {\n const seconds = Math.max(1, Math.ceil(failure.retryAfterSeconds ?? DEFAULT_RETRY_AFTER_SECONDS));\n return {\n status: 503,\n headers: { 'Retry-After': String(seconds) },\n body: {\n error: message,\n reason: failure.reason ?? failure.invalidReason ?? failure.error,\n retryable: true,\n retryAfterSeconds: seconds,\n safeToReplay: failure.safeToReplay === true,\n },\n retryAfterSeconds: seconds,\n };\n}\n\n/**\n * Answer a no-verdict facilitator refusal as 503 + `Retry-After`.\n *\n * The body repeats the facilitator's own `reason` and a `retryable` flag so a\n * client that only reads JSON still learns the payment was not rejected. The\n * header is a whole-second integer, as RFC 9110 requires.\n *\n * Express-shaped wrapper over {@link buildUnavailableResponse}, which is the\n * public, framework-agnostic form of the same decision.\n */\nfunction respondUnavailable(\n res: ExpressLikeResponse,\n message: string,\n failure: FacilitatorFailureFields & { error?: string; invalidReason?: string },\n): void {\n respondExpress(res, buildUnavailableResponse(message, failure));\n}\n\n/** Send a framework-agnostic `{ status, headers, body }` through Express. */\nfunction respondExpress(\n res: ExpressLikeResponse,\n { status, headers, body }: { status: number; headers: Record<string, string>; body: unknown },\n): void {\n const staged = res.status(status);\n if (Object.keys(headers).length > 0 && typeof staged.set === 'function') {\n staged.set(headers).json(body);\n return;\n }\n staged.json(body);\n}\n\n/** The slice of an Express `res` the middleware uses. Readers are optional for doubles. */\ntype ExpressLikeResponse = {\n set?: (headers: Record<string, string>) => unknown;\n /** Node's reader of a header already set, e.g. by a CORS middleware. */\n getHeader?: (name: string) => unknown;\n /** Express's alias of `getHeader`. */\n get?: (name: string) => unknown;\n /** True once the response went out; headers can no longer be added. */\n headersSent?: boolean;\n status: (code: number) => {\n json: (body: unknown) => void;\n set: (headers: Record<string, string>) => { json: (body: unknown) => void };\n };\n};\n\n/**\n * Add the payment result headers to an Express response, merging the CORS\n * expose list and the cache directives the application already set.\n *\n * Skipped once the response was sent: in `'manual'` mode a handler may answer\n * first and settle afterwards, and `res.set` then throws ERR_HTTP_HEADERS_SENT.\n */\nfunction setExpressPaymentHeaders(res: ExpressLikeResponse, result: VerifyResponse | SettleResponse): void {\n if (!result.receipt || !res.set || res.headersSent) return;\n const current = (name: string): string | undefined => {\n const value = res.getHeader ? res.getHeader(name) : res.get?.(name);\n if (value === undefined || value === null) return undefined;\n return Array.isArray(value) ? value.join(', ') : String(value);\n };\n res.set(mergePaymentResponseHeaders(propagatedResult(result), current));\n}\n\n/**\n * Create an Express-compatible middleware for x402 payments\n *\n * @param getRequirements - Function to get payment requirements for a request\n * @param options - Middleware options\n * @returns Express middleware function\n *\n * @example\n * ```ts\n * const paymentMiddleware = createPaymentMiddleware(\n * (req) => ({\n * amount: '1.00',\n * recipient: process.env.PAYMENT_RECIPIENT,\n * resource: `${req.protocol}://${req.get('host')}${req.originalUrl}`,\n * }),\n * { facilitatorUrl: 'https://facilitator.uvd.xyz' }\n * );\n *\n * app.get('/premium/*', paymentMiddleware, async (req, res) => {\n * const settleResult = await req.x402?.settle();\n * if (!settleResult?.success) {\n * return res.status(500).json({ error: settleResult?.error });\n * }\n *\n * res.json({ premium: 'data' });\n * });\n * ```\n */\nexport function createPaymentMiddleware(\n getRequirements: (req: { headers: Record<string, string | string[] | undefined> }) => PaymentRequirementsOptions,\n options: PaymentMiddlewareOptions = {}\n): (\n req: { headers: Record<string, string | string[] | undefined>; x402?: VerifiedPaymentState; method?: string; url?: string; originalUrl?: string; rawBody?: Uint8Array },\n res: ExpressLikeResponse,\n next: () => void\n) => Promise<void> {\n const client = new FacilitatorClient({\n baseUrl: options.facilitatorUrl || options.baseUrl,\n timeout: options.timeout,\n retries: options.retries,\n });\n const settlementStrategy = options.settlementStrategy || 'before-handler';\n\n return async (req, res, next) => {\n // Extract payment header\n const payment = extractPaymentFromHeaders(req.headers);\n\n // If no payment, return 402\n if (!payment) {\n const reqOptions = getRequirements(req);\n const { status, headers, body } = create402Response(reqOptions);\n res.status(status).set(headers).json(body);\n return;\n }\n\n // Build requirements and verify\n const reqOptions = getRequirements(req);\n const requirements = buildPaymentRequirements(reqOptions);\n let receiptContext: string | undefined;\n try {\n const entry = Object.entries(req.headers).find(([name]) => name.toLowerCase() === 'x-uvd-purchase')?.[1];\n if (entry !== undefined) {\n if (typeof entry !== 'string' || !req.method || (!['GET', 'HEAD'].includes(req.method.toUpperCase()) && !req.rawBody)) throw new Error('receipt context requires method and exact raw body');\n const actualUrl = new URL(req.originalUrl || req.url || reqOptions.resource, reqOptions.resource).toString();\n receiptContext = validatePurchaseContext(entry, req.method, actualUrl, req.rawBody || new Uint8Array());\n requirements.resource = actualUrl;\n }\n } catch { res.status(400).json({ error: 'receipt_context_mismatch' }); return; }\n // One key for this payment's verify, settle and their retries.\n const binding = { idempotencyKey: createIdempotencyKey(), receiptContext };\n const verifyResult = await client.verify(payment, requirements, binding);\n setExpressPaymentHeaders(res, verifyResult);\n\n if (!verifyResult.isValid) {\n // An authorization already admitted for another request: 409 when it was\n // used, 503 while it settles. Serving it would deliver the purchase twice.\n const conflict = buildPaymentConflictResponse(verifyResult);\n if (conflict) {\n respondExpress(res, conflict);\n return;\n }\n // 402 says \"your payment was REJECTED, sign a new authorization\". Sending\n // it for a facilitator that never reached a verdict is what makes the\n // buyer pay twice: their first authorization was never refused and is\n // still perfectly good. A no-verdict answer must keep the credential\n // alive, so it goes out as 503 + Retry-After instead.\n if (verifyResult.retryable) {\n respondUnavailable(res, 'Payment verification unavailable', verifyResult);\n return;\n }\n res.status(402).json({\n error: 'Payment verification failed',\n reason: verifyResult.invalidReason,\n });\n return;\n }\n\n req.x402 = createVerifiedPaymentState(client, payment, requirements, verifyResult, binding,\n result => setExpressPaymentHeaders(res, result));\n\n if (settlementStrategy === 'before-handler') {\n const settleResult = await req.x402.settle();\n if (!settleResult.success) {\n // A replayed or conflicting authorization is not a server fault: 409,\n // or 503 while in flight -- and the handler never runs.\n const conflict = buildPaymentConflictResponse(settleResult);\n if (conflict) {\n respondExpress(res, conflict);\n return;\n }\n // Same distinction on the settle side. A 500 tells a client its request\n // is broken and to stop; a settle that reached no verdict is the one\n // case where retrying the identical request is correct.\n //\n // `settlement_unconfirmed` deliberately lands in the 500 branch: its\n // transaction is already broadcast, so \"stop\" is the right instruction\n // and 503 + Retry-After would be an instruction to pay twice.\n if (settleResult.retryable) {\n respondUnavailable(res, 'Payment settlement unavailable', settleResult);\n return;\n }\n res.status(500).json(settlementFailureBody(settleResult, 'Unknown settlement error'));\n return;\n }\n }\n\n next();\n };\n}\n\n// ============================================================================\n// HONO MIDDLEWARE\n// ============================================================================\n\n/**\n * Options for creating a Hono x402 payment middleware\n */\nexport interface HonoMiddlewareOptions extends PaymentMiddlewareOptions {\n /** Payment requirements to advertise */\n accepts: PaymentAcceptance[];\n /** Response version to advertise (defaults to auto) */\n x402Version?: X402Version | 'auto';\n /** Custom requirement resolver for ambiguous multi-accept flows */\n resolveRequirement?: PaymentRequirementResolver;\n}\n\n/**\n * Create a Hono-compatible middleware for x402 payments.\n *\n * Handles the x402 payment flow:\n * 1. Returns 402 with payment requirements if no X-PAYMENT header\n * 2. Verifies the payment with the facilitator\n * 3. Optionally settles before the handler when settlementStrategy is set\n * 4. Passes control to the next handler on success\n *\n * @param options - Middleware options with facilitator URL and payment accepts\n * @returns Hono middleware function\n *\n * @example\n * ```ts\n * import { createHonoMiddleware } from 'uvd-x402-sdk';\n *\n * const paywall = createHonoMiddleware({\n * accepts: [{\n * network: 'skale-base',\n * asset: '0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20',\n * amount: '1000000',\n * payTo: '0xYourWallet',\n * extra: { name: 'Bridged USDC (SKALE Bridge)', version: '2' },\n * }],\n * });\n *\n * app.get('/api/premium', paywall, (c) => {\n * return c.json({ message: 'Premium content!' });\n * });\n * ```\n */\n/**\n * The body for a settle failure the caller must NOT retry.\n *\n * When the facilitator answered `settlement_unconfirmed` the transaction was\n * broadcast and may be mined, and the hash plus `paymentId` are the only way\n * anyone downstream can find out which. Dropping them at this hop rebuilds, one\n * layer up, exactly the dead end the facilitator change removed: \"something\n * went wrong, and here is nothing you can look up\".\n *\n * `retryable: false` is stated rather than implied — the buyer's client reads\n * JSON, and a bare `500` is only a convention.\n */\nfunction settlementFailureBody(\n failure: FacilitatorFailureFields & { error?: string },\n fallbackReason: string,\n): Record<string, unknown> {\n return {\n error: 'Payment settlement failed',\n reason: failure.error || fallbackReason,\n retryable: false,\n ...(failure.errorCode !== undefined ? { errorCode: failure.errorCode } : {}),\n ...(failure.transaction !== undefined ? { transaction: failure.transaction } : {}),\n ...(failure.paymentId !== undefined ? { paymentId: failure.paymentId } : {}),\n };\n}\n\n/** {@link respondUnavailable} for a Hono context. */\nfunction honoUnavailable(\n c: HonoLikeContext,\n message: string,\n failure: FacilitatorFailureFields & { error?: string; invalidReason?: string },\n): unknown {\n return respondHono(c, buildUnavailableResponse(message, failure));\n}\n\n/** Send a framework-agnostic `{ status, headers, body }` through Hono. */\nfunction respondHono(\n c: HonoLikeContext,\n { status, headers, body }: { status: number; headers: Record<string, string>; body: unknown },\n): unknown {\n for (const [name, value] of Object.entries(headers)) {\n c.header?.(name, value);\n }\n return c.json(body, status);\n}\n\n/** The slice of a Hono `Context` the middleware uses. Optional parts fit older doubles. */\ntype HonoLikeContext = {\n req: { header: (name: string) => string | undefined; url: string; method?: string; raw?: Request };\n json: (body: unknown, status?: number) => unknown;\n set?: (key: string, value: unknown) => void;\n /** Hono's response-header setter. Optional so older context doubles still fit. */\n header?: (name: string, value: string) => void;\n /** Hono's response so far, read to merge with headers a CORS middleware set. */\n res?: { headers: { get: (name: string) => string | null } };\n /** True once a handler's response was committed to the context. */\n finalized?: boolean;\n};\n\n/**\n * Add the payment result headers through Hono, merging the CORS expose list\n * and the cache directives already on the response instead of replacing them.\n *\n * Skipped once the response was committed, as in Express: a `'manual'` settle\n * after the handler returned must not rebuild a response already handed back.\n */\nfunction setHonoPaymentHeaders(c: HonoLikeContext, result: VerifyResponse | SettleResponse): void {\n if (!result.receipt || !c.header || c.finalized) return;\n const current = (name: string) => c.res?.headers.get(name) ?? undefined;\n for (const [name, value] of Object.entries(mergePaymentResponseHeaders(propagatedResult(result), current))) {\n c.header(name, value);\n }\n}\n\nexport function createHonoMiddleware(options: HonoMiddlewareOptions) {\n const client = new FacilitatorClient({\n baseUrl: options.facilitatorUrl || options.baseUrl,\n timeout: options.timeout,\n retries: options.retries,\n });\n const settlementStrategy = options.settlementStrategy || 'before-handler';\n\n if (!options.accepts[0]) {\n throw new Error('At least one accept entry is required');\n }\n\n return async (\n c: HonoLikeContext,\n next: () => Promise<void>\n ) => {\n const paymentHeader = c.req.header('PAYMENT-SIGNATURE') || c.req.header('X-PAYMENT') || c.req.header('x-payment');\n const advertisedVersion = resolveAdvertisedVersion(options.accepts, options.x402Version);\n const advertisedRequirements = options.accepts.map((accept) =>\n buildRequirementFromAcceptance(accept, c.req.url, advertisedVersion)\n );\n\n if (!paymentHeader) {\n return c.json(\n create402ResponseBody(\n advertisedRequirements[0],\n advertisedRequirements,\n advertisedVersion,\n options.facilitatorUrl\n ),\n 402\n );\n }\n\n const parsed = parsePaymentHeader(paymentHeader);\n if (!parsed) {\n return c.json({ error: 'Invalid X-PAYMENT header' }, 400);\n }\n\n const { requirement, reason } = await resolvePaymentRequirement(\n parsed,\n advertisedRequirements,\n options.resolveRequirement\n );\n\n if (!requirement) {\n return c.json({\n error: 'Payment verification failed',\n reason,\n }, 402);\n }\n\n let receiptContext: string | undefined;\n try {\n const header = c.req.header('X-UVD-Purchase');\n if (header) {\n const method = c.req.method || c.req.raw?.method;\n if (!method || (!['GET', 'HEAD'].includes(method) && !c.req.raw)) throw new Error('raw request required');\n const bytes = c.req.raw ? new Uint8Array(await c.req.raw.clone().arrayBuffer()) : new Uint8Array();\n receiptContext = validatePurchaseContext(header, method, c.req.url, bytes);\n }\n } catch { return c.json({ error: 'receipt_context_mismatch' }, 400); }\n // One key for this payment's verify, settle and their retries.\n const binding = { idempotencyKey: createIdempotencyKey(), receiptContext };\n const verifyResult = await client.verify(parsed, requirement, binding);\n setHonoPaymentHeaders(c, verifyResult);\n if (!verifyResult.isValid) {\n // See the Express branch: an admitted authorization is 409 or 503.\n const conflict = buildPaymentConflictResponse(verifyResult);\n if (conflict) return respondHono(c, conflict);\n // See respondUnavailable: 402 here would tell the buyer to sign again for\n // an authorization the facilitator never rejected.\n if (verifyResult.retryable) {\n return honoUnavailable(c, 'Payment verification unavailable', verifyResult);\n }\n return c.json({\n error: 'Payment verification failed',\n reason: verifyResult.invalidReason,\n }, 402);\n }\n\n const verifiedPayment = createVerifiedPaymentState(client, parsed, requirement, verifyResult, binding,\n result => setHonoPaymentHeaders(c, result));\n c.set?.('x402', verifiedPayment);\n\n if (settlementStrategy === 'before-handler') {\n const settleResult = await verifiedPayment.settle();\n if (!settleResult.success) {\n const conflict = buildPaymentConflictResponse(settleResult);\n if (conflict) return respondHono(c, conflict);\n if (settleResult.retryable) {\n return honoUnavailable(c, 'Payment settlement unavailable', settleResult);\n }\n // See the Express branch: `settlement_unconfirmed` belongs here, with\n // its hash, and not behind a Retry-After.\n return c.json(settlementFailureBody(settleResult, 'Unknown error'), 500);\n }\n }\n\n await next();\n };\n}\n\n// ============================================================================\n// BAZAAR DISCOVERY API\n// ============================================================================\n//\n// The Bazaar is the discovery registry served by the facilitator itself, under\n// `/discovery/*`. There is no separate Bazaar host.\n\n/**\n * Maximum length of the free-text `q` filter.\n *\n * Mirrors the facilitator's `MAX_SEARCH_LEN`; a longer needle is rejected\n * server-side with a 400.\n */\nexport const MAX_SEARCH_LEN = 128;\n\n/**\n * Liveness of a registered resource, as measured by the facilitator's prober.\n *\n * Resources that stop answering are quarantined rather than deleted, so filter\n * on this before paying anyone.\n */\nexport type DiscoveryHealthStatus =\n | 'alive'\n | 'degraded'\n | 'auth_gated'\n | 'quarantined'\n | 'unknown'\n | 'unprobeable';\n\n/** Values accepted by the `health` filter, including the `any` escape hatch. */\nexport const HEALTH_FILTERS = [\n 'alive',\n 'degraded',\n 'auth_gated',\n 'quarantined',\n 'unknown',\n 'unprobeable',\n 'any',\n] as const;\n\n/** Curated tier, in descending order of trust. */\nexport type DiscoveryTier = 'first_party' | 'vip' | 'verified' | 'listed';\n\n/** Values accepted by the `tier` filter. */\nexport const TIER_FILTERS = [\n 'first_party',\n 'vip',\n 'verified',\n 'listed',\n] as const;\n\n/** How a resource got into the registry. */\nexport type DiscoverySource =\n | 'self_registered'\n | 'settlement'\n | 'crawled'\n | 'aggregated';\n\n/** Health of a single resource, as reported by the registry's prober. */\nexport interface DiscoveryHealth {\n /** Last observed liveness */\n status?: DiscoveryHealthStatus;\n /** Unix epoch seconds of the last probe */\n lastChecked?: number;\n /** HTTP status the probe got back (402 is the healthy answer for x402) */\n httpStatus?: number;\n /** Round-trip time of the last probe, in milliseconds */\n latencyMs?: number;\n}\n\n/** Curation metadata attached to a resource. */\nexport interface DiscoveryCuration {\n /** Curated tier */\n tier?: DiscoveryTier;\n /** Human-readable name of the curated set */\n label?: string;\n}\n\n/** One payment method a resource declares. */\nexport interface DiscoveryAccepts {\n /** Payment scheme (\"exact\", \"escrow\", \"commerce\") */\n scheme: string;\n /** CAIP-2 network id, e.g. \"eip155:8453\" */\n network: string;\n /** Token contract address */\n asset?: string;\n /** Price in atomic units of `asset` */\n amount?: string;\n /** Recipient address */\n payTo?: string;\n /** Settlement deadline in seconds */\n maxTimeoutSeconds?: number;\n /** Scheme-specific extras (EIP-712 domain, etc.) */\n extra?: Record<string, unknown>;\n /** Anything the registry adds later */\n [key: string]: unknown;\n}\n\n/**\n * A discoverable paid resource, exactly as `GET /discovery/resources` serves it.\n *\n * Timestamps are Unix epoch **seconds**, not ISO strings and not milliseconds.\n */\nexport interface DiscoveryResource {\n /** Resource URL. This is the registry's primary key -- there is no `id` */\n url: string;\n /** Resource type (\"http\", \"mcp\", \"a2a\") */\n type: string;\n /** x402 protocol version the resource speaks */\n x402Version: number;\n /** Human-readable description */\n description?: string;\n /** Payment methods the resource accepts */\n accepts: DiscoveryAccepts[];\n /** Free-form metadata (category, provider, tags) */\n metadata?: Record<string, unknown>;\n /** How this resource entered the registry */\n source?: DiscoverySource;\n /** Facilitator this resource was aggregated from */\n sourceFacilitator?: string;\n /** Unix epoch seconds when the registry first saw this resource */\n firstSeen?: number;\n /** Unix epoch seconds when the registry last saw this resource */\n lastSeen?: number;\n /** Unix epoch seconds of the last change to this record */\n lastUpdated?: number;\n /** Liveness, when the resource has been probed */\n health?: DiscoveryHealth;\n /** Curation tier, when the resource has been curated */\n curation?: DiscoveryCuration;\n /** Anything the registry adds later */\n [key: string]: unknown;\n}\n\n/** Pagination envelope of `GET /discovery/resources`. */\nexport interface DiscoveryPagination {\n /** Page size that was applied */\n limit: number;\n /** Offset that was applied */\n offset: number;\n /** Total number of resources matching the filters, across all pages */\n total: number;\n}\n\n/** Paginated response from `GET /discovery/resources`. */\nexport interface DiscoveryResponse {\n /** x402 protocol version of the response envelope */\n x402Version: number;\n /** Resources on this page */\n items: DiscoveryResource[];\n /** Pagination state */\n pagination: DiscoveryPagination;\n}\n\n/**\n * Filters for `listResources()`.\n *\n * Every one of these is applied server-side over the whole catalog, so\n * `pagination.total` reflects the filtered set. Filtering a page after the\n * fact is not the same thing and will under-report.\n */\nexport interface DiscoveryListOptions {\n /** Page size (default: 10, max: 100) */\n limit?: number;\n /** Number of resources to skip */\n offset?: number;\n /** Filter by category */\n category?: string;\n /** Filter by network, CAIP-2 or v1 name */\n network?: string;\n /** Filter by provider name */\n provider?: string;\n /** Filter by tag */\n tag?: string;\n /** Filter by how the resource was discovered */\n source?: DiscoverySource;\n /** Filter by originating facilitator */\n sourceFacilitator?: string;\n /** Filter by liveness, or 'any' to opt out of the default visibility rules */\n health?: DiscoveryHealthStatus | 'any';\n /** Filter by curated tier */\n tier?: DiscoveryTier;\n /** Free-text search over url / description / provider / category / tags */\n q?: string;\n}\n\n/** Options for `registerResource()`. */\nexport interface DiscoveryRegisterOptions {\n /** URL of the paid resource. Doubles as its identity in the registry */\n url: string;\n /** Resource type (default: \"http\") */\n type?: string;\n /** Human-readable description */\n description?: string;\n /** Payment methods the resource accepts */\n accepts?: DiscoveryAccepts[];\n /** Free-form metadata (category, provider, tags) */\n metadata?: Record<string, unknown>;\n}\n\n/** Aggregate catalog metrics from `GET /discovery/stats`. */\nexport interface DiscoveryStats {\n /** Every record the registry holds, including quarantined ones */\n total: number;\n /** Records served by default listings */\n visible: number;\n /** Counts by discovery source */\n bySource: Record<string, number>;\n /** Counts by originating facilitator */\n bySourceFacilitator: Record<string, number>;\n /** Counts by CAIP-2 network */\n byNetwork: Record<string, number>;\n /** Counts by curated tier */\n byTier: Record<string, number>;\n /** Counts by liveness */\n byHealth: Record<string, number>;\n /** Unix epoch seconds this snapshot was computed (60s cache) */\n generatedAt?: number;\n}\n\n/** Options for the {@link BazaarClient}. */\nexport interface BazaarClientOptions {\n /** Facilitator base URL (default: https://facilitator.ultravioletadao.xyz) */\n baseUrl?: string;\n /** Request timeout in milliseconds (default: 30000) */\n timeout?: number;\n}\n\n/** Render an epoch-seconds field as a `Date`. */\nexport function epochToDate(seconds?: number): Date | undefined {\n return seconds === undefined ? undefined : new Date(seconds * 1000);\n}\n\n/** True when the last probe reached this resource. */\nexport function isAlive(resource: DiscoveryResource): boolean {\n return resource.health?.status === 'alive';\n}\n\n/**\n * Client for the x402 Bazaar Discovery API.\n *\n * The Bazaar is the facilitator's own registry of x402-enabled resources.\n * Providers register their endpoints and consumers discover them, with a\n * liveness probe and a curation tier attached to every record.\n *\n * @example\n * ```ts\n * const bazaar = new BazaarClient();\n *\n * // Only endpoints a probe actually reached, best-curated first\n * const page = await bazaar.listResources({ limit: 20, health: 'alive', tier: 'vip' });\n * for (const r of page.items) {\n * console.log(r.url, r.health?.status, r.health?.latencyMs, r.curation?.label);\n * }\n *\n * // Free-text search runs server-side over the whole catalog\n * const hits = await bazaar.listResources({ q: 'logs' });\n * console.log(hits.pagination.total);\n *\n * // Register your own\n * await bazaar.registerResource({\n * url: 'https://api.example.com/v1/generate',\n * description: 'Generate images with AI',\n * accepts: [{\n * scheme: 'exact',\n * network: 'eip155:8453',\n * asset: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\n * amount: '10000',\n * payTo: '0xYourWallet...',\n * maxTimeoutSeconds: 60,\n * }],\n * metadata: { category: 'ai', tags: ['image'] },\n * });\n * ```\n */\nexport class BazaarClient {\n private readonly baseUrl: string;\n private readonly timeout: number;\n\n constructor(options: BazaarClientOptions = {}) {\n this.baseUrl = (\n options.baseUrl || 'https://facilitator.ultravioletadao.xyz'\n ).replace(/\\/+$/, '');\n this.timeout = options.timeout || 30000;\n }\n\n /**\n * Issue a request against the facilitator with the configured timeout.\n */\n private async request<T>(path: string, init?: RequestInit): Promise<T> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(`${this.baseUrl}${path}`, {\n ...init,\n headers: { Accept: 'application/json', ...(init?.headers || {}) },\n signal: controller.signal,\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(\n `Bazaar API error: ${response.status} - ${errorText}`\n );\n }\n\n return (await response.json()) as T;\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n /**\n * List resources from the discovery registry.\n *\n * @param options - Server-side filters and pagination\n * @returns One page of resources plus the total across all pages\n *\n * @example\n * ```ts\n * const page = await bazaar.listResources({ network: 'eip155:8453', health: 'alive' });\n * ```\n */\n async listResources(\n options: DiscoveryListOptions = {}\n ): Promise<DiscoveryResponse> {\n if (options.q !== undefined && options.q.length > MAX_SEARCH_LEN) {\n throw new Error(`q must be at most ${MAX_SEARCH_LEN} characters`);\n }\n\n const params = new URLSearchParams();\n params.set('limit', String(options.limit ?? 10));\n params.set('offset', String(options.offset ?? 0));\n if (options.category) params.set('category', options.category);\n if (options.network) params.set('network', options.network);\n if (options.provider) params.set('provider', options.provider);\n if (options.tag) params.set('tag', options.tag);\n if (options.source) params.set('source', options.source);\n if (options.sourceFacilitator)\n params.set('sourceFacilitator', options.sourceFacilitator);\n if (options.health) params.set('health', options.health);\n if (options.tier) params.set('tier', options.tier);\n if (options.q) params.set('q', options.q);\n\n return this.request<DiscoveryResponse>(\n `/discovery/resources?${params.toString()}`\n );\n }\n\n /**\n * Walk the whole filtered catalog, one page at a time.\n *\n * Pages are fetched in sequence rather than in parallel: the read routes are\n * rate limited, and a burst of parallel pages is how a legitimate catalog\n * walk turns into a wall of 429s.\n *\n * @param options - Same filters as {@link listResources}; `limit` is the page size\n *\n * @example\n * ```ts\n * for await (const r of bazaar.iterateResources({ health: 'alive' })) {\n * console.log(r.url);\n * }\n * ```\n */\n async *iterateResources(\n options: DiscoveryListOptions = {}\n ): AsyncGenerator<DiscoveryResource, void, undefined> {\n const pageSize = options.limit ?? 100;\n let offset = options.offset ?? 0;\n\n for (;;) {\n const page = await this.listResources({\n ...options,\n limit: pageSize,\n offset,\n });\n if (page.items.length === 0) return;\n\n for (const item of page.items) yield item;\n\n offset += page.items.length;\n if (offset >= page.pagination.total) return;\n }\n }\n\n /**\n * Look up a single resource by its URL.\n *\n * The registry keys on URL and has no by-id lookup, so this searches and\n * then matches exactly.\n *\n * @param resourceUrl - Exact URL of the resource\n * @returns The resource, or null when it is not registered\n */\n async getResourceByUrl(\n resourceUrl: string\n ): Promise<DiscoveryResource | null> {\n const page = await this.listResources({\n q: resourceUrl.slice(0, MAX_SEARCH_LEN),\n limit: 100,\n health: 'any',\n });\n return page.items.find((item) => item.url === resourceUrl) ?? null;\n }\n\n /**\n * Register a paid resource in the discovery registry.\n *\n * Registration is open and rate limited; re-registering a known URL updates\n * the existing record rather than creating a duplicate.\n *\n * @param options - Resource details\n * @returns The registry's acknowledgement\n */\n async registerResource(\n options: DiscoveryRegisterOptions\n ): Promise<Record<string, unknown>> {\n const payload: Record<string, unknown> = {\n url: options.url,\n type: options.type || 'http',\n description: options.description || '',\n };\n if (options.accepts) payload.accepts = options.accepts;\n if (options.metadata) payload.metadata = options.metadata;\n\n return this.request<Record<string, unknown>>('/discovery/register', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(payload),\n });\n }\n\n /**\n * Aggregate catalog metrics (60s cached server-side).\n *\n * @returns Counts by source, facilitator, network, tier and liveness\n */\n async getStats(): Promise<DiscoveryStats> {\n return this.request<DiscoveryStats>('/discovery/stats');\n }\n\n /**\n * Check that the facilitator serving the registry is up.\n *\n * @returns True when the facilitator answers its health check\n */\n async healthCheck(): Promise<boolean> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n try {\n const response = await fetch(`${this.baseUrl}/health`, {\n method: 'GET',\n signal: controller.signal,\n });\n return response.ok;\n } catch {\n return false;\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n /**\n * @deprecated Renamed to {@link listResources}, which returns the registry's\n * real `{ items, pagination }` envelope. The old `discover()` returned a\n * `{ resources, page, totalPages }` shape that no endpoint ever served.\n */\n async discover(options: DiscoveryListOptions = {}): Promise<DiscoveryResponse> {\n return this.listResources(options);\n }\n}\n\n/**\n * @deprecated Use {@link DiscoveryResource}. The old shape (`id`, `name`,\n * `pricePerRequest`, `isActive`, ISO `createdAt`) described an API that was\n * never deployed.\n */\nexport type BazaarResource = DiscoveryResource;\n\n/** @deprecated Use {@link DiscoveryResponse}. */\nexport type BazaarDiscoverResponse = DiscoveryResponse;\n\n/** @deprecated Use {@link DiscoveryListOptions}. */\nexport type BazaarDiscoverOptions = DiscoveryListOptions;\n\n/** @deprecated Use {@link DiscoveryRegisterOptions}. */\nexport type BazaarRegisterOptions = DiscoveryRegisterOptions;\n\n// ============================================================================\n// ESCROW & REFUND EXTENSION\n// ============================================================================\n\n/**\n * Escrow payment status\n */\nexport type EscrowStatus =\n | 'pending' // Payment initiated, awaiting confirmation\n | 'held' // Funds held in escrow\n | 'released' // Funds released to recipient\n | 'refunded' // Funds returned to payer\n | 'disputed' // Dispute in progress\n | 'expired'; // Escrow expired without resolution\n\n/**\n * Refund request status\n */\nexport type RefundStatus =\n | 'pending' // Refund requested, awaiting processing\n | 'approved' // Refund approved\n | 'rejected' // Refund rejected\n | 'processed' // Refund completed on-chain\n | 'disputed'; // Under dispute review\n\n/**\n * Dispute resolution outcome\n */\nexport type DisputeOutcome =\n | 'pending' // Dispute under review\n | 'payer_wins' // Payer gets refund\n | 'recipient_wins' // Recipient keeps funds\n | 'split'; // Funds split between parties\n\n/**\n * Escrow payment record\n */\nexport interface EscrowPayment {\n /** Unique escrow ID */\n id: string;\n /** Original payment header (base64 encoded) */\n paymentHeader: string;\n /** Current status */\n status: EscrowStatus;\n /** Network where payment was made */\n network: string;\n /** Payer address */\n payer: string;\n /** Recipient address */\n recipient: string;\n /** Amount in atomic units */\n amount: string;\n /** Token/asset contract */\n asset: string;\n /** Resource URL being paid for */\n resource: string;\n /** Escrow expiration timestamp (ISO) */\n expiresAt: string;\n /** Release conditions (optional) */\n releaseConditions?: {\n /** Minimum time before release (seconds) */\n minHoldTime?: number;\n /** Required confirmations */\n confirmations?: number;\n /** Custom condition metadata */\n custom?: unknown;\n };\n /** Transaction hash if released/refunded */\n transactionHash?: string;\n /** Creation timestamp (ISO) */\n createdAt: string;\n /** Last update timestamp (ISO) */\n updatedAt: string;\n}\n\n/**\n * Refund request record\n */\nexport interface RefundRequest {\n /** Unique refund request ID */\n id: string;\n /** Related escrow ID */\n escrowId: string;\n /** Current status */\n status: RefundStatus;\n /** Reason for refund request */\n reason: string;\n /** Additional evidence/details */\n evidence?: string;\n /** Amount requested (may be partial) */\n amountRequested: string;\n /** Amount approved (if any) */\n amountApproved?: string;\n /** Requester (payer) address */\n requester: string;\n /** Transaction hash if processed */\n transactionHash?: string;\n /** Response from recipient/facilitator */\n response?: {\n status: 'approved' | 'rejected';\n reason?: string;\n respondedAt: string;\n };\n /** Creation timestamp (ISO) */\n createdAt: string;\n /** Last update timestamp (ISO) */\n updatedAt: string;\n}\n\n/**\n * Dispute record\n */\nexport interface Dispute {\n /** Unique dispute ID */\n id: string;\n /** Related escrow ID */\n escrowId: string;\n /** Related refund request ID (if any) */\n refundRequestId?: string;\n /** Dispute outcome */\n outcome: DisputeOutcome;\n /** Initiator (payer or recipient) */\n initiator: 'payer' | 'recipient';\n /** Reason for dispute */\n reason: string;\n /** Evidence from payer */\n payerEvidence?: string;\n /** Evidence from recipient */\n recipientEvidence?: string;\n /** Arbitration notes */\n arbitrationNotes?: string;\n /** Amount resolved to payer */\n payerAmount?: string;\n /** Amount resolved to recipient */\n recipientAmount?: string;\n /** Transaction hash(es) for resolution */\n transactionHashes?: string[];\n /** Creation timestamp (ISO) */\n createdAt: string;\n /** Resolution timestamp (ISO) */\n resolvedAt?: string;\n}\n\n/**\n * Options for creating an escrow payment\n */\nexport interface CreateEscrowOptions {\n /** Payment header (from client SDK) */\n paymentHeader: string;\n /** Payment requirements */\n requirements: PaymentRequirements;\n /** Escrow duration in seconds (default: 86400 = 24h) */\n escrowDuration?: number;\n /** Release conditions */\n releaseConditions?: {\n minHoldTime?: number;\n confirmations?: number;\n custom?: unknown;\n };\n}\n\n/**\n * Options for requesting a refund\n */\nexport interface RequestRefundOptions {\n /** Escrow ID to refund */\n escrowId: string;\n /** Reason for refund */\n reason: string;\n /** Amount to refund (full amount if not specified) */\n amount?: string;\n /** Supporting evidence */\n evidence?: string;\n}\n\n/**\n * Options for the EscrowClient\n */\nexport interface EscrowClientOptions {\n /** Base URL of the Escrow API (default: https://escrow.ultravioletadao.xyz) */\n baseUrl?: string;\n /** API key for authenticated operations */\n apiKey?: string;\n /** Request timeout in milliseconds (default: 30000) */\n timeout?: number;\n}\n\n/**\n * Client for x402 Escrow & Refund operations\n *\n * The Escrow system holds payments until service is verified,\n * enabling refunds and dispute resolution.\n *\n * @example\n * ```ts\n * // Create escrow payment (backend)\n * const escrow = new EscrowClient();\n * const escrowPayment = await escrow.createEscrow({\n * paymentHeader: req.headers['x-payment'],\n * requirements: paymentRequirements,\n * escrowDuration: 86400, // 24 hours\n * });\n *\n * // After service is provided, release the escrow\n * await escrow.release(escrowPayment.id);\n *\n * // If service not provided, payer can request refund\n * await escrow.requestRefund({\n * escrowId: escrowPayment.id,\n * reason: 'Service not delivered within expected timeframe',\n * });\n * ```\n */\nexport class EscrowClient {\n private readonly baseUrl: string;\n private readonly apiKey?: string;\n private readonly timeout: number;\n\n constructor(options: EscrowClientOptions = {}) {\n this.baseUrl = options.baseUrl || 'https://escrow.ultravioletadao.xyz';\n this.apiKey = options.apiKey;\n this.timeout = options.timeout || 30000;\n }\n\n private getHeaders(authenticated: boolean = false): Record<string, string> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n };\n if (authenticated && this.apiKey) {\n headers['Authorization'] = `Bearer ${this.apiKey}`;\n }\n return headers;\n }\n\n /**\n * Create an escrow payment\n *\n * Holds the payment in escrow until released or refunded.\n *\n * @param options - Escrow creation options\n * @returns Created escrow payment\n */\n async createEscrow(options: CreateEscrowOptions): Promise<EscrowPayment> {\n const url = `${this.baseUrl}/escrow`;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: this.getHeaders(true),\n body: JSON.stringify({\n paymentHeader: options.paymentHeader,\n paymentRequirements: options.requirements,\n escrowDuration: options.escrowDuration || 86400,\n releaseConditions: options.releaseConditions,\n }),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Escrow API error: ${response.status} - ${errorText}`);\n }\n\n return await response.json();\n } catch (error) {\n clearTimeout(timeoutId);\n throw error;\n }\n }\n\n /**\n * Get escrow payment by ID\n *\n * @param escrowId - Escrow payment ID\n * @returns Escrow payment details\n */\n async getEscrow(escrowId: string): Promise<EscrowPayment> {\n const url = `${this.baseUrl}/escrow/${encodeURIComponent(escrowId)}`;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(url, {\n method: 'GET',\n headers: this.getHeaders(),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Escrow API error: ${response.status} - ${errorText}`);\n }\n\n return await response.json();\n } catch (error) {\n clearTimeout(timeoutId);\n throw error;\n }\n }\n\n /**\n * Release escrow funds to recipient\n *\n * Call this after service has been successfully provided.\n *\n * @param escrowId - Escrow payment ID\n * @returns Updated escrow payment with transaction hash\n */\n async release(escrowId: string): Promise<EscrowPayment> {\n const url = `${this.baseUrl}/escrow/${encodeURIComponent(escrowId)}/release`;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: this.getHeaders(true),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Escrow API error: ${response.status} - ${errorText}`);\n }\n\n return await response.json();\n } catch (error) {\n clearTimeout(timeoutId);\n throw error;\n }\n }\n\n /**\n * Request a refund for an escrow payment\n *\n * Initiates a refund request that must be approved.\n *\n * @param options - Refund request options\n * @returns Created refund request\n */\n async requestRefund(options: RequestRefundOptions): Promise<RefundRequest> {\n const url = `${this.baseUrl}/escrow/${encodeURIComponent(options.escrowId)}/refund`;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: this.getHeaders(true),\n body: JSON.stringify({\n reason: options.reason,\n amount: options.amount,\n evidence: options.evidence,\n }),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Escrow API error: ${response.status} - ${errorText}`);\n }\n\n return await response.json();\n } catch (error) {\n clearTimeout(timeoutId);\n throw error;\n }\n }\n\n /**\n * Approve a refund request (for recipients)\n *\n * @param refundId - Refund request ID\n * @param amount - Amount to approve (may be less than requested)\n * @returns Updated refund request\n */\n async approveRefund(refundId: string, amount?: string): Promise<RefundRequest> {\n const url = `${this.baseUrl}/refund/${encodeURIComponent(refundId)}/approve`;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: this.getHeaders(true),\n body: JSON.stringify({ amount }),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Escrow API error: ${response.status} - ${errorText}`);\n }\n\n return await response.json();\n } catch (error) {\n clearTimeout(timeoutId);\n throw error;\n }\n }\n\n /**\n * Reject a refund request (for recipients)\n *\n * @param refundId - Refund request ID\n * @param reason - Reason for rejection\n * @returns Updated refund request\n */\n async rejectRefund(refundId: string, reason: string): Promise<RefundRequest> {\n const url = `${this.baseUrl}/refund/${encodeURIComponent(refundId)}/reject`;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: this.getHeaders(true),\n body: JSON.stringify({ reason }),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Escrow API error: ${response.status} - ${errorText}`);\n }\n\n return await response.json();\n } catch (error) {\n clearTimeout(timeoutId);\n throw error;\n }\n }\n\n /**\n * Get refund request by ID\n *\n * @param refundId - Refund request ID\n * @returns Refund request details\n */\n async getRefund(refundId: string): Promise<RefundRequest> {\n const url = `${this.baseUrl}/refund/${encodeURIComponent(refundId)}`;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(url, {\n method: 'GET',\n headers: this.getHeaders(),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Escrow API error: ${response.status} - ${errorText}`);\n }\n\n return await response.json();\n } catch (error) {\n clearTimeout(timeoutId);\n throw error;\n }\n }\n\n /**\n * Open a dispute for an escrow payment\n *\n * Initiates arbitration when payer and recipient disagree.\n *\n * @param escrowId - Escrow payment ID\n * @param reason - Reason for dispute\n * @param evidence - Supporting evidence\n * @returns Created dispute\n */\n async openDispute(\n escrowId: string,\n reason: string,\n evidence?: string\n ): Promise<Dispute> {\n const url = `${this.baseUrl}/escrow/${encodeURIComponent(escrowId)}/dispute`;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: this.getHeaders(true),\n body: JSON.stringify({ reason, evidence }),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Escrow API error: ${response.status} - ${errorText}`);\n }\n\n return await response.json();\n } catch (error) {\n clearTimeout(timeoutId);\n throw error;\n }\n }\n\n /**\n * Submit evidence to a dispute\n *\n * @param disputeId - Dispute ID\n * @param evidence - Evidence to submit\n * @returns Updated dispute\n */\n async submitEvidence(disputeId: string, evidence: string): Promise<Dispute> {\n const url = `${this.baseUrl}/dispute/${encodeURIComponent(disputeId)}/evidence`;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: this.getHeaders(true),\n body: JSON.stringify({ evidence }),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Escrow API error: ${response.status} - ${errorText}`);\n }\n\n return await response.json();\n } catch (error) {\n clearTimeout(timeoutId);\n throw error;\n }\n }\n\n /**\n * Get dispute by ID\n *\n * @param disputeId - Dispute ID\n * @returns Dispute details\n */\n async getDispute(disputeId: string): Promise<Dispute> {\n const url = `${this.baseUrl}/dispute/${encodeURIComponent(disputeId)}`;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(url, {\n method: 'GET',\n headers: this.getHeaders(),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Escrow API error: ${response.status} - ${errorText}`);\n }\n\n return await response.json();\n } catch (error) {\n clearTimeout(timeoutId);\n throw error;\n }\n }\n\n /**\n * List escrow payments (with filters)\n *\n * @param options - Filter and pagination options\n * @returns Paginated list of escrow payments\n */\n async listEscrows(options: {\n status?: EscrowStatus;\n payer?: string;\n recipient?: string;\n page?: number;\n limit?: number;\n } = {}): Promise<{\n escrows: EscrowPayment[];\n total: number;\n page: number;\n limit: number;\n hasMore: boolean;\n }> {\n const params = new URLSearchParams();\n if (options.status) params.set('status', options.status);\n if (options.payer) params.set('payer', options.payer);\n if (options.recipient) params.set('recipient', options.recipient);\n if (options.page) params.set('page', options.page.toString());\n if (options.limit) params.set('limit', options.limit.toString());\n\n const url = `${this.baseUrl}/escrow${params.toString() ? `?${params}` : ''}`;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(url, {\n method: 'GET',\n headers: this.getHeaders(true),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Escrow API error: ${response.status} - ${errorText}`);\n }\n\n return await response.json();\n } catch (error) {\n clearTimeout(timeoutId);\n throw error;\n }\n }\n\n /**\n * Query on-chain escrow state from the facilitator\n *\n * Calls POST /escrow/state to read current escrow state without settlement.\n *\n * @param options - Escrow state query parameters\n * @returns On-chain escrow state (status, balance, timestamps)\n *\n * @example\n * ```ts\n * const state = await escrow.getEscrowState({\n * network: 'base-mainnet',\n * payer: '0xPayer...',\n * recipient: '0xRecipient...',\n * nonce: '0x1234...',\n * });\n * console.log(`Status: ${state.status}`);\n * ```\n */\n async getEscrowState(options: {\n network: string;\n payer: string;\n recipient: string;\n nonce: string;\n }): Promise<Record<string, unknown>> {\n const url = `${this.baseUrl}/escrow/state`;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: this.getHeaders(),\n body: JSON.stringify(options),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Escrow API error: ${response.status} - ${errorText}`);\n }\n\n return await response.json();\n } catch (error) {\n clearTimeout(timeoutId);\n throw error;\n }\n }\n\n /**\n * Check Escrow API health\n *\n * @returns True if healthy\n */\n async healthCheck(): Promise<boolean> {\n try {\n const response = await fetch(`${this.baseUrl}/health`, {\n method: 'GET',\n });\n return response.ok;\n } catch {\n return false;\n }\n }\n}\n\n// ============================================================================\n// ESCROW HELPER FUNCTIONS\n// ============================================================================\n\n/**\n * Check if an escrow can be released\n *\n * @param escrow - Escrow payment to check\n * @returns True if the escrow can be released\n */\nexport function canReleaseEscrow(escrow: EscrowPayment): boolean {\n if (escrow.status !== 'held') {\n return false;\n }\n\n // Check expiration\n if (new Date(escrow.expiresAt) < new Date()) {\n return false;\n }\n\n // Check minimum hold time if specified\n if (escrow.releaseConditions?.minHoldTime) {\n const createdAt = new Date(escrow.createdAt);\n const minReleaseTime = new Date(\n createdAt.getTime() + escrow.releaseConditions.minHoldTime * 1000\n );\n if (new Date() < minReleaseTime) {\n return false;\n }\n }\n\n return true;\n}\n\n/**\n * Check if an escrow can be refunded\n *\n * @param escrow - Escrow payment to check\n * @returns True if the escrow can be refunded\n */\nexport function canRefundEscrow(escrow: EscrowPayment): boolean {\n // Can only refund held or pending escrows\n return escrow.status === 'held' || escrow.status === 'pending';\n}\n\n/**\n * Check if an escrow is expired\n *\n * @param escrow - Escrow payment to check\n * @returns True if the escrow is expired\n */\nexport function isEscrowExpired(escrow: EscrowPayment): boolean {\n return new Date(escrow.expiresAt) < new Date();\n}\n\n/**\n * Calculate time remaining until escrow expires\n *\n * @param escrow - Escrow payment to check\n * @returns Milliseconds until expiration (negative if expired)\n */\nexport function escrowTimeRemaining(escrow: EscrowPayment): number {\n return new Date(escrow.expiresAt).getTime() - Date.now();\n}\n\n// ============================================================================\n// ERC-8004 TRUSTLESS AGENTS\n// ============================================================================\n\n/**\n * ERC-8004 extension identifier\n */\nexport const ERC8004_EXTENSION_ID = '8004-reputation';\n\n/**\n * Agent ID type: EVM uses sequential uint256 (number), Solana uses base58 pubkey (string)\n */\nexport type AgentId = number | string;\n\n/**\n * ERC-8004 contract addresses per network\n */\n// Mainnet addresses (CREATE2 deterministic - same on all mainnets)\nconst MAINNET_IDENTITY = '0x8004A169FB4a3325136EB29fA0ceB6D2e539a432';\nconst MAINNET_REPUTATION = '0x8004BAa17C55a88189AE136b182e5fdA19dE9b63';\n// Deployed after the identity/reputation pair, which is why it was missing here.\n// Verified live on all eleven EVM mainnets (Arc on 2026-09-23); SKALE Base has\n// no code at this address and is the one mainnet that legitimately has no\n// validation registry.\nconst MAINNET_VALIDATION = '0x8004Cc8439f36fd5F9F049D9fF86523Df6dAAB58';\n\n// Testnet addresses (same on all testnets)\nconst TESTNET_IDENTITY = '0x8004A818BFB912233c491871b3d84c89A494BD9e';\nconst TESTNET_REPUTATION = '0x8004B663056A597Dffe9eCcC1965A193B7388713';\nconst TESTNET_VALIDATION = '0x8004Cb1BF31DAf7788923b405b754f57acEB4272';\n\n// Solana program IDs (QuantuLabs 8004-solana)\nconst SOLANA_AGENT_REGISTRY = '8oo4dC4JvBLwy5tGgiH3WwK4B9PWxL9Z4XjA2jzkQMbQ';\nconst SOLANA_ATOM_ENGINE = 'AToMw53aiPQ8j7iHVb4fGt6nzUNxUhcPc3tbPBZuzVVb';\n\n/**\n * ERC-8004 contract addresses per network (23 networks: 21 EVM + 2 Solana)\n */\nexport const ERC8004_CONTRACTS: Record<string, {\n identityRegistry?: string;\n reputationRegistry?: string;\n validationRegistry?: string;\n agentRegistryProgram?: string;\n atomEngineProgram?: string;\n}> = {\n // Mainnets (12)\n ethereum: {\n identityRegistry: MAINNET_IDENTITY,\n reputationRegistry: MAINNET_REPUTATION,\n validationRegistry: MAINNET_VALIDATION,\n },\n base: {\n identityRegistry: MAINNET_IDENTITY,\n reputationRegistry: MAINNET_REPUTATION,\n validationRegistry: MAINNET_VALIDATION,\n },\n polygon: {\n identityRegistry: MAINNET_IDENTITY,\n reputationRegistry: MAINNET_REPUTATION,\n validationRegistry: MAINNET_VALIDATION,\n },\n arbitrum: {\n identityRegistry: MAINNET_IDENTITY,\n reputationRegistry: MAINNET_REPUTATION,\n validationRegistry: MAINNET_VALIDATION,\n },\n optimism: {\n identityRegistry: MAINNET_IDENTITY,\n reputationRegistry: MAINNET_REPUTATION,\n validationRegistry: MAINNET_VALIDATION,\n },\n celo: {\n identityRegistry: MAINNET_IDENTITY,\n reputationRegistry: MAINNET_REPUTATION,\n validationRegistry: MAINNET_VALIDATION,\n },\n bsc: {\n identityRegistry: MAINNET_IDENTITY,\n reputationRegistry: MAINNET_REPUTATION,\n validationRegistry: MAINNET_VALIDATION,\n },\n monad: {\n identityRegistry: MAINNET_IDENTITY,\n reputationRegistry: MAINNET_REPUTATION,\n validationRegistry: MAINNET_VALIDATION,\n },\n avalanche: {\n identityRegistry: MAINNET_IDENTITY,\n reputationRegistry: MAINNET_REPUTATION,\n validationRegistry: MAINNET_VALIDATION,\n },\n scroll: {\n identityRegistry: MAINNET_IDENTITY,\n reputationRegistry: MAINNET_REPUTATION,\n validationRegistry: MAINNET_VALIDATION,\n },\n // SKALE Base is the one mainnet without a validation registry (no code at\n // the canonical address), so leaving it out is correct, not an omission.\n 'skale-base': {\n identityRegistry: MAINNET_IDENTITY,\n reputationRegistry: MAINNET_REPUTATION,\n },\n // Arc (Circle, chain 5042). The facilitator names these three in\n // ARC_MAINNET_CONTRACTS (x402-rs 2.37.0+). Read on 2026-09-23 against\n // rpc.mainnet.arc.io: each is a 130-byte EIP-1967 proxy whose implementation\n // is the one Base runs, and getVersion() answers 2.0.0.\n arc: {\n identityRegistry: MAINNET_IDENTITY,\n reputationRegistry: MAINNET_REPUTATION,\n validationRegistry: MAINNET_VALIDATION,\n },\n // Deprecated alias for 'base' -- kept so existing lookups keep resolving.\n 'base-mainnet': {\n identityRegistry: MAINNET_IDENTITY,\n reputationRegistry: MAINNET_REPUTATION,\n validationRegistry: MAINNET_VALIDATION,\n },\n // Testnets (9)\n 'ethereum-sepolia': {\n identityRegistry: TESTNET_IDENTITY,\n reputationRegistry: TESTNET_REPUTATION,\n validationRegistry: TESTNET_VALIDATION,\n },\n 'base-sepolia': {\n identityRegistry: TESTNET_IDENTITY,\n reputationRegistry: TESTNET_REPUTATION,\n validationRegistry: TESTNET_VALIDATION,\n },\n 'polygon-amoy': {\n identityRegistry: TESTNET_IDENTITY,\n reputationRegistry: TESTNET_REPUTATION,\n validationRegistry: TESTNET_VALIDATION,\n },\n 'arbitrum-sepolia': {\n identityRegistry: TESTNET_IDENTITY,\n reputationRegistry: TESTNET_REPUTATION,\n validationRegistry: TESTNET_VALIDATION,\n },\n 'optimism-sepolia': {\n identityRegistry: TESTNET_IDENTITY,\n reputationRegistry: TESTNET_REPUTATION,\n validationRegistry: TESTNET_VALIDATION,\n },\n 'celo-sepolia': {\n identityRegistry: TESTNET_IDENTITY,\n reputationRegistry: TESTNET_REPUTATION,\n validationRegistry: TESTNET_VALIDATION,\n },\n 'avalanche-fuji': {\n identityRegistry: TESTNET_IDENTITY,\n reputationRegistry: TESTNET_REPUTATION,\n validationRegistry: TESTNET_VALIDATION,\n },\n 'skale-base-sepolia': {\n identityRegistry: TESTNET_IDENTITY,\n reputationRegistry: TESTNET_REPUTATION,\n validationRegistry: TESTNET_VALIDATION,\n },\n // Arc testnet (chain 5042002), ARC_TESTNET_CONTRACTS in the facilitator. Read\n // on 2026-09-23 against rpc.testnet.arc.io and rpc.testnet.arc.network: the\n // proxies Base Sepolia runs, validation registry included. Reads only -- no\n // FeedbackDelegate is deployed here, so it is not in RELAYED_FEEDBACK_NETWORKS.\n 'arc-testnet': {\n identityRegistry: TESTNET_IDENTITY,\n reputationRegistry: TESTNET_REPUTATION,\n validationRegistry: TESTNET_VALIDATION,\n },\n // Solana (2) - uses QuantuLabs 8004-solana Anchor program + ATOM Engine\n solana: {\n agentRegistryProgram: SOLANA_AGENT_REGISTRY,\n atomEngineProgram: SOLANA_ATOM_ENGINE,\n },\n 'solana-devnet': {\n agentRegistryProgram: SOLANA_AGENT_REGISTRY,\n atomEngineProgram: SOLANA_ATOM_ENGINE,\n },\n};\n\n/**\n * Return the network name the facilitator actually accepts.\n *\n * `base-mainnet` reads like the canonical spelling and is not: the facilitator\n * answers `400 {\"error\": \"Invalid network: base-mainnet\"}`. Every name is passed\n * through here before it reaches a URL or a request body, so callers holding the\n * old spelling keep working instead of being rejected at the edge.\n */\nexport function wireNetwork(network: string): string {\n return network === 'base-mainnet' ? 'base' : network;\n}\n\n/**\n * Network type for ERC-8004 operations (23 networks: 21 EVM + 2 Solana)\n *\n * These are the names the FACILITATOR accepts, verified against\n * GET /feedback -> supportedNetworks (all 23, facilitator 2.39.0, 2026-09-23).\n * 'base-mainnet' is kept only as a\n * deprecated alias: the facilitator rejects it outright (400 \"Invalid network\"),\n * so anything passed through this module is normalised to 'base' before it\n * reaches the wire. Use 'base'.\n */\nexport type Erc8004Network =\n // EVM Mainnets\n | 'ethereum' | 'base' | 'polygon' | 'arbitrum' | 'optimism' | 'celo' | 'bsc' | 'monad' | 'avalanche' | 'scroll' | 'skale-base' | 'arc'\n // Deprecated alias, rewritten to 'base' before it reaches the wire\n | 'base-mainnet'\n // EVM Testnets\n | 'ethereum-sepolia' | 'base-sepolia' | 'polygon-amoy' | 'arbitrum-sepolia' | 'optimism-sepolia' | 'celo-sepolia' | 'avalanche-fuji' | 'skale-base-sepolia' | 'arc-testnet'\n // Solana (uses QuantuLabs 8004-solana Anchor program + ATOM Engine)\n | 'solana' | 'solana-devnet';\n\n/**\n * Networks where the facilitator serves the RELAYED feedback rail, i.e. where\n * Execution Market has deployed a `FeedbackDelegate` and the facilitator\n * verified it on-chain (code present, and its `REPUTATION_REGISTRY()` reads\n * back that network's registry).\n *\n * Anywhere else `POST /feedback/evm/prepare` answers 400 — and it should. An\n * invented delegate address would send a type-4 transaction to an account with\n * no code behind it, and in the EVM a `.call()` to an address with no code\n * RETURNS SUCCESS. The failure would look exactly like a rating that rated\n * nobody.\n *\n * `avalanche` is absent and is not waiting to join: the C-Chain rejects the\n * transaction type itself (`-32000 transaction type not supported`), so there\n * is nothing to deploy against. Anchor the rating on a chain that supports\n * EIP-7702; the payment stays where it was made.\n *\n * `arc` joined with facilitator 2.38.0: Execution Market deployed the v4\n * delegate `0x955Cc9fB9aB95FC0821ae74197D273dde5dA84f1` there on 2026-09-23\n * (`VERSION()` = 4, `REPUTATION_REGISTRY()` = the mainnet registry), and\n * `prepare` answers 200 for it. `arc-testnet` serves ERC-8004 reads but has\n * no delegate, and `prepare` answers `400 \"relayed feedback is not available\n * on arc-testnet\"`. Arc mainnet having one is not a reason to assume it.\n */\nexport const RELAYED_FEEDBACK_NETWORKS: readonly Erc8004Network[] = [\n 'base',\n 'ethereum',\n 'polygon',\n 'arbitrum',\n 'optimism',\n 'celo',\n 'bsc',\n 'monad',\n 'arc',\n 'base-sepolia',\n] as const;\n\n/**\n * Whether `network` serves the rater-authored feedback rail.\n *\n * Lets a caller route without paying a round trip for a 400. The facilitator\n * re-checks the delegate on-chain on every request regardless — this list is a\n * routing hint, never the authority.\n */\nexport function supportsRelayedFeedback(network: string): boolean {\n return (RELAYED_FEEDBACK_NETWORKS as readonly string[]).includes(wireNetwork(network));\n}\n\n/**\n * Networks where the facilitator serves the rater-authored feedback rail on\n * **Solana**, through `POST /feedback/solana/prepare` + `/submit`.\n *\n * A separate list from {@link RELAYED_FEEDBACK_NETWORKS} on purpose, and the\n * two must never be merged. That one names the chains where Execution Market\n * deployed a `FeedbackDelegate` and the facilitator verified it on-chain; it\n * routes to `/feedback/evm/*`. Adding `solana` to it would send a Solana\n * rating to the EVM route, which answers 400 — and would claim a delegate that\n * does not exist and is not missing.\n *\n * Solana needs no delegate at all: account 0 of the program's `give_feedback`\n * instruction is already declared `[signer, writable] client`, so the rater\n * signs as the author natively and the facilitator only co-signs as fee payer.\n * Nothing is delegated because nothing has to be.\n *\n * Both networks are served by the deployed facilitator (v2.16.0, measured\n * against `GET /supported`).\n */\nexport const SOLANA_FEEDBACK_NETWORKS: readonly Erc8004Network[] = [\n 'solana',\n 'solana-devnet',\n] as const;\n\n/**\n * Whether `network` serves the rater-authored feedback rail on Solana.\n *\n * A routing hint, never the authority: the facilitator re-resolves the\n * programs and the RPC provider per request and answers\n * `400 \"<network> is not a Solana network served by this facilitator\"` for\n * anything else.\n */\nexport function supportsSolanaFeedback(network: string): boolean {\n return (SOLANA_FEEDBACK_NETWORKS as readonly string[]).includes(wireNetwork(network));\n}\n\n/**\n * An EIP-7702 authorization, as a wallet produces it.\n *\n * Needed only the first time a rater rates: it points their EOA at the\n * `FeedbackDelegate`. Once delegated, `prepare` answers `delegated: true` and\n * the submission carries no authorization at all.\n */\nexport interface RelayAuthorizationParams {\n /**\n * Chain the authorization is for.\n *\n * `0` is EIP-7702's wildcard and is valid on EVERY chain — a far broader\n * grant than pinning this one. Send the chain id `prepare` returned.\n */\n chainId: number;\n /**\n * The delegate the account is pointed at. Must be the address `prepare`\n * offered; the facilitator refuses anything else before it pays for a\n * transaction.\n */\n address: string;\n /** The rater account's nonce at the moment the authorization executes */\n nonce: number;\n yParity: number;\n r: string;\n s: string;\n}\n\n/**\n * Request body for `POST /feedback/evm/prepare`.\n *\n * `rater` is the address that will appear on-chain as the author, which is the\n * whole point of this rail.\n */\nexport interface PrepareRelayFeedbackRequest {\n x402Version: 1 | 2;\n network: Erc8004Network;\n feedback: FeedbackParams & { rater: string };\n}\n\n/**\n * Response from `POST /feedback/evm/prepare`.\n *\n * Everything the rater has to sign so the CHAIN records them as the author\n * while the facilitator pays the gas.\n */\nexport interface PrepareRelayFeedbackResponse {\n success: boolean;\n /** The `FeedbackDelegate` the rater's EOA must be delegated to */\n delegate?: string;\n /** Registry calldata the rater is authorising, hex-encoded */\n data?: string;\n /**\n * The value the rater's signature must recover against.\n *\n * **The EIP-191 envelope is already applied here.** A holder of a raw key\n * signs this directly as a prehash (viem's `sign({ hash })`, ethers'\n * `signingKey.sign`). A WALLET must not be handed this value: `personal_sign`\n * applies the envelope itself, so it gets wrapped twice and recovers an\n * address that is not the rater. Wallets sign {@link signingPayload}.\n */\n digest?: string;\n /**\n * The same hash with the envelope still OFF — what a wallet signs.\n *\n * `keccak256('\\x19Ethereum Signed Message:\\n32' || signingPayload)` is\n * exactly {@link digest}, so a client can check the two against each other\n * rather than rebuilding the preimage from `data`.\n *\n * Requires facilitator v1.95.0+. Older facilitators omit it; a client that\n * needs it should fail loudly rather than fall back to signing `digest`\n * through a wallet, which produces a well-formed signature that authorises\n * nobody.\n */\n signingPayload?: string;\n /**\n * The full `eth_signTypedData_v4` payload. **v4 delegates only.**\n *\n * Present exactly when the delegate deployed on that chain is v4, which the\n * facilitator reads from the chain per request rather than assuming from a\n * release. **When it is present, sign IT** — the wallet renders the agent, the\n * score, the tags and the deadline as named fields, so the rater sees what\n * they authorise instead of a hex blob.\n *\n * v4 carries no {@link signingPayload} and needs none: `signTypedData` has no\n * envelope to apply twice, which is the entire class of bug that kept the v3\n * rail at zero signatures for days.\n *\n * Requires facilitator v1.96.0+.\n */\n typedData?: Record<string, unknown>;\n /**\n * Unix seconds after which the authorisation is void. Short on purpose:\n * relaying is permissionless, so a signed authorisation is live in the wild\n * until it expires.\n */\n deadline?: number;\n /** Single-use value binding this authorisation. Echo it back on submit */\n nonce?: string;\n /**\n * Whether the account is already delegated. When `false` the submission MUST\n * carry an `authorization`.\n */\n delegated: boolean;\n /** The account nonce to put in the EIP-7702 authorization, when needed */\n accountNonce?: number;\n chainId: number;\n error?: string;\n network: Erc8004Network;\n}\n\n/**\n * Request body for `POST /feedback/evm/submit`.\n *\n * The feedback parameters are not redundant with `prepare`: the facilitator\n * rebuilds the registry calldata from them and requires the rater's signature\n * to cover exactly that. It does not relay calldata it was handed.\n */\nexport interface SubmitRelayFeedbackRequest {\n x402Version: 1 | 2;\n network: Erc8004Network;\n feedback: FeedbackParams & { rater: string };\n /** The deadline `prepare` returned */\n deadline: number;\n /** The single-use nonce `prepare` returned */\n nonce: string;\n /**\n * The rater's signature. It must recover to `rater` over `digest` — so\n * either a raw-key prehash signature over `digest`, or a wallet\n * `personal_sign` over `signingPayload`. Not `personal_sign` over `digest`.\n */\n signature: string;\n /** Required only when `prepare` answered `delegated: false` */\n authorization?: RelayAuthorizationParams;\n}\n\n/**\n * Request body for `POST /feedback/solana/prepare`.\n *\n * `rater` is REQUIRED here and is a base58 Solana pubkey — an `0x` address is\n * refused (`400 \"rater must be a base58 Solana pubkey on this network\"`).\n * `agentId` is the agent's asset pubkey, also base58.\n */\nexport interface PrepareSolanaFeedbackRequest {\n x402Version: 1 | 2;\n /** One of {@link SOLANA_FEEDBACK_NETWORKS} */\n network: Erc8004Network;\n /**\n * The rating, plus who signs it.\n *\n * **Set `score`.** It is optional on the wire and the ATOM Engine ignores an\n * unscored feedback entirely: the record lands on the agent, the transaction\n * succeeds, and the program reports `had_impact=false` — reputation stays at\n * zero however much unscored feedback accumulates, and it is not retroactive.\n * Omit it only when a deliberately non-scoring record is what you want.\n */\n feedback: FeedbackParams & { rater: string };\n}\n\n/**\n * Response from `POST /feedback/solana/prepare`.\n *\n * Carries an UNSIGNED transaction whose `client` account is the rater. Sign it\n * with the rater's key and hand it back to {@link Erc8004Client.submitSolanaFeedback}.\n */\nexport interface PrepareSolanaFeedbackResponse {\n success: boolean;\n /**\n * base64 of the bincode-serialised unsigned **legacy** transaction — read it\n * with `Transaction.from()`, not `VersionedTransaction`.\n *\n * It expects TWO signatures: the rater's, which you add, and the fee\n * payer's, which `/feedback/solana/submit` adds. Do not re-encode the\n * message or rebuild the instruction — the facilitator rebuilds it from the\n * declared parameters and refuses to co-sign anything that is not\n * byte-for-byte what it offered.\n */\n transaction?: string;\n /** Who must sign as `client`, i.e. who the chain will record as the author */\n rater?: string;\n /** Who pays the fee. Still the facilitator — that is the point */\n feePayer?: string;\n /** The blockhash baked into the message. Submit before it expires */\n blockhash?: string;\n /**\n * Last block height at which this transaction is still valid.\n *\n * Past it the network drops the transaction; nothing is written and nothing\n * is charged. Prepare again rather than resubmitting.\n */\n lastValidBlockHeight?: number;\n error?: string;\n network: Erc8004Network;\n}\n\n/**\n * Request body for `POST /feedback/solana/submit`.\n *\n * The feedback parameters are not redundant with `prepare`: the facilitator\n * re-derives the message from them plus the blockhash carried by\n * {@link transaction}, and refuses to co-sign anything that does not match\n * byte for byte. Signing arbitrary blobs would turn the fee-payer keypair into\n * a public signing oracle — one `system_program::transfer` would empty the\n * wallet with the facilitator's signature on it.\n */\nexport interface SubmitSolanaFeedbackRequest {\n x402Version: 1 | 2;\n network: Erc8004Network;\n /** Exactly what was sent to `prepare`, `rater` included */\n feedback: FeedbackParams & { rater: string };\n /** base64 of the rater-signed transaction */\n transaction: string;\n}\n\n/**\n * Request body for `POST /feedback/response/evm/prepare`.\n *\n * `responder` is the address the chain will record as the author.\n */\nexport interface PrepareRelayResponseRequest {\n x402Version: 1 | 2;\n network: Erc8004Network;\n responder: string;\n agentId: number | string;\n /** WHOSE feedback is being answered — inside the signed struct. */\n clientAddress: string;\n /** Which feedback (1-indexed) — also inside the struct. */\n feedbackIndex: number;\n responseUri: string;\n responseHash?: string;\n}\n\n/** Request body for `POST /feedback/response/evm/submit`. */\nexport interface SubmitRelayResponseRequest {\n x402Version: 1 | 2;\n network: Erc8004Network;\n responder: string;\n agentId: number | string;\n clientAddress: string;\n feedbackIndex: number;\n responseUri: string;\n responseHash?: string;\n deadline: number;\n nonce: string;\n /** The responder's signature over the typed data. */\n signature: string;\n authorization?: RelayAuthorizationParams;\n}\n\n/**\n * Proof of payment returned when settling with ERC-8004 extension\n */\nexport interface ProofOfPayment {\n /** Transaction hash of the settled payment */\n transactionHash: string;\n /** Block number where the transaction was included */\n blockNumber: number;\n /** Network where the payment was settled */\n network: string;\n /** The payer (consumer/client) address */\n payer: string;\n /** The payee (agent/resource owner) address */\n payee: string;\n /** Amount paid in token base units */\n amount: string;\n /** Token contract address */\n token: string;\n /** Unix timestamp of the block */\n timestamp: number;\n /** Keccak256 hash of the payment data for verification */\n paymentHash: string;\n}\n\n/**\n * Extended settle response with ERC-8004 proof of payment\n */\nexport interface SettleResponseWithProof extends SettleResponse {\n /** Proof of payment for ERC-8004 reputation submission */\n proofOfPayment?: ProofOfPayment;\n}\n\n/**\n * Agent identity from the Identity Registry\n */\nexport interface AgentIdentity {\n /** The agent's ID (EVM: sequential uint256, Solana: base58 pubkey string) */\n agentId: AgentId;\n /** Owner address of the agent NFT */\n owner: string;\n /** URI pointing to agent registration file */\n agentUri: string;\n /** Payment wallet address (if set) */\n agentWallet?: string;\n /** Network where the agent is registered */\n network: Erc8004Network;\n}\n\n/**\n * Agent registration file structure (resolved from agentURI)\n */\nexport interface AgentRegistrationFile {\n /** Type identifier */\n type: string;\n /** Agent name */\n name: string;\n /** Agent description */\n description: string;\n /** Image URL */\n image?: string;\n /** List of services the agent provides */\n services: AgentService[];\n /** Whether x402 payments are supported */\n x402Support: boolean;\n /** Whether the agent is active */\n active: boolean;\n /** List of registrations across chains */\n registrations: AgentRegistration[];\n /** Supported trust models */\n supportedTrust: string[];\n}\n\n/**\n * Agent service entry\n */\nexport interface AgentService {\n name: string;\n endpoint: string;\n version?: string;\n}\n\n/**\n * Agent registration reference\n */\nexport interface AgentRegistration {\n agentId: AgentId;\n agentRegistry: string; // Format: {namespace}:{chainId}:{address}\n}\n\n/**\n * Reputation summary for an agent\n */\nexport interface ReputationSummary {\n /** Agent ID (EVM: number, Solana: string) */\n agentId: AgentId;\n /** Number of feedback entries */\n count: number;\n /** Aggregated value */\n summaryValue: number;\n /** Decimal places for summaryValue */\n summaryValueDecimals: number;\n /** Network */\n network: Erc8004Network;\n}\n\n/**\n * Individual feedback entry\n */\nexport interface FeedbackEntry {\n /** Client who submitted the feedback */\n client: string;\n /** Feedback index (1-indexed) */\n feedbackIndex: number;\n /** Feedback value */\n value: number;\n /** Value decimals */\n valueDecimals: number;\n /** Primary tag */\n tag1: string;\n /** Secondary tag */\n tag2: string;\n /** Whether this feedback was revoked */\n isRevoked: boolean;\n}\n\n/**\n * Parameters for submitting reputation feedback\n */\nexport interface FeedbackParams {\n /** The agent's ID (EVM: tokenId number, Solana: base58 pubkey string) */\n agentId: AgentId;\n /** Feedback value (e.g., 87 for 87/100) */\n value: number;\n /** Decimal places for value interpretation (0-18) */\n valueDecimals?: number;\n /** Primary categorization tag (e.g., \"starred\", \"uptime\") */\n tag1?: string;\n /** Secondary categorization tag */\n tag2?: string;\n /** Service endpoint that was used */\n endpoint?: string;\n /** URI to off-chain feedback file (IPFS, HTTPS) */\n feedbackUri?: string;\n /** Keccak256 hash of feedback content (for integrity) */\n feedbackHash?: string;\n /**\n * Quality score 0-100.\n *\n * Solana only, and effectively required there: the ATOM Engine ignores an\n * unscored feedback. It is written to the agent but contributes nothing to\n * reputation, and the program reports `had_impact=false`. This is not\n * retroactive — reputation stays at zero however much unscored feedback\n * accumulates.\n */\n score?: number;\n /** Proof of payment (required for authorized feedback) */\n proof?: ProofOfPayment;\n}\n\n/**\n * Feedback request body for POST /feedback\n */\nexport interface FeedbackRequest {\n /** x402 protocol version */\n x402Version: 1 | 2;\n /** Network where feedback will be submitted */\n network: Erc8004Network;\n /** Feedback parameters */\n feedback: FeedbackParams;\n}\n\n/**\n * Feedback response from POST /feedback\n */\nexport interface FeedbackResponse extends FacilitatorFailureFields {\n /** Whether the feedback was successfully submitted */\n success: boolean;\n /** Transaction hash of the feedback submission */\n transaction?: string;\n /** Feedback index assigned (1-indexed) */\n feedbackIndex?: number;\n /** Error message (if failed) */\n error?: string;\n /** Network where feedback was submitted */\n network: Erc8004Network;\n}\n\n/**\n * Reputation query response\n */\n/**\n * Error from an ERC-8004 lookup, carrying the HTTP status as a field.\n *\n * `notFound` and `retryable` are mutually exclusive and must stay that way in\n * calling code: the facilitator answers 404 for \"this address owns no agent\"\n * and 503 for \"I could not find out\", usually an RPC failure behind it.\n * Treating a 503 as absence is how a transient failure becomes a permanent\n * wrong answer — on a registration path it mints a second agent for an owner\n * who already has one, burning gas and leaving an orphan.\n */\nexport class Erc8004LookupError extends Error {\n /** HTTP status returned by the facilitator */\n readonly status: number;\n /** Raw response body, for debugging */\n readonly body: string;\n /**\n * `Retry-After`, already clamped, when the facilitator sent one.\n *\n * Optional so every existing three-argument construction keeps compiling; it\n * falls back to the default wait rather than to zero, because a caller that\n * retries instantly on a 503 is the load that caused it.\n */\n private readonly retryAfterHint: number | undefined;\n\n constructor(message: string, status: number, body: string, retryAfterSeconds?: number) {\n super(message);\n this.name = 'Erc8004LookupError';\n this.status = status;\n this.body = body;\n this.retryAfterHint = retryAfterSeconds;\n }\n\n /** The address genuinely owns no agent on this network. */\n get notFound(): boolean {\n return this.status === 404;\n }\n\n /**\n * The lookup reached no verdict. Retry; never read as \"owns nothing\".\n *\n * `502` and `504` join `503` and `429` here: a gateway that answered on the\n * facilitator's behalf is exactly as silent about the agent's existence, and\n * reading either as absence has the same consequence -- a duplicate mint.\n *\n * **Except when the body says otherwise.** `POST /register` goes through the\n * same EVM `send_transaction_from` as a settle, so it can answer\n * `settlement_unconfirmed`: the mint was broadcast and may be mined. That is\n * a `502` where retrying is precisely the thing that mints the duplicate this\n * class exists to prevent, so an explicit `retryable: false` wins over the\n * status. See {@link SETTLEMENT_UNCONFIRMED}.\n */\n get retryable(): boolean {\n const parsed = parseFacilitatorErrorBody(this.body);\n if (parsed.retryable === false || parsed.errorCode === SETTLEMENT_UNCONFIRMED) {\n return false;\n }\n return (\n this.status === 429 ||\n this.status === 502 ||\n this.status === 503 ||\n this.status === 504\n );\n }\n\n /**\n * The facilitator's own `reason`, when the body carried one.\n *\n * On a WRITE route this is the writer-lease reason and it decides whether the\n * request may be re-sent; see {@link isReplayableLeaseReason}.\n */\n get reason(): string | undefined {\n return parseFacilitatorErrorBody(this.body).reason;\n }\n\n /** The facilitator's machine-readable `error` code, when the body carried one. */\n get errorCode(): string | undefined {\n return parseFacilitatorErrorBody(this.body).errorCode;\n }\n\n /**\n * A transaction that WAS broadcast and could not be confirmed.\n *\n * Present on `settlement_unconfirmed`. This is what to do INSTEAD of\n * retrying: look it up on chain. An error that carries \"do not retry\" and no\n * hash leaves the caller with nothing to act on.\n */\n get transaction(): string | undefined {\n return parseFacilitatorErrorBody(this.body).transaction;\n }\n\n /** The payment id for {@link transaction}, identical to a successful settle's. */\n get paymentId(): string | undefined {\n return parseFacilitatorErrorBody(this.body).paymentId;\n }\n\n /**\n * The facilitator NAMED a reason proving it executed nothing.\n *\n * False for `forward_failed` and for every unattributed 5xx: \"something\n * answered\" is not evidence that nothing ran. On `/register`, replaying when\n * this is false is the sequence that minted five duplicate agents.\n */\n get safeToReplay(): boolean {\n // Gated on `retryable` so the two can never disagree: an error this SDK\n // will not retry at all must never be described as safe to replay.\n return (\n this.retryable &&\n (this.status === 429 || (this.status === 503 && isReplayableLeaseReason(this.reason)))\n );\n }\n\n /** Seconds to wait before retrying, clamped. Absent when not retryable. */\n get retryAfterSeconds(): number | undefined {\n if (!this.retryable) return undefined;\n return this.retryAfterHint ?? DEFAULT_RETRY_AFTER_SECONDS;\n }\n}\n\n/**\n * ATOM Engine reputation analytics (Solana only).\n *\n * Present only when the agent's `atom_stats` account has been initialized. The\n * facilitator does that during `registerAgent`; agents registered elsewhere may\n * never have it, in which case their feedback is never scored.\n *\n * The engine measures quality through EMA scores, so there are no\n * positive/negative tallies.\n */\nexport interface AtomStats {\n /** Trust tier 0-4 */\n trustTier: number;\n /** Human-readable trust tier */\n trustTierName: string;\n /** Cached quality score */\n qualityScore: number;\n /** Cached loyalty score */\n loyaltyScore: number;\n /** Statistical confidence */\n confidence: number;\n /** Risk assessment (lower is better) */\n riskScore: number;\n /** Client diversity from HyperLogLog */\n diversityRatio: number;\n /** Lowest score ever recorded */\n minScore: number;\n /** Highest score ever recorded */\n maxScore: number;\n /** Most recent score recorded */\n lastScore: number;\n /** Total feedback counted by the engine */\n feedbackCount: number;\n /** Slot of the most recent feedback */\n lastFeedbackSlot: number;\n}\n\nexport interface ReputationResponse {\n agentId: AgentId;\n summary: ReputationSummary;\n feedback?: FeedbackEntry[];\n /** ATOM Engine analytics; absent when the agent has no initialized stats */\n atomStats?: AtomStats | null;\n network: Erc8004Network;\n}\n\n/**\n * Key-value metadata entry for agent registration\n */\nexport interface MetadataEntryParam {\n /** Metadata key */\n key: string;\n /** Metadata value (hex-encoded bytes or UTF-8 string) */\n value: string;\n}\n\n/**\n * Request body for POST /register\n */\nexport interface RegisterAgentRequest {\n /** x402 protocol version */\n x402Version: 1 | 2;\n /** Network where agent will be registered */\n network: Erc8004Network;\n /** URI pointing to agent registration file (IPFS, HTTPS) */\n agentUri: string;\n /** Optional metadata key-value pairs */\n metadata?: MetadataEntryParam[];\n /** Optional recipient address - NFT is transferred to this address after minting */\n recipient?: string;\n}\n\n/**\n * Response from POST /register\n */\nexport interface RegisterAgentResponse extends FacilitatorFailureFields {\n /** Whether registration succeeded */\n success: boolean;\n /** The newly assigned agent ID (EVM: tokenId number, Solana: base58 pubkey string) */\n agentId?: AgentId;\n /** Registration transaction hash */\n transaction?: string;\n /** Transfer transaction hash (if recipient was specified) */\n transferTransaction?: string;\n /** Owner address of the agent NFT */\n owner?: string;\n /** Error message if failed */\n error?: string;\n /** Network where agent was registered */\n network: string;\n}\n\n/**\n * Response from GET /identity/{network}/owner/{address}\n */\nexport interface IdentityByOwnerResponse {\n /** First (lowest) token ID owned by this address */\n agentId: AgentId;\n /** The queried address (checksummed) */\n owner: string;\n /** Agent's registration URI (may be empty) */\n agentUri: string;\n /** Network name */\n network: string;\n /** Total number of agent NFTs owned (as string) */\n balance: string;\n}\n\n/**\n * Response from GET /identity/{network}/{agent_id}/metadata/{key}\n */\n/**\n * Lifecycle of an async registration. `mint_confirmed` and `done` carry an\n * `agentId`; `failed` carries an `error`.\n */\nexport type RegisterJobStatus = 'pending' | 'mint_confirmed' | 'done' | 'failed';\n\n/**\n * Status of an asynchronous registration.\n *\n * Returned by `POST /register` with `Prefer: respond-async` (HTTP 202) and by\n * `GET /register/status/{jobId}`.\n *\n * Terminal jobs are retained for one hour and then age out, after which the\n * status endpoint 404s. Read the agent id before then, or it is only\n * recoverable from the chain.\n */\nexport interface RegisterJobResponse {\n jobId: string;\n status: RegisterJobStatus;\n network?: string;\n agentId?: AgentId;\n transaction?: string;\n transferTransaction?: string;\n owner?: string;\n error?: string;\n}\n\n/** Whether polling can stop: the job either finished or failed. */\nexport function isRegisterJobTerminal(job: RegisterJobResponse): boolean {\n return job.status === 'done' || job.status === 'failed';\n}\n\n/**\n * Thrown when a registration is still running after the wait elapsed.\n *\n * This is emphatically **not** a failure. The mint may still land. `jobId` is a\n * field rather than only part of the message, because the correct recovery is to\n * keep polling `getRegisterStatus(jobId)` — and a caller who cannot reach the id\n * without parsing a string will re-register instead, minting a duplicate agent.\n * That is the exact sequence that once produced five duplicate mints.\n *\n * Never map this to \"registration failed\".\n */\nexport class RegistrationPendingError extends Error {\n readonly jobId: string;\n readonly lastStatus: RegisterJobStatus;\n readonly timeoutMs: number;\n readonly retryable = true;\n\n constructor(jobId: string, lastStatus: RegisterJobStatus, timeoutMs: number) {\n super(\n `Registration job ${jobId} still '${lastStatus}' after ${Math.round(\n timeoutMs / 1000,\n )}s. It may still complete: poll getRegisterStatus('${jobId}') rather than registering again.`,\n );\n this.name = 'RegistrationPendingError';\n this.jobId = jobId;\n this.lastStatus = lastStatus;\n this.timeoutMs = timeoutMs;\n }\n}\n\n/**\n * Present a finished async job in the shape the synchronous call returns.\n *\n * Keeping the return type identical is the whole point of `asyncTransport`:\n * switching transports must not force callers to rewrite anything downstream.\n */\nfunction jobToRegisterResponse(\n job: RegisterJobResponse,\n network: Erc8004Network,\n): RegisterAgentResponse {\n return {\n success: job.status !== 'failed',\n agentId: job.agentId,\n transaction: job.transaction,\n transferTransaction: job.transferTransaction,\n owner: job.owner,\n error: job.error,\n network: (job.network as Erc8004Network) ?? network,\n };\n}\n\nexport interface IdentityMetadataResponse {\n /** Agent ID (EVM: number, Solana: string) */\n agentId: AgentId;\n /** Metadata key */\n key: string;\n /**\n * Raw hex-encoded value. The facilitator sends this as `value`; this field\n * used to be declared as `valueHex`, which no response ever carried, so it\n * was always undefined at runtime.\n */\n value: string;\n /** UTF-8 decoded value (if decodable) */\n valueUtf8?: string;\n /** Whether the entry can still be changed */\n immutable?: boolean;\n /** Network */\n network: string;\n}\n\n/**\n * Response from GET /identity/{network}/total-supply\n *\n * On Solana the counts come from the Metaplex Core collection, not the registry,\n * which keeps no counter of its own.\n */\nexport interface IdentityTotalSupplyResponse {\n /** Registered agents, net of burns */\n totalSupply: number;\n /** All-time mint count (Solana) */\n numMinted?: number;\n /** Metaplex Core collection backing the count (Solana) */\n collection?: string;\n /** Network */\n network: string;\n}\n\n/**\n * Options for the ERC8004Client\n */\nexport interface Erc8004ClientOptions {\n /** Base URL of the facilitator (default: https://facilitator.ultravioletadao.xyz) */\n baseUrl?: string;\n /** Request timeout in milliseconds (default: 30000) */\n timeout?: number;\n /**\n * Extra attempts after the first, spent only on a refusal the facilitator\n * proved it did not execute. Default 2; `0` disables. An ambiguous\n * `forward_failed` is never replayed at any setting.\n */\n retries?: number;\n}\n\n/**\n * Client for ERC-8004 Trustless Agents API\n *\n * Provides methods for:\n * - Registering new agents (gasless, facilitator pays gas)\n * - Registering agents on behalf of users (gasless delegation)\n * - Querying agent identity, metadata, and total supply\n * - Querying agent reputation\n * - Submitting reputation feedback\n * - Revoking feedback\n *\n * @example\n * ```ts\n * const client = new Erc8004Client();\n *\n * // Get agent identity\n * const identity = await client.getIdentity('ethereum', 42);\n * console.log(identity.agentUri);\n *\n * // Get agent reputation\n * const reputation = await client.getReputation('ethereum', 42);\n * console.log(`Score: ${reputation.summary.summaryValue}`);\n *\n * // Submit feedback after payment\n * const result = await client.submitFeedback({\n * x402Version: 1,\n * network: 'ethereum',\n * feedback: {\n * agentId: 42,\n * value: 95,\n * valueDecimals: 0,\n * tag1: 'quality',\n * proof: settleResponse.proofOfPayment,\n * },\n * });\n * ```\n */\nexport class Erc8004Client {\n private readonly baseUrl: string;\n private readonly timeout: number;\n private readonly retries: number | undefined;\n\n constructor(options: Erc8004ClientOptions = {}) {\n this.baseUrl = options.baseUrl || 'https://facilitator.ultravioletadao.xyz';\n this.timeout = options.timeout || 30000;\n this.retries = options.retries;\n }\n\n /**\n * POST a write route, keeping a refusal readable.\n *\n * Every ERC-8004 write goes through the facilitator's EVM writer lease, so\n * every one of them can answer `503` + `reason`. Flattened to a string, those\n * are indistinguishable from \"the registry rejected your feedback\" — and on\n * `/register` the wrong reading re-POSTs a mint that may already have landed,\n * which is precisely how five duplicate agents were once created.\n *\n * A refusal the facilitator proved it did not execute is replayed\n * automatically (`safeToReplay`); `forward_failed` never is.\n */\n private async writeJson(\n url: string,\n body: unknown,\n extraHeaders: Record<string, string> = {},\n ): Promise<{ response: Response; error?: FacilitatorErrorInfo }> {\n return facilitatorFetch(\n url,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n ...extraHeaders,\n },\n body: JSON.stringify(body),\n },\n { timeoutMs: this.timeout, retries: this.retries },\n );\n }\n\n /**\n * Get agent identity from the Identity Registry\n *\n * @param network - Network where agent is registered\n * @param agentId - Agent's tokenId\n * @returns Agent identity information\n */\n async getIdentity(network: Erc8004Network, agentId: AgentId): Promise<AgentIdentity> {\n const url = `${this.baseUrl}/identity/${wireNetwork(network)}/${agentId}`;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(url, {\n method: 'GET',\n headers: { 'Accept': 'application/json' },\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`ERC-8004 API error: ${response.status} - ${errorText}`);\n }\n\n return await response.json();\n } catch (error) {\n clearTimeout(timeoutId);\n throw error;\n }\n }\n\n /**\n * Get agent identity by owner address\n *\n * Resolves the first ERC-8004 agent ID owned by a wallet address on a given network.\n *\n * @param network - Network to query\n * @param address - Owner wallet address\n * @returns Agent identity information including balance\n *\n * @example\n * ```ts\n * const identity = await client.getIdentityByOwner('base-mainnet', '0x52E0...');\n * console.log(`Agent #${identity.agentId}, balance: ${identity.balance}`);\n * ```\n */\n async getIdentityByOwner(network: Erc8004Network, address: string): Promise<IdentityByOwnerResponse> {\n const url = `${this.baseUrl}/identity/${wireNetwork(network)}/owner/${address}`;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n const response = await fetch(url, {\n method: 'GET',\n headers: { Accept: 'application/json' },\n signal: controller.signal,\n }).finally(() => clearTimeout(timeoutId));\n\n if (!response.ok) {\n // 404 and 503 are different answers: \"owns nothing\" versus \"could not\n // find out\". Reading the status out of a message string is how they get\n // collapsed, and collapsing them mints a duplicate agent for an owner\n // who already has one. Carry the status, the reason and the wait as\n // fields.\n const info = await readFacilitatorError(response);\n throw new Erc8004LookupError(\n `ERC-8004 API error: ${info.status} - ${info.body}`,\n info.status,\n info.body,\n info.retryAfterSeconds,\n );\n }\n\n return await response.json();\n }\n\n /**\n * Resolve agent registration file from agentURI\n *\n * @param agentUri - URI pointing to agent registration file\n * @returns Resolved agent registration file\n */\n async resolveAgentUri(agentUri: string): Promise<AgentRegistrationFile> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n // Handle IPFS URIs\n let url = agentUri;\n if (agentUri.startsWith('ipfs://')) {\n const cid = agentUri.replace('ipfs://', '');\n url = `https://ipfs.io/ipfs/${cid}`;\n }\n\n const response = await fetch(url, {\n method: 'GET',\n headers: { 'Accept': 'application/json' },\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n throw new Error(`Failed to resolve agentURI: ${response.status}`);\n }\n\n return await response.json();\n } catch (error) {\n clearTimeout(timeoutId);\n throw error;\n }\n }\n\n /**\n * Get agent reputation from the Reputation Registry\n *\n * @param network - Network where agent is registered\n * @param agentId - Agent's tokenId\n * @param options - Query options (tag filters, include individual feedback, client addresses)\n * @param options.clientAddresses - Comma-separated client addresses to filter by.\n * If omitted, the facilitator auto-discovers all clients via getClients().\n * @returns Reputation summary and optionally individual feedback entries\n */\n async getReputation(\n network: Erc8004Network,\n agentId: AgentId,\n options: {\n tag1?: string;\n tag2?: string;\n includeFeedback?: boolean;\n clientAddresses?: string;\n } = {}\n ): Promise<ReputationResponse> {\n const params = new URLSearchParams();\n if (options.tag1) params.set('tag1', options.tag1);\n if (options.tag2) params.set('tag2', options.tag2);\n if (options.includeFeedback) params.set('includeFeedback', 'true');\n if (options.clientAddresses) params.set('clientAddresses', options.clientAddresses);\n\n const url = `${this.baseUrl}/reputation/${wireNetwork(network)}/${agentId}${params.toString() ? `?${params}` : ''}`;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(url, {\n method: 'GET',\n headers: { 'Accept': 'application/json' },\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`ERC-8004 API error: ${response.status} - ${errorText}`);\n }\n\n return await response.json();\n } catch (error) {\n clearTimeout(timeoutId);\n throw error;\n }\n }\n\n /**\n * Submit reputation feedback for an agent\n *\n * Requires proof of payment for authorized feedback submission.\n *\n * @deprecated On this route the facilitator is the AUTHOR: the registry\n * records `msg.sender`, and that is the facilitator's wallet — which can also\n * revoke what it wrote. On the networks in {@link RELAYED_FEEDBACK_NETWORKS}\n * use {@link Erc8004Client.prepareRelayedFeedback} +\n * {@link Erc8004Client.submitRelayedFeedback} instead, which record the RATER\n * as author. This route still works and is not going away without notice: it\n * is the only one available where no `FeedbackDelegate` is deployed.\n *\n * @param request - Feedback request with agent ID, value, and proof\n * @returns Feedback response with transaction hash\n *\n * @example\n * ```ts\n * // After settling a payment with ERC-8004 extension\n * const settleResult = await facilitator.settle(payment, {\n * ...requirements,\n * extra: { '8004-reputation': { includeProof: true } },\n * });\n *\n * // Submit feedback with proof of payment\n * const feedback = await erc8004.submitFeedback({\n * x402Version: 1,\n * network: 'ethereum',\n * feedback: {\n * agentId: 42,\n * value: 95, // 95/100\n * valueDecimals: 0,\n * tag1: 'quality',\n * tag2: 'response-time',\n * proof: settleResult.proofOfPayment,\n * },\n * });\n * ```\n */\n async submitFeedback(request: FeedbackRequest): Promise<FeedbackResponse> {\n const url = `${this.baseUrl}/feedback`;\n\n try {\n const { response, error } = await this.writeJson(url, {\n ...request,\n network: wireNetwork(request.network),\n });\n\n if (error) {\n return {\n success: false,\n error: error.error,\n network: request.network,\n ...failureFields(error),\n };\n }\n\n return await response.json();\n } catch (error) {\n // Timeout or connection failure: the write may already be on-chain.\n // Retryable, never replayable -- reconcile before resending.\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error',\n network: request.network,\n retryable: true,\n safeToReplay: false,\n retryAfterSeconds: DEFAULT_RETRY_AFTER_SECONDS,\n };\n }\n }\n\n /**\n * Ask the facilitator what the rater must sign to author a rating.\n *\n * Step 1 of the rater-authored rail. Writes nothing on-chain and costs\n * nothing: it reads the delegate, the rater's delegation state and their\n * account nonce, then hands back a digest, a deadline and a single-use nonce.\n *\n * Why this exists: the ERC-8004 Reputation Registry records `msg.sender` as\n * the author, and the deployed implementation has no delegation path — no\n * `giveFeedbackWithSignature`, no ERC-2771 forwarder. So a rating the\n * facilitator relays the ordinary way is a rating attributed to the\n * FACILITATOR. EIP-7702 fixes it without touching the registry: the rater\n * delegates their own EOA to the `FeedbackDelegate` and the transaction is\n * sent TO THE RATER'S ADDRESS, so the registry sees the rater while the\n * facilitator pays.\n *\n * What to do with the answer:\n * 1. Produce the rater's signature. **Which value you sign depends on how you\n * sign it**, and getting it wrong yields a well-formed signature that\n * authorises nobody:\n * - raw key: sign `digest` as a **prehash**. It already carries the\n * EIP-191 envelope.\n * - wallet: `personal_sign` over `signingPayload`. `personal_sign` adds the\n * envelope itself, so signing `digest` with it wraps the value TWICE and\n * recovers a stranger — the only symptom is `relay_bad_signature`.\n * - **unless `typedData` came back** — that chain runs a v4 delegate. Then\n * sign THAT with `eth_signTypedData_v4` and ignore the other two: it is\n * the only form the rater can read, and it has no envelope ambiguity.\n * 2. If `delegated` is `false`, also produce an EIP-7702 authorization over\n * `(chainId, delegate, accountNonce)`.\n * 3. Hand both to {@link submitRelayedFeedback} with the SAME feedback\n * parameters, `deadline` and `nonce`.\n *\n * @param request - Network, rater address and feedback parameters\n * @returns Everything needed to sign, including whether an EIP-7702\n * authorization is still required\n *\n * @example\n * ```ts\n * const prep = await erc8004.prepareRelayedFeedback({\n * x402Version: 1,\n * network: 'base',\n * feedback: { agentId: 18896, value: 95, tag1: 'quality', rater: raterAddress },\n * });\n * // prep.delegated === false -> an EIP-7702 authorization is required\n * ```\n */\n async prepareRelayedFeedback(\n request: PrepareRelayFeedbackRequest,\n ): Promise<PrepareRelayFeedbackResponse> {\n const url = `${this.baseUrl}/feedback/evm/prepare`;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n },\n body: JSON.stringify({ ...request, network: wireNetwork(request.network) }),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorText = await response.text();\n return {\n success: false,\n delegated: false,\n chainId: 0,\n error: `Facilitator error: ${response.status} - ${errorText}`,\n network: request.network,\n };\n }\n\n return await response.json();\n } catch (error) {\n clearTimeout(timeoutId);\n return {\n success: false,\n delegated: false,\n chainId: 0,\n error: error instanceof Error ? error.message : 'Unknown error',\n network: request.network,\n };\n }\n }\n\n /**\n * Relay a rater-authored rating; the facilitator pays the gas.\n *\n * Step 2 of the rater-authored rail. The on-chain record that comes out of it\n * has the RATER as `msg.sender`, so `getClients(agentId)` shows the rater\n * rather than the facilitator.\n *\n * Pass back the same feedback parameters, `deadline` and `nonce` that\n * {@link prepareRelayedFeedback} returned. They are not redundant: the\n * facilitator rebuilds the registry calldata from them and requires the\n * rater's signature to cover exactly that.\n *\n * `authorization` is required only when `prepare` answered\n * `delegated: false`. One that names a different delegate than the one\n * `prepare` offered is refused before any gas is spent.\n *\n * @param request - Feedback parameters plus the rater's signature\n * @returns Feedback response with the transaction hash\n */\n async submitRelayedFeedback(\n request: SubmitRelayFeedbackRequest,\n ): Promise<FeedbackResponse> {\n const url = `${this.baseUrl}/feedback/evm/submit`;\n\n try {\n const { response, error } = await this.writeJson(url, {\n ...request,\n network: wireNetwork(request.network),\n });\n\n if (error) {\n return {\n success: false,\n error: error.error,\n network: request.network,\n ...failureFields(error),\n };\n }\n\n return await response.json();\n } catch (error) {\n // Timeout or connection failure: the write may already be on-chain.\n // Retryable, never replayable -- reconcile before resending.\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error',\n network: request.network,\n retryable: true,\n safeToReplay: false,\n retryAfterSeconds: DEFAULT_RETRY_AFTER_SECONDS,\n };\n }\n }\n\n /**\n * Ask the facilitator for the Solana transaction the rater must sign.\n *\n * Step 1 of the rater-authored rail on Solana. Writes nothing on-chain and\n * costs nothing: it resolves the programs and the agent asset, reads the\n * registry collection and a finalized blockhash, and hands back an UNSIGNED\n * transaction whose `client` account is the rater.\n *\n * Why this exists, and why it is not the EVM rail: the program's\n * `give_feedback` instruction declares account 0 as\n * `[signer, writable] client (feedback author / fee payer)`, and plain\n * `POST /feedback` puts the FACILITATOR's keypair there — so the chain\n * records the facilitator as the author of the rating. Solana carries several\n * signers per transaction natively, so the rater signs as `client` while the\n * facilitator stays the fee payer. **No delegation and no program change**,\n * which is why {@link SOLANA_FEEDBACK_NETWORKS} is its own list and `solana`\n * must never appear in {@link RELAYED_FEEDBACK_NETWORKS} — that one routes to\n * `/feedback/evm/*`, which answers 400 here.\n *\n * What to do with the answer:\n * 1. Deserialise `transaction` — base64 of the bincode-serialised **legacy**\n * transaction, which is `@solana/web3.js`'s `Transaction.from()`, not\n * `VersionedTransaction` — and add the RATER's ed25519 signature. Sign the\n * message as it came: re-encoding it changes bytes the facilitator will\n * compare. The fee payer's slot stays empty; `submit` fills it.\n * 2. Hand it back to {@link Erc8004Client.submitSolanaFeedback} with the SAME\n * feedback parameters, before `lastValidBlockHeight` passes.\n *\n * @param request - Network, rater pubkey and feedback parameters\n * @returns The unsigned transaction, the fee payer and the blockhash window\n *\n * @example\n * ```ts\n * import { Transaction } from '@solana/web3.js';\n *\n * const prep = await erc8004.prepareSolanaFeedback({\n * x402Version: 1,\n * network: 'solana',\n * feedback: {\n * agentId: '7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgHkv',\n * rater: raterPubkey, // base58: who the chain records as the author\n * value: 87,\n * score: 95, // without it the rating counts for nothing\n * tag1: 'quality',\n * },\n * });\n *\n * const tx = Transaction.from(Buffer.from(prep.transaction!, 'base64'));\n * tx.partialSign(raterKeypair);\n * ```\n */\n async prepareSolanaFeedback(\n request: PrepareSolanaFeedbackRequest,\n ): Promise<PrepareSolanaFeedbackResponse> {\n const url = `${this.baseUrl}/feedback/solana/prepare`;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n },\n body: JSON.stringify({ ...request, network: wireNetwork(request.network) }),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorText = await response.text();\n return {\n success: false,\n error: `Facilitator error: ${response.status} - ${errorText}`,\n network: request.network,\n };\n }\n\n return await response.json();\n } catch (error) {\n clearTimeout(timeoutId);\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error',\n network: request.network,\n };\n }\n }\n\n /**\n * Co-sign and send a rater-signed Solana feedback transaction.\n *\n * Step 2 of the rater-authored rail on Solana. What lands on-chain has the\n * RATER as `client`, so the agent's feedback lists the rater rather than the\n * facilitator — and only the rater can revoke it.\n *\n * Pass back the same feedback parameters {@link Erc8004Client.prepareSolanaFeedback}\n * was given. They are not redundant: the facilitator re-derives the message\n * from them plus the blockhash inside the submitted transaction, and refuses\n * to co-sign anything that is not byte-for-byte what it built\n * (`400 \"submitted transaction does not match the one this facilitator built\"`).\n * The rater's signature is verified BEFORE the facilitator adds its own, so a\n * transaction the network would reject never costs a fee.\n *\n * @param request - Feedback parameters plus the rater-signed transaction\n * @returns Feedback response with the transaction signature\n */\n async submitSolanaFeedback(\n request: SubmitSolanaFeedbackRequest,\n ): Promise<FeedbackResponse> {\n const url = `${this.baseUrl}/feedback/solana/submit`;\n\n try {\n const { response, error } = await this.writeJson(url, {\n ...request,\n network: wireNetwork(request.network),\n });\n\n if (error) {\n return {\n success: false,\n error: error.error,\n network: request.network,\n ...failureFields(error),\n };\n }\n\n return await response.json();\n } catch (error) {\n // Timeout or connection failure: the write may already be on-chain.\n // Retryable, never replayable -- and on this rail a resubmission needs a\n // fresh `prepare`, because the blockhash the rater signed over expires.\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error',\n network: request.network,\n retryable: true,\n safeToReplay: false,\n retryAfterSeconds: DEFAULT_RETRY_AFTER_SECONDS,\n };\n }\n }\n\n /**\n * Revoke previously submitted feedback\n *\n * Only the original submitter can revoke their feedback.\n *\n * @param network - Network where feedback was submitted\n * @param agentId - Agent ID\n * @param feedbackIndex - Index of feedback to revoke\n * @returns Revocation result\n */\n async revokeFeedback(\n network: Erc8004Network,\n agentId: AgentId,\n feedbackIndex: number,\n options?: { sealHash?: string; originalFeedback?: Omit<FeedbackParams, 'agentId' | 'proof'> }\n ): Promise<FeedbackResponse> {\n const url = `${this.baseUrl}/feedback/revoke`;\n\n const payload: Record<string, unknown> = {\n x402Version: 1,\n network: wireNetwork(network),\n agentId,\n feedbackIndex,\n };\n // Solana revocations need the SEAL hash of the feedback being revoked. Pass\n // originalFeedback and the facilitator derives it; computing it yourself\n // means reimplementing the program's keccak256 layout exactly.\n if (options?.sealHash) {\n payload.sealHash = options.sealHash;\n } else if (options?.originalFeedback) {\n payload.originalFeedback = options.originalFeedback;\n }\n\n try {\n const { response, error } = await this.writeJson(url, payload);\n\n if (error) {\n return {\n success: false,\n error: error.error,\n network,\n ...failureFields(error),\n };\n }\n\n return await response.json();\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error',\n network,\n retryable: true,\n safeToReplay: false,\n retryAfterSeconds: DEFAULT_RETRY_AFTER_SECONDS,\n };\n }\n }\n\n /**\n * Get ERC-8004 contract addresses for a network\n *\n * @param network - Network to get contracts for\n * @returns Contract addresses or undefined if not deployed\n */\n getContracts(network: Erc8004Network): typeof ERC8004_CONTRACTS[Erc8004Network] | undefined {\n return ERC8004_CONTRACTS[network];\n }\n\n /**\n * Check if ERC-8004 is available on a network\n *\n * @param network - Network to check\n * @returns True if ERC-8004 contracts are deployed\n */\n isAvailable(network: string): network is Erc8004Network {\n return network in ERC8004_CONTRACTS;\n }\n\n /**\n * Get feedback endpoint metadata\n *\n * @returns Endpoint information for /feedback\n */\n async getFeedbackMetadata(): Promise<{\n endpoint: string;\n supportedNetworks: Erc8004Network[];\n version: string;\n }> {\n const url = `${this.baseUrl}/feedback`;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(url, {\n method: 'GET',\n headers: { 'Accept': 'application/json' },\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n throw new Error(`Failed to get feedback metadata: ${response.status}`);\n }\n\n return await response.json();\n } catch (error) {\n clearTimeout(timeoutId);\n throw error;\n }\n }\n\n /**\n * Ask what the RESPONDER must sign to author a response on-chain.\n *\n * The mirror of {@link prepareRelayedFeedback}, for the other write the\n * registry accepts from anybody. `appendResponse` is not agent-only — the\n * registry takes it from any address — so on the plain {@link appendResponse}\n * route the `responder` recorded on-chain is the FACILITATOR. That does not\n * destroy anyone's reputation the way a revoke would; it ties the\n * facilitator's on-chain identity to a third party's content, which is its own\n * kind of wrong.\n *\n * **v4 delegates only.** The v3 delegate accepts exactly two selectors and\n * `appendResponse` is not one of them, so a v3 network answers 400\n * `relay_response_needs_v4` rather than silently falling back to the route\n * this replaces.\n *\n * `clientAddress` and `feedbackIndex` are inside the signed struct: without\n * them one signature would answer any client's rating, or any rating at that\n * index.\n */\n async prepareRelayedResponse(\n request: PrepareRelayResponseRequest\n ): Promise<PrepareRelayFeedbackResponse> {\n return this.postRelay('/feedback/response/evm/prepare', request, {\n success: false,\n delegated: false,\n chainId: 0,\n network: request.network,\n });\n }\n\n /**\n * Relay a responder-authored response; the facilitator pays the gas.\n *\n * Pass back the same parameters, `deadline` and `nonce` that\n * {@link prepareRelayedResponse} returned: the facilitator rebuilds the struct\n * from them and refuses to relay anything the signature does not cover.\n */\n async submitRelayedResponse(\n request: SubmitRelayResponseRequest\n ): Promise<FeedbackResponse> {\n return this.postRelay('/feedback/response/evm/submit', request, {\n success: false,\n network: request.network,\n });\n }\n\n /** Shared POST for the relay routes: a refusal is data, never a throw. */\n private async postRelay<T>(path: string, request: { network: Erc8004Network }, onError: T): Promise<T> {\n try {\n const { response, error } = await this.writeJson(`${this.baseUrl}${path}`, {\n ...request,\n network: wireNetwork(request.network),\n });\n if (error) {\n return { ...onError, error: error.error, ...failureFields(error) };\n }\n return await response.json();\n } catch (error) {\n return {\n ...onError,\n error: error instanceof Error ? error.message : 'Unknown error',\n retryable: true,\n safeToReplay: false,\n retryAfterSeconds: DEFAULT_RETRY_AFTER_SECONDS,\n };\n }\n }\n\n /**\n * Append a response to existing feedback\n *\n * @deprecated On this route the facilitator is the AUTHOR: the registry\n * records `msg.sender` as the `responder`, and that is the facilitator's\n * wallet. Where the delegate is **v4**, use {@link prepareRelayedResponse} +\n * {@link submitRelayedResponse} instead. This route still works and is the\n * only one available where the delegate is still v3.\n *\n * **This is NOT agent-only**, despite what this comment claimed until\n * 2026-08-25. Verified on-chain on 2026-08-18: the registry accepts\n * `appendResponse` from ANY address. There is no identity-owner check, here or\n * in the contract.\n *\n * @param network - Network where feedback was submitted\n * @param agentId - Agent ID\n * @param feedbackIndex - Index of feedback to respond to\n * @param response - Response content\n * @param responseUri - Optional URI to off-chain response file\n * @returns Response result\n *\n * @example\n * ```ts\n * // Agent responds to feedback\n * const result = await erc8004.appendResponse(\n * 'ethereum',\n * 42,\n * 1,\n * 'Thank you for your feedback! We have addressed the issue.',\n * );\n * ```\n */\n async appendResponse(\n network: Erc8004Network,\n agentId: AgentId,\n feedbackIndex: number,\n response: string,\n options?: { responseUri?: string; sealHash?: string }\n ): Promise<FeedbackResponse> {\n const url = `${this.baseUrl}/feedback/response`;\n\n const payload: Record<string, unknown> = {\n x402Version: 1,\n network: wireNetwork(network),\n agentId,\n feedbackIndex,\n response,\n };\n if (options?.responseUri) {\n payload.responseUri = options.responseUri;\n }\n if (options?.sealHash) {\n payload.sealHash = options.sealHash;\n }\n\n try {\n const { response: fetchResponse, error } = await this.writeJson(url, payload);\n\n if (error) {\n return {\n success: false,\n error: error.error,\n network,\n ...failureFields(error),\n };\n }\n\n return await fetchResponse.json();\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error',\n network,\n retryable: true,\n safeToReplay: false,\n retryAfterSeconds: DEFAULT_RETRY_AFTER_SECONDS,\n };\n }\n }\n\n /**\n * Register an agent on the Identity Registry (idempotent)\n *\n * If the recipient already owns an agent on the target network, returns the\n * existing one instead of minting a duplicate. The facilitator pays gas fees.\n * Optionally transfer the NFT to a recipient address (gasless delegation).\n *\n * @param request - Registration request\n * @returns Registration response with agent ID and transaction hash\n *\n * @example\n * ```ts\n * // Register agent owned by facilitator\n * const result = await client.registerAgent({\n * x402Version: 1,\n * network: 'ethereum',\n * agentUri: 'ipfs://QmYourAgentFile',\n * });\n * console.log(`Agent #${result.agentId} registered`);\n *\n * // Register agent and transfer to user\n * const result = await client.registerAgent({\n * x402Version: 1,\n * network: 'ethereum',\n * agentUri: 'ipfs://QmYourAgentFile',\n * recipient: '0xUserAddress...',\n * });\n * console.log(`Agent #${result.agentId} transferred to user`);\n * ```\n */\n async registerAgent(\n request: RegisterAgentRequest,\n options?: { asyncTransport?: boolean; pollIntervalMs?: number; timeoutMs?: number },\n ): Promise<RegisterAgentResponse> {\n // asyncTransport changes how the wait is carried out, not what comes back.\n // The synchronous call holds one HTTP request open for the whole mint, which\n // on a congested chain outlives proxy timeouts; each poll here is short, so\n // nothing in the path can time out ambiguously.\n if (options?.asyncTransport) {\n const job = await this.registerAgentAsync(request);\n const terminal = await this.waitForRegistration(job.jobId, {\n pollIntervalMs: options.pollIntervalMs,\n timeoutMs: options.timeoutMs,\n });\n return jobToRegisterResponse(terminal, request.network);\n }\n\n const url = `${this.baseUrl}/register`;\n\n try {\n const { response, error } = await this.writeJson(url, {\n ...request,\n network: wireNetwork(request.network),\n });\n\n if (error) {\n // The facilitator answers 4xx with a structured RegisterAgentResponse,\n // and on 409 - a registration for this agent is ALREADY IN FLIGHT -\n // that body carries the agent id and tx of the run already underway,\n // plus an explicit \"poll GET /register/status/{jobId}\" hint.\n //\n // Flattening it into a bare string threw away the only thing that lets\n // a caller resolve instead of re-POSTing, and re-POSTing a mint is\n // exactly how duplicate agents get created. Keep the body.\n try {\n const parsed = JSON.parse(error.body) as RegisterAgentResponse;\n if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {\n return {\n ...parsed,\n // Never let a non-2xx body claim success, whatever it says.\n success: false,\n error: parsed.error ?? `Facilitator error: ${error.status}`,\n network: parsed.network ?? request.network,\n ...failureFields(error),\n };\n }\n } catch {\n // Not JSON - fall through to the flattened error.\n }\n return {\n success: false,\n error: error.error,\n network: request.network,\n ...failureFields(error),\n };\n }\n\n return await response.json();\n } catch (error) {\n // A MINT that timed out is the single most dangerous ambiguity in this\n // SDK: the transaction may be mining right now. `safeToReplay: false`\n // says so out loud. Resolve with\n // `GET /identity/{network}/owner/{recipient}` -- honouring its 404-vs-503\n // distinction -- or with `getRegisterStatus`, never by re-POSTing.\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error',\n network: request.network,\n retryable: true,\n safeToReplay: false,\n retryAfterSeconds: DEFAULT_RETRY_AFTER_SECONDS,\n };\n }\n }\n\n /**\n * Start a registration without waiting for the chain to confirm it.\n *\n * Registration waits on a mint receipt, which on a congested chain outlives\n * client and proxy timeouts. A timed-out synchronous call is genuinely\n * ambiguous — the mint may well have landed — and retrying it is how five\n * duplicate agents once got minted. This returns immediately with a job id\n * instead; poll {@link getRegisterStatus} or use {@link waitForRegistration}.\n *\n * On Solana, `recipient` is a base58 address: the facilitator mints,\n * initializes the ATOM stats and transfers, paying every fee.\n */\n async registerAgentAsync(request: RegisterAgentRequest): Promise<RegisterJobResponse> {\n const url = `${this.baseUrl}/register`;\n\n // A 503 here is the SAFE half of the register story: the job was never\n // created, so a replay creates one job, not two. `writeJson` replays only\n // what the facilitator proved it did not execute, and never\n // `forward_failed`.\n const { response, error } = await this.writeJson(\n url,\n { ...request, network: wireNetwork(request.network) },\n { Prefer: 'respond-async' },\n );\n\n if (error) {\n throw new Erc8004LookupError(\n `ERC-8004 API error: ${error.status} - ${error.body}`,\n error.status,\n error.body,\n error.retryAfterSeconds,\n );\n }\n\n return await response.json();\n }\n\n /**\n * Read the current state of an asynchronous registration.\n *\n * Throws {@link Erc8004LookupError} with `notFound` when the job is unknown or\n * has aged out — terminal jobs are kept for one hour.\n */\n async getRegisterStatus(jobId: string): Promise<RegisterJobResponse> {\n const url = `${this.baseUrl}/register/status/${encodeURIComponent(jobId)}`;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n const response = await fetch(url, {\n method: 'GET',\n headers: { Accept: 'application/json' },\n signal: controller.signal,\n }).finally(() => clearTimeout(timeoutId));\n\n if (!response.ok) {\n const info = await readFacilitatorError(response);\n throw new Erc8004LookupError(\n `ERC-8004 API error: ${info.status} - ${info.body}`,\n info.status,\n info.body,\n info.retryAfterSeconds,\n );\n }\n\n return await response.json();\n }\n\n /**\n * Poll an asynchronous registration until it finishes.\n *\n * Rejects on timeout rather than resolving with the last non-terminal status,\n * so \"still pending\" is never mistaken for \"did not happen\": the mint may\n * still land afterwards, and treating a timeout as failure is what leads to\n * registering the same agent twice. Keep the job id and poll again rather\n * than re-registering.\n */\n async waitForRegistration(\n jobId: string,\n options?: { pollIntervalMs?: number; timeoutMs?: number },\n ): Promise<RegisterJobResponse> {\n const pollIntervalMs = options?.pollIntervalMs ?? 2000;\n const timeoutMs = options?.timeoutMs ?? 300_000;\n const deadline = Date.now() + timeoutMs;\n\n for (;;) {\n const job = await this.getRegisterStatus(jobId);\n if (isRegisterJobTerminal(job)) {\n return job;\n }\n if (Date.now() >= deadline) {\n throw new RegistrationPendingError(jobId, job.status, timeoutMs);\n }\n await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));\n }\n }\n\n /**\n * Get registration endpoint metadata\n *\n * @returns Endpoint information for POST /register\n */\n async getRegisterInfo(): Promise<Record<string, unknown>> {\n const url = `${this.baseUrl}/register`;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(url, {\n method: 'GET',\n headers: { 'Accept': 'application/json' },\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`ERC-8004 API error: ${response.status} - ${errorText}`);\n }\n\n return await response.json();\n } catch (error) {\n clearTimeout(timeoutId);\n throw error;\n }\n }\n\n /**\n * Get a specific metadata entry for an agent\n *\n * @param network - Network where agent is registered\n * @param agentId - Agent's tokenId\n * @param key - Metadata key to retrieve\n * @returns Metadata value (hex-encoded and UTF-8 decoded if possible)\n */\n async getIdentityMetadata(\n network: Erc8004Network,\n agentId: AgentId,\n key: string,\n ): Promise<IdentityMetadataResponse> {\n const url = `${this.baseUrl}/identity/${wireNetwork(network)}/${agentId}/metadata/${encodeURIComponent(key)}`;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(url, {\n method: 'GET',\n headers: { 'Accept': 'application/json' },\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`ERC-8004 API error: ${response.status} - ${errorText}`);\n }\n\n return await response.json();\n } catch (error) {\n clearTimeout(timeoutId);\n throw error;\n }\n }\n\n /**\n * Get total number of registered agents on a network\n *\n * @param network - Network to query\n * @returns Total supply count\n */\n async getIdentityTotalSupply(network: Erc8004Network): Promise<IdentityTotalSupplyResponse> {\n const url = `${this.baseUrl}/identity/${wireNetwork(network)}/total-supply`;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(url, {\n method: 'GET',\n headers: { 'Accept': 'application/json' },\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`ERC-8004 API error: ${response.status} - ${errorText}`);\n }\n\n return await response.json();\n } catch (error) {\n clearTimeout(timeoutId);\n throw error;\n }\n }\n}\n\n/**\n * Build payment requirements with ERC-8004 extension\n *\n * Adds the 8004-reputation extension to include proof of payment\n * in settlement responses for reputation submission.\n *\n * @param options - Base payment requirements options\n * @returns Payment requirements with ERC-8004 extension\n *\n * @example\n * ```ts\n * const requirements = buildErc8004PaymentRequirements({\n * amount: '1.00',\n * recipient: '0x...',\n * resource: 'https://api.example.com/service',\n * chainName: 'ethereum',\n * });\n *\n * // Settlement will include proofOfPayment\n * const result = await facilitator.settle(payment, requirements);\n * console.log(result.proofOfPayment);\n * ```\n */\nexport function buildErc8004PaymentRequirements(\n options: PaymentRequirementsOptions\n): PaymentRequirements & { extra: { '8004-reputation': { includeProof: boolean } } } {\n const base = buildPaymentRequirements(options);\n return {\n ...base,\n extra: {\n [ERC8004_EXTENSION_ID]: {\n includeProof: true,\n },\n },\n };\n}\n\n// ============================================================================\n// ADVANCED ESCROW (PaymentOperator - On-Chain Escrow)\n// ============================================================================\n//\n// The 5 Advanced Escrow flows via the PaymentOperator contract:\n// 1. AUTHORIZE - Lock funds in escrow (via facilitator)\n// 2. RELEASE - Capture escrowed funds to receiver (on-chain)\n// 3. REFUND IN ESCROW - Return escrowed funds to payer (on-chain)\n// 4. CHARGE - Direct instant payment without escrow (on-chain)\n// 5. REFUND POST ESCROW - Dispute refund after release (on-chain)\n//\n// Contract mapping:\n// operator.authorize() -> escrow.authorize() (lock funds)\n// operator.release() -> escrow.capture() (pay receiver)\n// operator.refundInEscrow() -> escrow.partialVoid() (refund payer)\n// operator.charge() -> escrow.charge() (direct payment)\n// operator.refundPostEscrow() -> escrow.refund() (dispute refund)\n//\n// On a 'v3' operator (Arc, Arc Testnet) the client maps RELEASE to\n// operator.capture() and REFUND IN ESCROW to operator.void(), which returns\n// the WHOLE capturable amount. See OPERATOR_ABI_V3.\n// ============================================================================\n\n/**\n * PAYMENT_INFO_TYPEHASH used for nonce computation.\n * Must match the on-chain AuthCaptureEscrow contract.\n */\nexport const PAYMENT_INFO_TYPEHASH =\n '0xae68ac7ce30c86ece8196b61a7c486d8f0061f575037fbd34e7fe4e2820c6591';\n\nexport const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';\n\n/**\n * Contract deposit limit (enforced by PaymentOperator condition).\n * As of 2026-02-03, commerce-payments contracts enforce $100 max per deposit.\n */\nexport const DEPOSIT_LIMIT_USDC = '100000000'; // $100 in atomic units (6 decimals)\n\n/**\n * Default facilitator request timeout per chain in milliseconds.\n * Ethereum L1 (~12s blocks) needs much longer than L2s (~2s blocks).\n * Timeout chain: Client > SDK > Facilitator. The facilitator uses 900s for Ethereum L1.\n *\n * These are correct, and they are also a PRODUCT constraint worth reading before\n * you offer a network in a checkout: Ethereum L1 is 960s against 90s for every\n * L2 here. A buyer waiting in a browser will not wait sixteen minutes, so a\n * human-facing flow should offer the L2s and leave L1 to agent-to-agent or\n * batch callers that can tolerate the wait. Do not shorten this to make a\n * checkout feel faster — the value tracks L1 block time and the facilitator's\n * own 900s TxWatcher, and cutting it just times out a payment that was going\n * to land.\n */\nexport const ESCROW_TIMEOUT_MS: Record<number, number> = {\n 1: 960_000, // Ethereum L1: 960s (facilitator uses 900s TxWatcher)\n 11155111: 960_000, // Ethereum Sepolia: same as L1\n 137: 90_000, // Polygon: 90s\n 8453: 90_000, // Base: 90s\n 84532: 90_000, // Base Sepolia: 90s\n 42161: 90_000, // Arbitrum: 90s\n 10: 90_000, // Optimism: 90s\n 43114: 90_000, // Avalanche: 90s\n 42220: 90_000, // Celo: 90s\n 143: 90_000, // Monad: 90s\n};\n\n/** Default timeout when chain is not in ESCROW_TIMEOUT_MS */\nconst DEFAULT_ESCROW_TIMEOUT_MS = 30_000;\n\n/**\n * An Arc network's USDC as the chain registry (`src/chains`) has it. The\n * escrow tables below read the address and the EIP-712 domain name from here\n * instead of typing them a second time.\n */\nfunction arcUsdc(network: 'arc' | 'arc-testnet'): { address: string; name: string } {\n const chain = getChainByName(network);\n if (!chain) throw new Error(`The chain registry has no '${network}'.`);\n return chain.usdc;\n}\n\n/**\n * USDC EIP-712 domain name per chain.\n * Most chains use \"USD Coin\", but some (Celo, Monad, HyperEVM) use \"USDC\".\n * This must match the on-chain token's name() for EIP-712 signing to work.\n */\nexport const USDC_DOMAIN_NAME: Record<number, string> = {\n 8453: 'USD Coin', // Base Mainnet\n 84532: 'USD Coin', // Base Sepolia\n 1: 'USD Coin', // Ethereum Mainnet\n 11155111: 'USD Coin', // Ethereum Sepolia\n 137: 'USD Coin', // Polygon\n 42161: 'USD Coin', // Arbitrum\n 43114: 'USD Coin', // Avalanche\n 42220: 'USDC', // Celo\n 143: 'USDC', // Monad\n 5042: arcUsdc('arc').name, // Arc ('USDC', from src/chains)\n 5042002: arcUsdc('arc-testnet').name, // Arc Testnet ('USDC', from src/chains)\n};\n\n/**\n * Multi-chain escrow contract addresses for the Advanced Escrow system.\n * Keyed by EVM chain ID. Source: x402r-sdk A1igator/multichain-config deployment.\n */\n/**\n * Per-chain escrow contract addresses.\n *\n * KNOWN GAP, measured 2026-09-05: the `operator` entries are\n * PaymentOperatorFactory addresses, not deployed PaymentOperator instances.\n * Verified on Base mainnet, Base Sepolia and Arbitrum — they answer\n * `ESCROW()` and `operators(bytes32)` and revert on `FEE_CALCULATOR()`,\n * `FEE_RECIPIENT()` and `release(...)` — and x402-rs\n * `docs/X402R_MULTICHAIN_DEPLOYMENT.md` labels the same addresses\n * \"PaymentOperatorFactory\". A factory has no `release`/`charge`, so the direct\n * on-chain paths below cannot execute against these addresses as written;\n * resolve the real operator from the marketplace's own escrow config\n * ({@link EscrowNetworkConfig}) and pass it via `options.contracts`.\n * See {@link OPERATOR_FEE_BPS} for the commands.\n *\n * Arc (5042) and Arc Testnet (5042002) use the x402r canonical escrow\n * (AuthCaptureEscrow `0xBdEA0D1b…`, PaymentOperatorFactory v1.0.2\n * `0xc24153B7…`). Their `operator` is a PaymentOperator address: the one the\n * factory's `computeAddress` returns, recorded on both chains in\n * `src/fixtures/arc-escrow-d.rpc.json`. Their operator generation is `'v3'`\n * ({@link OPERATOR_ABI_V3}).\n */\nexport const ESCROW_CONTRACTS: Record<number, AdvancedEscrowContracts> = {\n // Base Sepolia (testnet, chain 84532)\n 84532: {\n operator: '0x97d53e63A9CB97556c00BeFd325AF810c9b267B2',\n escrow: '0x29025c0E9D4239d438e169570818dB9FE0A80873',\n tokenCollector: '0x5cA789000070DF15b4663DB64a50AeF5D49c5Ee0',\n protocolFeeConfig: '0x8F96C493bAC365E41f0315cf45830069EBbDCaCe',\n refundRequest: '0x1C2Ab244aC8bDdDB74d43389FF34B118aF2E90F4',\n usdc: '0x036CbD53842c5426634e7929541eC2318f3dCF7e',\n },\n // Base Mainnet (chain 8453)\n 8453: {\n operator: '0x3D0837fF8Ea36F417261577b9BA568400A840260',\n escrow: '0xb9488351E48b23D798f24e8174514F28B741Eb4f',\n tokenCollector: '0x48ADf6E37F9b31dC2AAD0462C5862B5422C736B8',\n protocolFeeConfig: '0x59314674BAbb1a24Eb2704468a9cCdD50668a1C6',\n refundRequest: '0x35fb2EFEfAc3Ee9f6E52A9AAE5C9655bC08dEc00',\n usdc: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\n },\n // Ethereum Sepolia (testnet, chain 11155111)\n 11155111: {\n operator: '0x32d6AC59BCe8DFB3026F10BcaDB8D00AB218f5b6',\n escrow: '0x320a3c35F131E5D2Fb36af56345726B298936037',\n tokenCollector: '0x230fd3A171750FA45db2976121376b7F47Cba308',\n protocolFeeConfig: '0xD979dBfBdA5f4b16AAF60Eaab32A44f352076838',\n refundRequest: '0xc1256Bb30bd0cdDa07D8C8Cf67a59105f2EA1b98',\n usdc: '0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238',\n },\n // Ethereum Mainnet (chain 1) - Updated from Ali's redeploy (commit e6cf29d)\n 1: {\n operator: '0x69B67962ffb7c5C7078ff348a87DF604dfA8001b',\n escrow: '0x9D4146EF898c8E60B3e865AE254ef438E7cEd2A0',\n tokenCollector: '0x206D4DbB6E7b876e4B5EFAAD2a04e7d7813FB6ba',\n protocolFeeConfig: '0x5b3e33791C1764cF7e2573Bf8116F1D361FD97Cd',\n refundRequest: '0xFa8C4Cb156053b867Ae7489220A29b5939E3Df70',\n usdc: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',\n },\n // Polygon (chain 137)\n 137: {\n operator: '0xb33D6502EdBbC47201cd1E53C49d703EC0a660b8',\n escrow: '0x32d6AC59BCe8DFB3026F10BcaDB8D00AB218f5b6',\n tokenCollector: '0xc1256Bb30bd0cdDa07D8C8Cf67a59105f2EA1b98',\n protocolFeeConfig: '0xE78648e7af7B1BaDE717FF6E410B922F92adE80f',\n refundRequest: '0xed02d3E5167BCc9582D851885A89b050AB816a56',\n usdc: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',\n },\n // Arbitrum (chain 42161)\n 42161: {\n operator: '0x32d6AC59BCe8DFB3026F10BcaDB8D00AB218f5b6',\n escrow: '0x320a3c35F131E5D2Fb36af56345726B298936037',\n tokenCollector: '0x230fd3A171750FA45db2976121376b7F47Cba308',\n protocolFeeConfig: '0xD979dBfBdA5f4b16AAF60Eaab32A44f352076838',\n refundRequest: '0xc1256Bb30bd0cdDa07D8C8Cf67a59105f2EA1b98',\n usdc: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',\n },\n // Celo (chain 42220)\n 42220: {\n operator: '0x32d6AC59BCe8DFB3026F10BcaDB8D00AB218f5b6',\n escrow: '0x320a3c35F131E5D2Fb36af56345726B298936037',\n tokenCollector: '0x230fd3A171750FA45db2976121376b7F47Cba308',\n protocolFeeConfig: '0xD979dBfBdA5f4b16AAF60Eaab32A44f352076838',\n refundRequest: '0xc1256Bb30bd0cdDa07D8C8Cf67a59105f2EA1b98',\n usdc: '0xcebA9300f2b948710d2653dD7B07f33A8B32118C',\n },\n // Monad (chain 143)\n 143: {\n operator: '0x32d6AC59BCe8DFB3026F10BcaDB8D00AB218f5b6',\n escrow: '0x320a3c35F131E5D2Fb36af56345726B298936037',\n tokenCollector: '0x230fd3A171750FA45db2976121376b7F47Cba308',\n protocolFeeConfig: '0xD979dBfBdA5f4b16AAF60Eaab32A44f352076838',\n refundRequest: '0xc1256Bb30bd0cdDa07D8C8Cf67a59105f2EA1b98',\n usdc: '0x754704Bc059F8C67012fEd69BC8a327a5aafb603',\n },\n // Avalanche (chain 43114)\n 43114: {\n operator: '0x32d6AC59BCe8DFB3026F10BcaDB8D00AB218f5b6',\n escrow: '0x320a3c35F131E5D2Fb36af56345726B298936037',\n tokenCollector: '0x230fd3A171750FA45db2976121376b7F47Cba308',\n protocolFeeConfig: '0xD979dBfBdA5f4b16AAF60Eaab32A44f352076838',\n refundRequest: '0xc1256Bb30bd0cdDa07D8C8Cf67a59105f2EA1b98',\n usdc: '0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E',\n },\n // Optimism (chain 10)\n 10: {\n operator: '0x32d6AC59BCe8DFB3026F10BcaDB8D00AB218f5b6',\n escrow: '0x320a3c35F131E5D2Fb36af56345726B298936037',\n tokenCollector: '0x230fd3A171750FA45db2976121376b7F47Cba308',\n protocolFeeConfig: '0xD979dBfBdA5f4b16AAF60Eaab32A44f352076838',\n refundRequest: '0xc1256Bb30bd0cdDa07D8C8Cf67a59105f2EA1b98',\n usdc: '0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85',\n },\n // SKALE Base (chain 1187947933) - CREATE3 deployment, operator via factory\n 1187947933: {\n operator: '0x28c23AE8f55aDe5Ea10a5353FC40418D0c1B3d33',\n escrow: '0xBC151792f80C0EB1973d56b0235e6bee2A60e245',\n tokenCollector: '0x9A12A116a44636F55c9e135189A1321Abcfe2f30',\n protocolFeeConfig: '0xf62788834C99B2E85a6891C0b46D1EB996f8f596',\n refundRequest: '0x69e9BF2b40Ed472b55E47e9D4205d93Ed673093F',\n usdc: '0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20',\n },\n // Arc (chain 5042) - x402r canonical escrow, 'v3' operator\n 5042: {\n operator: '0x0258472A1410Ac3Ad720f1BC83f22B3c0af1Fd9D',\n escrow: '0xBdEA0D1bcC5966192B070Fdf62aB4EF5b4420cff',\n tokenCollector: '0x0E3dF9510de65469C4518D7843919c0b8C7A7757',\n protocolFeeConfig: '0xBe2d24614F339a1eB103A399F93AA2a39Ca815Bc',\n refundRequest: '0xe971C674fD5c3462023f3F891dF6289DFbC9CEFC',\n usdc: arcUsdc('arc').address,\n },\n // Arc Testnet (chain 5042002) - same canonical addresses as Arc\n 5042002: {\n operator: '0x0258472A1410Ac3Ad720f1BC83f22B3c0af1Fd9D',\n escrow: '0xBdEA0D1bcC5966192B070Fdf62aB4EF5b4420cff',\n tokenCollector: '0x0E3dF9510de65469C4518D7843919c0b8C7A7757',\n protocolFeeConfig: '0xBe2d24614F339a1eB103A399F93AA2a39Ca815Bc',\n refundRequest: '0xe971C674fD5c3462023f3F891dF6289DFbC9CEFC',\n usdc: arcUsdc('arc-testnet').address,\n },\n};\n\n/**\n * Base Mainnet contract addresses for the Advanced Escrow system.\n * @deprecated Use ESCROW_CONTRACTS[8453] or getEscrowContractsByChainId(8453) instead.\n */\nexport const BASE_MAINNET_CONTRACTS: AdvancedEscrowContracts = ESCROW_CONTRACTS[8453];\n\n/**\n * Get escrow contract addresses for a given chain ID.\n *\n * @param chainId - EVM chain ID (e.g., 8453 for Base, 1 for Ethereum)\n * @returns Contract addresses or undefined if chain is not supported\n */\nexport function getEscrowContractsByChainId(chainId: number): AdvancedEscrowContracts | undefined {\n return ESCROW_CONTRACTS[chainId];\n}\n\n/**\n * Get all chain IDs that have escrow contracts deployed.\n *\n * @returns Array of chain IDs with escrow support\n */\nexport function getEscrowSupportedChainIds(): number[] {\n return Object.keys(ESCROW_CONTRACTS).map(Number);\n}\n\n/**\n * Check if escrow contracts are deployed on a given chain.\n *\n * @param chainId - EVM chain ID\n * @returns True if escrow is supported on this chain\n */\nexport function isEscrowSupportedOnChain(chainId: number): boolean {\n return chainId in ESCROW_CONTRACTS;\n}\n\n/**\n * Task tiers determine timing parameters for escrow operations.\n */\nexport type AdvancedEscrowTaskTier = 'micro' | 'standard' | 'premium' | 'enterprise';\n\n/**\n * Timing configuration per task tier (in seconds).\n */\nexport const TIER_TIMINGS: Record<AdvancedEscrowTaskTier, { pre: number; auth: number; refund: number }> = {\n micro: { pre: 3600, auth: 7200, refund: 86400 },\n standard: { pre: 7200, auth: 86400, refund: 604800 },\n premium: { pre: 14400, auth: 172800, refund: 1209600 },\n enterprise: { pre: 86400, auth: 604800, refund: 2592000 },\n};\n\n/**\n * PaymentInfo struct matching the on-chain PaymentOperator contract.\n */\nexport interface AdvancedPaymentInfo {\n operator: string;\n receiver: string;\n token: string;\n maxAmount: string;\n preApprovalExpiry: number;\n authorizationExpiry: number;\n refundExpiry: number;\n minFeeBps: number;\n maxFeeBps: number;\n feeReceiver: string;\n salt: string;\n}\n\n/**\n * Optional signed lifecycle order for `releaseViaFacilitator` /\n * `refundViaFacilitator`.\n *\n * Both actions move money that is ALREADY escrowed, so neither carries an\n * ERC-3009 signature and the entitlement question — who may ask for the move —\n * has no other answer. Supplying a `lifecycleSigner` answers it; omitting one\n * leaves the request byte-for-byte as it was, which is why every field here is\n * optional and the default is to send nothing.\n *\n * The accepted signers are the facilitator's, not this SDK's: `release` takes\n * the payer or the operator owner (`FEE_RECIPIENT()`); `refundInEscrow` takes\n * the receiver, the operator owner, or the payer once `authorizationExpiry`\n * has passed. Anything else is logged as `unauthorized_role`.\n */\nexport interface LifecycleAuthOptions {\n /**\n * Who signs the order. Any adapter with `getAddress()` + `signTypedData()`:\n * `EnvKeyAdapter` server-side, `OWSWalletAdapter`, or\n * `wagmiLifecycleSigner(walletClient)` when the PAYER signs in their own\n * browser and this backend only transports the block.\n */\n lifecycleSigner?: LifecycleSigner;\n /**\n * Unix seconds. Default: `now + 600`, which leaves 300 s of headroom under\n * the facilitator's 900 s ceiling. Only read alongside `lifecycleSigner` —\n * a `lifecycleAuth` already carries the deadline it was signed with.\n */\n lifecycleDeadline?: number;\n /**\n * An order that was ALREADY SIGNED somewhere else — the publisher's browser\n * — and that this backend only transports.\n *\n * The signing side builds the document with `buildLifecycleTypedData`, the\n * browser signs it, and `lifecycleAuthFromSignature` turns the signature\n * back into this block. Nothing is re-derived here: the `paymentInfo`, the\n * `payer` and the `amount` this call sends must be the ones the order\n * committed to, or the facilitator reads `bad_signature`.\n *\n * MUTUALLY EXCLUSIVE with `lifecycleSigner`. Passing both is not a\n * preference to resolve — it means the caller believes two different orders\n * are about to travel, and only one can. It throws.\n */\n lifecycleAuth?: LifecycleAuth;\n}\n\n/**\n * The order that rides on a lifecycle request, from whichever of the two\n * shapes the caller chose.\n *\n * Kept out of both methods so the exclusivity rule is written ONCE: duplicated,\n * the day one branch grows a condition the other silently keeps the old one.\n */\nasync function resolveLifecycleAuth(\n action: LifecycleAction,\n options: LifecycleAuthOptions | undefined,\n order: {\n paymentInfo: LifecyclePaymentInfo;\n payer: string;\n amount: string;\n chainId: number;\n }\n): Promise<LifecycleAuth | undefined> {\n if (options?.lifecycleSigner && options?.lifecycleAuth) {\n throw new X402Error(\n 'lifecycleSigner and lifecycleAuth are mutually exclusive: the first signs an order ' +\n 'here, the second was already signed elsewhere. Passing both means two different ' +\n 'orders exist and only one can travel.',\n 'INVALID_CONFIG'\n );\n }\n // Transported as-is. Re-signing or \"normalizing\" it would change the bytes\n // the browser committed to.\n if (options?.lifecycleAuth) return options.lifecycleAuth;\n if (!options?.lifecycleSigner) return undefined;\n return buildLifecycleAuth({\n action,\n paymentInfo: order.paymentInfo,\n payer: order.payer,\n amount: order.amount,\n chainId: order.chainId,\n wallet: options.lifecycleSigner,\n deadline: options.lifecycleDeadline,\n });\n}\n\n/**\n * Result of an AUTHORIZE operation.\n */\nexport interface AdvancedAuthorizationResult {\n success: boolean;\n transactionHash?: string;\n paymentInfo?: AdvancedPaymentInfo;\n salt?: string;\n error?: string;\n}\n\n/**\n * Result of an on-chain transaction (release, refund, charge).\n */\nexport interface AdvancedTransactionResult extends FacilitatorFailureFields {\n success: boolean;\n transactionHash?: string;\n gasUsed?: number;\n /**\n * Why it failed.\n *\n * On the gasless (`*ViaFacilitator`) paths, check `retryable` first: a\n * facilitator that could not hand the write to its lease holder rejected\n * nothing on-chain, and the escrow is exactly as it was. Reporting that as a\n * failed refund is how funds get written off while they are still sitting in\n * escrow, recoverable.\n */\n error?: string;\n}\n\n/**\n * Response from the facilitator's /escrow/state endpoint.\n * Represents the on-chain state of an escrow for a given paymentInfo + payer.\n */\nexport interface EscrowStateResponse {\n /** Whether the payment has already been collected (released) */\n hasCollectedPayment: boolean;\n /** Amount that can still be captured/released (in atomic units) */\n capturableAmount: string;\n /** Amount that can still be refunded to the payer (in atomic units) */\n refundableAmount: string;\n /** Keccak256 hash of the paymentInfo struct */\n paymentInfoHash: string;\n /** Network in CAIP-2 format (e.g., \"eip155:8453\") */\n network: string;\n}\n\n/**\n * Contract addresses configuration for AdvancedEscrowClient.\n *\n * Maps to the on-chain x402r escrow contracts:\n * - operator: PaymentOperatorFactory\n * - escrow: AuthCaptureEscrow\n * - tokenCollector: TokenCollector\n * - protocolFeeConfig: ProtocolFeeConfig\n * - refundRequest: RefundRequest\n * - usdc: USDC token contract\n */\nexport interface AdvancedEscrowContracts {\n /** PaymentOperatorFactory contract address */\n operator: string;\n /** AuthCaptureEscrow contract address */\n escrow: string;\n /** TokenCollector contract address */\n tokenCollector: string;\n /** ProtocolFeeConfig contract address */\n protocolFeeConfig: string;\n /** RefundRequest contract address */\n refundRequest: string;\n /** USDC token contract address */\n usdc: string;\n}\n\n/**\n * Configuration options for AdvancedEscrowClient.\n */\nexport interface AdvancedEscrowClientOptions {\n /** Facilitator URL for AUTHORIZE operations */\n facilitatorUrl?: string;\n /** JSON-RPC URL for on-chain operations (required when using SigningWalletAdapter) */\n rpcUrl?: string;\n /**\n * Chain ID (default: 8453 for Base Mainnet).\n * Supported chains: 8453 (Base), 84532 (Base Sepolia), 1 (Ethereum),\n * 11155111 (Ethereum Sepolia), 137 (Polygon), 42161 (Arbitrum),\n * 10 (Optimism), 42220 (Celo), 143 (Monad), 43114 (Avalanche),\n * 1187947933 (SKALE Base), 5042 (Arc), 5042002 (Arc Testnet).\n */\n chainId?: number;\n /** Contract addresses (auto-resolved from chainId if not provided) */\n contracts?: AdvancedEscrowContracts;\n /** Gas limit for transactions (default: 300000) */\n gasLimit?: number;\n /**\n * Request timeout in milliseconds for facilitator HTTP calls (authorize, gasless release/refund).\n * Default is per-network: 960s for Ethereum L1, 90s for L2s.\n * Ethereum L1 confirmations can take several minutes under congestion.\n */\n timeout?: number;\n /**\n * SigningWalletAdapter for OWS wallet signing (v2.36.0+).\n *\n * When provided, the client uses the adapter for all signing operations\n * instead of requiring a raw ethers.Signer. The first constructor argument\n * is ignored when `wallet` is set.\n *\n * Requires `rpcUrl` to be set for on-chain transaction building.\n *\n * @example\n * ```typescript\n * import { OWSWalletAdapter, AdvancedEscrowClient } from 'uvd-x402-sdk/backend';\n *\n * const wallet = new OWSWalletAdapter(owsWallet);\n * const client = new AdvancedEscrowClient(null, {\n * wallet,\n * rpcUrl: 'https://mainnet.base.org',\n * chainId: 8453,\n * });\n * ```\n */\n wallet?: import('../wallet').SigningWalletAdapter;\n /**\n * Extra attempts on the gasless facilitator paths when the facilitator proved\n * it executed nothing. Default 2; `0` disables.\n */\n retries?: number;\n}\n\n/**\n * Minimal PaymentOperator ABI for the 4 on-chain functions.\n * (AUTHORIZE goes through the facilitator, not directly on-chain)\n */\nexport const OPERATOR_ABI = [\n 'function release(tuple(address operator, address payer, address receiver, address token, uint120 maxAmount, uint48 preApprovalExpiry, uint48 authorizationExpiry, uint48 refundExpiry, uint16 minFeeBps, uint16 maxFeeBps, address feeReceiver, uint256 salt) paymentInfo, uint256 amount)',\n 'function refundInEscrow(tuple(address operator, address payer, address receiver, address token, uint120 maxAmount, uint48 preApprovalExpiry, uint48 authorizationExpiry, uint48 refundExpiry, uint16 minFeeBps, uint16 maxFeeBps, address feeReceiver, uint256 salt) paymentInfo, uint120 amount)',\n 'function charge(tuple(address operator, address payer, address receiver, address token, uint120 maxAmount, uint48 preApprovalExpiry, uint48 authorizationExpiry, uint48 refundExpiry, uint16 minFeeBps, uint16 maxFeeBps, address feeReceiver, uint256 salt) paymentInfo, uint256 amount, address tokenCollector, bytes collectorData)',\n 'function refundPostEscrow(tuple(address operator, address payer, address receiver, address token, uint120 maxAmount, uint48 preApprovalExpiry, uint48 authorizationExpiry, uint48 refundExpiry, uint16 minFeeBps, uint16 maxFeeBps, address feeReceiver, uint256 salt) paymentInfo, uint256 amount, address tokenCollector, bytes collectorData)',\n];\n\n/**\n * CREATE3-deployed operators (SKALE, future chains) use updated ABI with extra `bytes data` param\n * on release() and refundInEscrow(). Pass empty bytes (0x) for the data parameter.\n */\nexport const OPERATOR_ABI_CREATE3 = [\n 'function release(tuple(address operator, address payer, address receiver, address token, uint120 maxAmount, uint48 preApprovalExpiry, uint48 authorizationExpiry, uint48 refundExpiry, uint16 minFeeBps, uint16 maxFeeBps, address feeReceiver, uint256 salt) paymentInfo, uint256 amount, bytes data)',\n 'function refundInEscrow(tuple(address operator, address payer, address receiver, address token, uint120 maxAmount, uint48 preApprovalExpiry, uint48 authorizationExpiry, uint48 refundExpiry, uint16 minFeeBps, uint16 maxFeeBps, address feeReceiver, uint256 salt) paymentInfo, uint120 amount, bytes data)',\n 'function charge(tuple(address operator, address payer, address receiver, address token, uint120 maxAmount, uint48 preApprovalExpiry, uint48 authorizationExpiry, uint48 refundExpiry, uint16 minFeeBps, uint16 maxFeeBps, address feeReceiver, uint256 salt) paymentInfo, uint256 amount, address tokenCollector, bytes collectorData)',\n 'function refundPostEscrow(tuple(address operator, address payer, address receiver, address token, uint120 maxAmount, uint48 preApprovalExpiry, uint48 authorizationExpiry, uint48 refundExpiry, uint16 minFeeBps, uint16 maxFeeBps, address feeReceiver, uint256 salt) paymentInfo, uint256 amount, address tokenCollector, bytes collectorData)',\n];\n\n/**\n * PaymentOperator of the x402r canonical PaymentOperatorFactory v1.0.2\n * (`0xc24153B7ED8DC03e551F29DDEeA5CadFe57e2716`), the operator generation of\n * Arc and Arc Testnet. Source: BackTrackCo/x402r-contracts\n * `src/operator/payment/PaymentOperator.sol` @ 8345776e.\n *\n * It has no `release` and no `refundInEscrow`:\n * - `capture(paymentInfo, amount, data)` pays the receiver;\n * - `void(paymentInfo, data)` takes NO amount: it returns the whole\n * `capturableAmount` to the payer;\n * - `refund(...)` returns funds after a capture;\n * - the owner is `FEE_RECEIVER()`.\n *\n * Every selector here is checked against the factory bytecode recorded on\n * Arc (`src/fixtures/arc-escrow-d.rpc.json`): `capture` 0xf12b86f6, `void`\n * 0xc3c5090e, `FEE_RECEIVER` 0xd3e78e4d.\n */\nexport const OPERATOR_ABI_V3 = [\n 'function capture(tuple(address operator, address payer, address receiver, address token, uint120 maxAmount, uint48 preApprovalExpiry, uint48 authorizationExpiry, uint48 refundExpiry, uint16 minFeeBps, uint16 maxFeeBps, address feeReceiver, uint256 salt) paymentInfo, uint256 amount, bytes data)',\n 'function void(tuple(address operator, address payer, address receiver, address token, uint120 maxAmount, uint48 preApprovalExpiry, uint48 authorizationExpiry, uint48 refundExpiry, uint16 minFeeBps, uint16 maxFeeBps, address feeReceiver, uint256 salt) paymentInfo, bytes data)',\n 'function refund(tuple(address operator, address payer, address receiver, address token, uint120 maxAmount, uint48 preApprovalExpiry, uint48 authorizationExpiry, uint48 refundExpiry, uint16 minFeeBps, uint16 maxFeeBps, address feeReceiver, uint256 salt) paymentInfo, uint256 amount, address tokenCollector, bytes collectorData)',\n 'function FEE_RECEIVER() view returns (address)',\n 'function AUTHORIZE_PRE_ACTION_CONDITION() view returns (address)',\n 'function CHARGE_PRE_ACTION_CONDITION() view returns (address)',\n 'function CAPTURE_PRE_ACTION_CONDITION() view returns (address)',\n 'function VOID_PRE_ACTION_CONDITION() view returns (address)',\n 'function REFUND_PRE_ACTION_CONDITION() view returns (address)',\n];\n\n/**\n * The two AuthCaptureEscrow reads a v3 `refundInEscrow` makes before it sends\n * anything: the payment's hash, then its `capturableAmount`.\n */\nconst AUTH_CAPTURE_ESCROW_STATE_ABI = [\n 'function getHash(tuple(address operator, address payer, address receiver, address token, uint120 maxAmount, uint48 preApprovalExpiry, uint48 authorizationExpiry, uint48 refundExpiry, uint16 minFeeBps, uint16 maxFeeBps, address feeReceiver, uint256 salt) paymentInfo) view returns (bytes32)',\n 'function paymentState(bytes32 paymentInfoHash) view returns (bool hasCollectedPayment, uint120 capturableAmount, uint120 refundableAmount)',\n];\n\n/**\n * `refundInEscrow` on a v3 operator was given an amount other than the whole\n * `capturableAmount`. `void` takes no amount, so sending it would return more\n * than was asked. Nothing was sent. `errorCode` of the result.\n */\nexport const ESCROW_VOID_AMOUNT_MISMATCH = 'escrow_void_amount_mismatch';\n\n/**\n * `refundInEscrow` on a v3 operator found `capturableAmount` = 0: nothing is\n * left to return. Nothing was sent. `errorCode` of the result.\n */\nexport const ESCROW_NOTHING_TO_VOID = 'escrow_nothing_to_void';\n\n/**\n * The v3 operator has no code on the chain. A call to it would succeed and\n * move nothing, so the SDK does not send one. `errorCode` of the result.\n */\nexport const ESCROW_OPERATOR_NOT_DEPLOYED = 'escrow_operator_not_deployed';\n\n/**\n * The call has no counterpart on the chain's operator generation (`charge` on\n * a v3 operator). Nothing was signed or sent. `errorCode` of the result.\n */\nexport const ESCROW_UNSUPPORTED_ON_GENERATION = 'escrow_unsupported_on_generation';\n\n/**\n * Which PaymentOperator ABI a chain's escrow operator speaks.\n *\n * - `'v1'`: {@link OPERATOR_ABI} — `release(PaymentInfo, amount)` and\n * `refundInEscrow(PaymentInfo, amount)`.\n * - `'v2'`: {@link OPERATOR_ABI_CREATE3} — the same two with a trailing\n * `bytes data`.\n * - `'v3'`: {@link OPERATOR_ABI_V3} — `capture(PaymentInfo, amount, data)` and\n * `void(PaymentInfo, data)`.\n */\nexport type EscrowOperatorGeneration = 'v1' | 'v2' | 'v3';\n\n/**\n * Operator generation per chain — the single source the escrow client reads\n * to pick the operator ABI. A chain absent from this table is `'v1'`, which is\n * what a custom `options.contracts` on an unlisted chain has always used.\n */\nexport const ESCROW_OPERATOR_GENERATION: Record<number, EscrowOperatorGeneration> = {\n 84532: 'v1', // Base Sepolia\n 8453: 'v1', // Base\n 11155111: 'v1', // Ethereum Sepolia\n 1: 'v1', // Ethereum\n 137: 'v1', // Polygon\n 42161: 'v1', // Arbitrum\n 42220: 'v1', // Celo\n 143: 'v1', // Monad\n 43114: 'v1', // Avalanche\n 10: 'v1', // Optimism\n 1187947933: 'v2', // SKALE Base\n 5042: 'v3', // Arc\n 5042002: 'v3', // Arc Testnet\n};\n\n/** Operator generation of a chain; `'v1'` when the chain is not listed. */\nexport function getEscrowOperatorGeneration(chainId: number): EscrowOperatorGeneration {\n return ESCROW_OPERATOR_GENERATION[chainId] ?? 'v1';\n}\n\n/**\n * AdvancedEscrowClient provides the 5 Advanced Escrow flows via the\n * PaymentOperator contract on 9 supported EVM networks.\n *\n * Supported chains: Base (8453), Base Sepolia (84532), Ethereum (1),\n * Ethereum Sepolia (11155111), Polygon (137), Arbitrum (42161),\n * Optimism (10), Celo (42220), Monad (143), Avalanche (43114),\n * SKALE Base (1187947933), Arc (5042), Arc Testnet (5042002).\n *\n * The operator ABI follows the chain's {@link ESCROW_OPERATOR_GENERATION}.\n * On Arc and Arc Testnet (`'v3'`) `release` sends `capture`, `refundInEscrow`\n * sends `void` (whole capturable amount only), `refundPostEscrow` sends\n * `refund`, and `charge` refuses without signing or sending.\n *\n * Contract addresses are auto-resolved from the chain ID.\n * Pass custom contracts to override.\n *\n * Two signer modes (v2.36.0+):\n * - **Legacy**: Pass an ethers.Signer as the first argument.\n * - **OWS Wallet**: Pass a SigningWalletAdapter via `options.wallet`.\n * The adapter signs transactions offline (no raw private key needed).\n * Requires `rpcUrl` for transaction building and broadcast.\n *\n * @example Legacy mode (ethers.Signer)\n * ```typescript\n * import { ethers } from 'ethers';\n * import { AdvancedEscrowClient } from 'uvd-x402-sdk/backend';\n *\n * const provider = new ethers.JsonRpcProvider('https://mainnet.base.org');\n * const signer = new ethers.Wallet(process.env.KEY!, provider);\n * const client = new AdvancedEscrowClient(signer, { chainId: 8453 });\n * ```\n *\n * @example OWS Wallet mode (SigningWalletAdapter)\n * ```typescript\n * import { OWSWalletAdapter } from 'uvd-x402-sdk';\n * import { AdvancedEscrowClient } from 'uvd-x402-sdk/backend';\n *\n * const wallet = new OWSWalletAdapter(owsWallet);\n * const client = new AdvancedEscrowClient(null, {\n * wallet,\n * rpcUrl: 'https://mainnet.base.org',\n * chainId: 8453,\n * });\n * await client.init();\n *\n * const pi = client.buildPaymentInfo('0xWorker...', '5000000', 'standard');\n * const auth = await client.authorize(pi);\n * const release = await client.release(pi);\n * ```\n */\nexport class AdvancedEscrowClient {\n private facilitatorUrl: string;\n private chainId: number;\n private gasLimit: number;\n private readonly timeout: number;\n private readonly retries: number | undefined;\n private contracts: AdvancedEscrowContracts;\n private signer: any; // ethers.Signer (legacy mode)\n private walletAdapter: import('../wallet').SigningWalletAdapter | null; // OWS mode (v2.36.0+)\n private rpcUrl: string | undefined;\n private payerAddress: string = '';\n\n /**\n * Create an AdvancedEscrowClient.\n *\n * Two modes of operation:\n *\n * 1. **Legacy (ethers.Signer)**: Pass an ethers Signer as the first argument.\n * ```ts\n * const client = new AdvancedEscrowClient(signer, { rpcUrl, chainId });\n * ```\n *\n * 2. **OWS Wallet (SigningWalletAdapter)**: Pass `wallet` in options. The\n * first argument is ignored (pass `null`). Requires `rpcUrl` for on-chain\n * transaction building and broadcast.\n * ```ts\n * const wallet = new OWSWalletAdapter(owsWallet);\n * const client = new AdvancedEscrowClient(null, { wallet, rpcUrl, chainId });\n * ```\n *\n * @param signer - ethers.Signer instance (ignored when options.wallet is set)\n * @param options - Configuration options\n */\n constructor(signer: any, options: AdvancedEscrowClientOptions = {}) {\n this.walletAdapter = options.wallet || null;\n this.signer = this.walletAdapter ? null : signer;\n this.rpcUrl = options.rpcUrl;\n this.facilitatorUrl = (options.facilitatorUrl || 'https://facilitator.ultravioletadao.xyz').replace(/\\/$/, '');\n this.chainId = options.chainId || 8453;\n this.gasLimit = options.gasLimit || 300000;\n this.timeout = options.timeout || ESCROW_TIMEOUT_MS[this.chainId] || DEFAULT_ESCROW_TIMEOUT_MS;\n this.retries = options.retries;\n\n if (this.walletAdapter && !this.rpcUrl) {\n throw new Error(\n 'AdvancedEscrowClient: rpcUrl is required when using a SigningWalletAdapter. ' +\n 'The adapter signs transactions offline; an RPC provider is needed to build ' +\n 'and broadcast them.'\n );\n }\n\n if (options.contracts) {\n this.contracts = options.contracts;\n } else {\n const resolved = ESCROW_CONTRACTS[this.chainId];\n if (!resolved) {\n throw new Error(\n `No escrow contracts found for chain ID ${this.chainId}. ` +\n `Supported chains: ${getEscrowSupportedChainIds().join(', ')}. ` +\n `Pass custom contracts via options.contracts to use an unsupported chain.`\n );\n }\n this.contracts = resolved;\n }\n }\n\n /**\n * Initialize the client (resolves payer address).\n * Call this before using any methods.\n */\n async init(): Promise<void> {\n if (this.walletAdapter) {\n this.payerAddress = this.walletAdapter.getAddress();\n } else {\n this.payerAddress = await this.signer.getAddress();\n }\n }\n\n /**\n * Build a PaymentInfo struct with appropriate timing for the task tier.\n *\n * @param receiver - Worker's wallet address\n * @param amount - Amount in token atomic units (e.g., '5000000' for $5 USDC)\n * @param tier - Task tier determines timing parameters\n * @param salt - Random salt (auto-generated if not provided)\n */\n buildPaymentInfo(\n receiver: string,\n amount: string,\n tier: AdvancedEscrowTaskTier = 'standard',\n salt?: string,\n opts?: {\n deadline?: number;\n reviewWindowSec?: number;\n /**\n * Fee bounds to sign, in basis points. Default\n * {@link DEFAULT_MIN_FEE_BPS} / {@link DEFAULT_MAX_FEE_BPS}. Override\n * only against an operator whose fee you have actually read on-chain —\n * `maxFeeBps` is a CEILING, so a value under the operator's own fee does\n * not shave the fee, it reverts the deposit.\n */\n minFeeBps?: number;\n maxFeeBps?: number;\n },\n ): AdvancedPaymentInfo {\n const now = Math.floor(Date.now() / 1000);\n const t = TIER_TIMINGS[tier];\n // The release window must outlast the REVIEW, not just the tier. `micro`\n // alone gives two hours; a buyer approving later gets\n // `AfterAuthorizationExpiry` on-chain — the release reverts and the worker\n // is not paid. Measured in production 2026-08-19: a release attempted 26.2\n // HOURS past expiry, 8 escrows stuck on one network in 24h.\n //\n // This comment used to add \"and only the payer's `reclaim()` can move the\n // funds\". That is FALSE and it is why those escrows were treated as lost:\n // `AuthCaptureEscrow.partialVoid` is `onlySender(operator)` — the operator\n // is the facilitator — pays the PAYER, and does not look at\n // `authorizationExpiry`. `refundViaFacilitator` reaches it with no gas and\n // no payer. Widening the window still matters: it is what pays the WORKER,\n // and a refund does not.\n //\n // buildEscrowPreAuth — the other escrow path in this same SDK — already\n // floors both windows this way and says why. This path never got the memo,\n // and it is the one the marketplace documents as recommended.\n const reviewWindow = opts?.reviewWindowSec ?? REVIEW_WINDOW_SEC;\n const reviewBase = Math.max(now, opts?.deadline ?? now);\n const authorizationExpiry = Math.max(now + t.auth, reviewBase + reviewWindow);\n const refundExpiry = Math.max(now + t.refund, authorizationExpiry + REFUND_WINDOW_SEC);\n // Use crypto-safe randomness (Node.js crypto or Web Crypto API)\n let generatedSalt = salt;\n if (!generatedSalt) {\n const bytes = new Uint8Array(32);\n if (typeof globalThis.crypto !== 'undefined' && globalThis.crypto.getRandomValues) {\n globalThis.crypto.getRandomValues(bytes);\n } else {\n // Node.js fallback\n const nodeCrypto = require('crypto');\n const buf = nodeCrypto.randomBytes(32);\n bytes.set(new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength));\n }\n generatedSalt = '0x' + Array.from(bytes).map(b => b.toString(16).padStart(2, '0')).join('');\n }\n\n // Fee bounds come from ONE place — the same constants `buildEscrowPreAuth`\n // signs — because both build the same struct for the same contracts. This\n // path used to hardcode `maxFeeBps: 800`, below the SDK's own canonical\n // OPERATOR_FEE_BPS (1300). That is not a cheaper fee: `PaymentOperator`\n // compares protocolFee + operatorFee against this ceiling and reverts with\n // `FeeBoundsIncompatible` when it does not fit, so the deposit never opens\n // and nobody is paid.\n const minFeeBps = opts?.minFeeBps ?? DEFAULT_MIN_FEE_BPS;\n const maxFeeBps = opts?.maxFeeBps ?? DEFAULT_MAX_FEE_BPS;\n if (maxFeeBps < minFeeBps) {\n throw new Error(`maxFeeBps=${maxFeeBps} is below minFeeBps=${minFeeBps}`);\n }\n if (maxFeeBps < OPERATOR_FEE_BPS) {\n // Fail here, where the caller can still choose, rather than on-chain\n // after the payer has signed. Same guard buildEscrowPreAuth applies.\n throw new Error(\n `maxFeeBps=${maxFeeBps} cannot cover the operator's ${OPERATOR_FEE_BPS} ` +\n `bps fee — the on-chain authorize would revert with FeeBoundsIncompatible. ` +\n `Read the fee off your operator before overriding it.`,\n );\n }\n\n return {\n operator: this.contracts.operator,\n receiver,\n token: this.contracts.usdc,\n maxAmount: amount,\n preApprovalExpiry: now + t.pre,\n authorizationExpiry,\n refundExpiry,\n minFeeBps,\n maxFeeBps,\n feeReceiver: this.contracts.operator,\n salt: generatedSalt,\n };\n }\n\n /**\n * Compute the correct nonce (with PAYMENT_INFO_TYPEHASH).\n * Matches the on-chain AuthCaptureEscrow nonce derivation.\n */\n private async computeNonce(paymentInfo: AdvancedPaymentInfo): Promise<string> {\n // Dynamic import of ethers to avoid hard dependency at module level\n const { ethers } = await import('ethers');\n\n const piTuple = ethers.AbiCoder.defaultAbiCoder().encode(\n ['bytes32', 'tuple(address,address,address,address,uint120,uint48,uint48,uint48,uint16,uint16,address,uint256)'],\n [\n PAYMENT_INFO_TYPEHASH,\n [\n paymentInfo.operator,\n ZERO_ADDRESS, // payer = 0 for payer-agnostic hash\n paymentInfo.receiver,\n paymentInfo.token,\n paymentInfo.maxAmount,\n paymentInfo.preApprovalExpiry,\n paymentInfo.authorizationExpiry,\n paymentInfo.refundExpiry,\n paymentInfo.minFeeBps,\n paymentInfo.maxFeeBps,\n paymentInfo.feeReceiver,\n paymentInfo.salt,\n ],\n ],\n );\n const piHash = ethers.keccak256(piTuple);\n\n const finalEncoded = ethers.AbiCoder.defaultAbiCoder().encode(\n ['uint256', 'address', 'bytes32'],\n [this.chainId, this.contracts.escrow, piHash],\n );\n return ethers.keccak256(finalEncoded);\n }\n\n /**\n * Sign ReceiveWithAuthorization for ERC-3009.\n *\n * Uses SigningWalletAdapter.signTypedData() when in OWS mode,\n * or ethers Signer.signTypedData() in legacy mode.\n */\n private async signErc3009(auth: Record<string, string>): Promise<string> {\n const domain = {\n name: USDC_DOMAIN_NAME[this.chainId] || 'USD Coin',\n version: '2',\n chainId: this.chainId,\n verifyingContract: this.contracts.usdc,\n };\n\n const types = {\n ReceiveWithAuthorization: [\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 };\n\n const message = {\n from: auth.from,\n to: auth.to,\n value: auth.value,\n validAfter: auth.validAfter,\n validBefore: auth.validBefore,\n nonce: auth.nonce,\n };\n\n // OWS wallet adapter mode: serialize to JSON and use adapter.signTypedData()\n if (this.walletAdapter) {\n const typedData = JSON.stringify({\n domain,\n types,\n primaryType: 'ReceiveWithAuthorization',\n message,\n });\n const result = await this.walletAdapter.signTypedData(typedData);\n return result.signature;\n }\n\n // Legacy ethers.Signer mode\n return this.signer.signTypedData(domain, types, message);\n }\n\n /**\n * Build the on-chain PaymentInfo tuple for contract calls.\n */\n private buildTuple(pi: AdvancedPaymentInfo): any[] {\n return [\n pi.operator,\n this.payerAddress,\n pi.receiver,\n pi.token,\n pi.maxAmount,\n pi.preApprovalExpiry,\n pi.authorizationExpiry,\n pi.refundExpiry,\n pi.minFeeBps,\n pi.maxFeeBps,\n pi.feeReceiver,\n pi.salt,\n ];\n }\n\n /**\n * AUTHORIZE: Lock funds in escrow via the facilitator.\n *\n * Sends an ERC-3009 ReceiveWithAuthorization to the facilitator,\n * which calls PaymentOperator.authorize() on-chain.\n */\n async authorize(paymentInfo: AdvancedPaymentInfo): Promise<AdvancedAuthorizationResult> {\n if (!this.payerAddress) await this.init();\n\n try {\n const nonce = await this.computeNonce(paymentInfo);\n\n const auth = {\n from: this.payerAddress,\n to: this.contracts.tokenCollector,\n value: paymentInfo.maxAmount,\n validAfter: '0',\n validBefore: String(paymentInfo.preApprovalExpiry),\n nonce,\n };\n const signature = await this.signErc3009(auth);\n\n const payload = {\n x402Version: 2,\n scheme: 'escrow',\n payload: {\n authorization: auth,\n signature,\n paymentInfo: paymentInfo,\n },\n paymentRequirements: {\n scheme: 'escrow',\n network: `eip155:${this.chainId}`,\n maxAmountRequired: paymentInfo.maxAmount,\n asset: this.contracts.usdc,\n payTo: paymentInfo.receiver,\n extra: {\n escrowAddress: this.contracts.escrow,\n operatorAddress: this.contracts.operator,\n tokenCollector: this.contracts.tokenCollector,\n },\n },\n };\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(`${this.facilitatorUrl}/settle`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(payload),\n signal: controller.signal,\n });\n clearTimeout(timeoutId);\n const result = await response.json();\n\n if (result.success) {\n return {\n success: true,\n transactionHash: result.transaction,\n paymentInfo,\n salt: paymentInfo.salt,\n };\n }\n return { success: false, error: result.errorReason };\n } catch (fetchErr: any) {\n clearTimeout(timeoutId);\n\n // On timeout, check on-chain state as fallback\n if (fetchErr.name === 'AbortError') {\n try {\n const state = await this.queryEscrowState(paymentInfo);\n if (state.capturableAmount && BigInt(state.capturableAmount) > 0n) {\n return {\n success: true,\n paymentInfo,\n salt: paymentInfo.salt,\n };\n }\n } catch { /* fallback query failed, report original timeout */ }\n return { success: false, error: `Authorize timed out after ${this.timeout}ms. On-chain state could not confirm escrow lock.` };\n }\n throw fetchErr;\n }\n } catch (e: any) {\n return { success: false, error: e.message || String(e) };\n }\n }\n\n /**\n * RELEASE: Capture escrowed funds to receiver (worker gets paid).\n *\n * Calls PaymentOperator.release() -> escrow.capture()\n *\n * On a `'v3'` operator (Arc, Arc Testnet) it calls\n * `PaymentOperator.capture(paymentInfo, amount, 0x)` instead, after checking\n * that the operator has code ({@link ESCROW_OPERATOR_NOT_DEPLOYED}).\n *\n * @param paymentInfo - PaymentInfo from the authorize step\n * @param amount - Amount to release (defaults to maxAmount)\n */\n async release(paymentInfo: AdvancedPaymentInfo, amount?: string): Promise<AdvancedTransactionResult> {\n if (!this.payerAddress) await this.init();\n\n try {\n const { ethers } = await import('ethers');\n const generation = getEscrowOperatorGeneration(this.chainId);\n const isCreate3 = generation === 'v2';\n const abi = isCreate3 ? OPERATOR_ABI_CREATE3 : OPERATOR_ABI;\n const amt = amount || paymentInfo.maxAmount;\n const tuple = this.buildTuple(paymentInfo);\n\n if (generation === 'v3') {\n return await this.sendV3OperatorCall(ethers, this.v3Provider(ethers), 'capture', [tuple, amt, '0x']);\n }\n\n // OWS wallet adapter mode: build unsigned TX, sign via adapter, broadcast\n if (this.walletAdapter) {\n return this.sendViaAdapter(ethers, abi, (iface) => {\n return isCreate3\n ? iface.encodeFunctionData('release', [tuple, amt, '0x'])\n : iface.encodeFunctionData('release', [tuple, amt]);\n });\n }\n\n // Legacy ethers.Signer mode: contract sends directly\n const contract = new ethers.Contract(this.contracts.operator, abi, this.signer);\n const tx = isCreate3\n ? await contract.release(tuple, amt, '0x', { gasLimit: this.gasLimit })\n : await contract.release(tuple, amt, { gasLimit: this.gasLimit });\n const receipt = await tx.wait();\n\n return {\n success: receipt.status === 1,\n transactionHash: receipt.hash,\n gasUsed: Number(receipt.gasUsed),\n error: receipt.status !== 1 ? 'Transaction reverted' : undefined,\n };\n } catch (e: any) {\n return { success: false, error: e.message || String(e) };\n }\n }\n\n /**\n * REFUND IN ESCROW: Return escrowed funds to payer (cancel task).\n *\n * Calls PaymentOperator.refundInEscrow() -> escrow.partialVoid()\n *\n * On a `'v3'` operator (Arc, Arc Testnet) it calls\n * `PaymentOperator.void(paymentInfo, 0x)`, which takes no amount and returns\n * the WHOLE `capturableAmount`. So it first reads that amount on-chain\n * (`AuthCaptureEscrow.getHash` + `paymentState`) and sends only when\n * `amount` equals it. Otherwise nothing is sent and `errorCode` says why:\n * {@link ESCROW_NOTHING_TO_VOID} when it is 0,\n * {@link ESCROW_VOID_AMOUNT_MISMATCH} for any other amount. To return part\n * of an escrow on v3, `release` the part the receiver keeps, then\n * `refundInEscrow` what is left.\n *\n * @param paymentInfo - PaymentInfo from the authorize step\n * @param amount - Amount to refund (defaults to maxAmount)\n */\n async refundInEscrow(paymentInfo: AdvancedPaymentInfo, amount?: string): Promise<AdvancedTransactionResult> {\n if (!this.payerAddress) await this.init();\n\n try {\n const { ethers } = await import('ethers');\n const generation = getEscrowOperatorGeneration(this.chainId);\n const isCreate3 = generation === 'v2';\n const abi = isCreate3 ? OPERATOR_ABI_CREATE3 : OPERATOR_ABI;\n const amt = amount || paymentInfo.maxAmount;\n const tuple = this.buildTuple(paymentInfo);\n\n if (generation === 'v3') {\n return await this.voidWholeCapturable(ethers, tuple, amt);\n }\n\n // OWS wallet adapter mode: build unsigned TX, sign via adapter, broadcast\n if (this.walletAdapter) {\n return this.sendViaAdapter(ethers, abi, (iface) => {\n return isCreate3\n ? iface.encodeFunctionData('refundInEscrow', [tuple, amt, '0x'])\n : iface.encodeFunctionData('refundInEscrow', [tuple, amt]);\n });\n }\n\n // Legacy ethers.Signer mode\n const contract = new ethers.Contract(this.contracts.operator, abi, this.signer);\n const tx = isCreate3\n ? await contract.refundInEscrow(tuple, amt, '0x', { gasLimit: this.gasLimit })\n : await contract.refundInEscrow(tuple, amt, { gasLimit: this.gasLimit });\n const receipt = await tx.wait();\n\n return {\n success: receipt.status === 1,\n transactionHash: receipt.hash,\n gasUsed: Number(receipt.gasUsed),\n error: receipt.status !== 1 ? 'Transaction reverted' : undefined,\n };\n } catch (e: any) {\n return { success: false, error: e.message || String(e) };\n }\n }\n\n // ==========================================================================\n // GASLESS FACILITATOR METHODS\n // ==========================================================================\n\n /**\n * GASLESS RELEASE: Release escrowed funds via the facilitator.\n *\n * Instead of calling the PaymentOperator contract directly (which requires\n * gas), this sends a release request to the facilitator, which submits\n * the transaction on your behalf.\n *\n * @param paymentInfo - PaymentInfo from the authorize step\n * @param amount - Amount to release in atomic units (defaults to maxAmount)\n * @returns Transaction result from the facilitator\n *\n * @example\n * ```typescript\n * const pi = client.buildPaymentInfo('0xWorker...', '5000000', 'standard');\n * await client.authorize(pi);\n * // Worker completes task...\n * const result = await client.releaseViaFacilitator(pi);\n * console.log(result.transactionHash);\n * ```\n *\n * @example Signed release (the payer proves the release is theirs to ask for)\n * ```typescript\n * await client.releaseViaFacilitator(pi, undefined, {\n * lifecycleSigner: payerWallet, // EnvKeyAdapter, OWS, wagmiLifecycleSigner(...)\n * });\n * ```\n *\n * @example Transporting an order the publisher signed in their browser\n * ```typescript\n * // The browser sent back a signature over a document THIS backend built.\n * const lifecycleAuth = lifecycleAuthFromSignature(typedData, signature, payer);\n * await client.releaseViaFacilitator(pi, amount, { lifecycleAuth });\n * ```\n */\n async releaseViaFacilitator(\n paymentInfo: AdvancedPaymentInfo,\n amount?: string,\n options?: LifecycleAuthOptions,\n ): Promise<AdvancedTransactionResult> {\n if (!this.payerAddress) await this.init();\n\n try {\n const wirePaymentInfo = {\n operator: paymentInfo.operator,\n receiver: paymentInfo.receiver,\n token: paymentInfo.token,\n maxAmount: paymentInfo.maxAmount,\n preApprovalExpiry: paymentInfo.preApprovalExpiry,\n authorizationExpiry: paymentInfo.authorizationExpiry,\n refundExpiry: paymentInfo.refundExpiry,\n minFeeBps: paymentInfo.minFeeBps,\n maxFeeBps: paymentInfo.maxFeeBps,\n feeReceiver: paymentInfo.feeReceiver,\n salt: paymentInfo.salt,\n };\n const releaseAmount = amount || paymentInfo.maxAmount;\n\n // The signed lifecycle order: signed here from a `lifecycleSigner`, or\n // handed over already signed as `lifecycleAuth`. With NEITHER the payload\n // goes out byte-for-byte as it did before — the facilitator's default\n // mode does not look at the field at all.\n const lifecycleAuth = await resolveLifecycleAuth('release', options, {\n paymentInfo: wirePaymentInfo,\n payer: this.payerAddress,\n amount: releaseAmount,\n chainId: this.chainId,\n });\n\n const payload = {\n x402Version: 2,\n scheme: 'escrow',\n action: 'release',\n payload: {\n paymentInfo: wirePaymentInfo,\n payer: this.payerAddress,\n amount: releaseAmount,\n ...(lifecycleAuth ? { lifecycleAuth } : {}),\n },\n paymentRequirements: {\n scheme: 'escrow',\n network: `eip155:${this.chainId}`,\n extra: {\n escrowAddress: this.contracts.escrow,\n operatorAddress: this.contracts.operator,\n tokenCollector: this.contracts.tokenCollector,\n },\n },\n };\n\n try {\n // A 503 from the writer lease is NOT a refused release. The facilitator\n // never reached the chain, so the escrow still holds every token and\n // the same request is the right thing to send again. Reading it as a\n // refusal is how a recoverable escrow gets written off.\n const { response, error } = await facilitatorFetch(\n `${this.facilitatorUrl}/settle`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(payload),\n },\n { timeoutMs: this.timeout, retries: this.retries },\n );\n if (error) {\n return { success: false, error: error.error, ...failureFields(error) };\n }\n const result = await response.json();\n\n if (result.success) {\n return {\n success: true,\n transactionHash: result.transaction || result.transactionHash || result.transaction_hash,\n };\n }\n // Parity with the Python SDK (2026-08-22): a last-resort message that\n // says only \"Release failed\" is the same dead end as an empty string —\n // name the status and what the body DID carry so the caller has a\n // thread to pull. Divergence between the two SDKs is exactly what let\n // the escrow-window bug live in one of them for weeks.\n return {\n success: false,\n error:\n result.errorReason ||\n result.error ||\n `Release refused with no reason (HTTP ${response.status}, body keys: ${Object.keys(result ?? {}).sort().join(', ') || 'none'})`,\n };\n } catch (fetchErr: any) {\n // On timeout, check on-chain state as fallback\n if (fetchErr.name === 'AbortError') {\n try {\n const state = await this.queryEscrowState(paymentInfo);\n if (state.capturableAmount === '0' && state.hasCollectedPayment) {\n return { success: true };\n }\n } catch { /* fallback query failed */ }\n return { success: false, error: `Gasless release timed out after ${this.timeout}ms. Check escrow state on-chain.` };\n }\n throw fetchErr;\n }\n } catch (e: any) {\n return { success: false, error: e.message || String(e) };\n }\n }\n\n /**\n * GASLESS REFUND: return escrowed funds to the payer via the facilitator.\n *\n * Sends `action: \"refundInEscrow\"` to `POST /settle`; the facilitator's\n * PaymentOperator calls `AuthCaptureEscrow.partialVoid`.\n *\n * # This is how an EXPIRED escrow is recovered\n *\n * A widely repeated claim — including in this SDK's own comments until now —\n * says that once `authorizationExpiry` passes, only the payer's `reclaim()`\n * can move the funds. **That is false, and believing it has left real money\n * stranded.**\n *\n * Read the contract (`AuthCaptureEscrow.sol`):\n *\n * - `partialVoid` is `onlySender(paymentInfo.operator)` — the operator is the\n * FACILITATOR, not the payer — it sends the tokens **to the payer**, and it\n * **does not check `authorizationExpiry` at all**. It works before expiry\n * and after it, and the payer never has to appear.\n * - `reclaim` is `onlySender(paymentInfo.payer)` and only after expiry. It is\n * a payer's self-service escape hatch, which is why this facilitator does\n * not expose it — **not** the only way out.\n *\n * So a release that reverted with `AfterAuthorizationExpiry` is recoverable\n * from here, with no gas and no cooperation from the payer. Get the amount\n * from {@link queryEscrowState}'s `capturableAmount`.\n *\n * # A refusal that is not a refusal\n *\n * Check `retryable` before writing an escrow off. A `503` means the\n * facilitator never reached the chain — the escrow is untouched and the same\n * request should be sent again.\n *\n * @param paymentInfo - PaymentInfo from the authorize step\n * @param amount - Amount to refund in atomic units (defaults to maxAmount).\n * For a stuck escrow pass `capturableAmount` from {@link queryEscrowState}.\n * @returns Transaction result from the facilitator\n *\n * @example Recovering an escrow whose release window already closed\n * ```typescript\n * const state = await client.queryEscrowState(pi);\n * if (state.capturableAmount !== '0') {\n * // No payer needed, no gas, and expiry is irrelevant to partialVoid.\n * const result = await client.refundViaFacilitator(pi, state.capturableAmount);\n * if (!result.success && result.retryable) {\n * // No verdict was reached. The funds are still there; send it again.\n * }\n * }\n * ```\n */\n async refundViaFacilitator(\n paymentInfo: AdvancedPaymentInfo,\n amount?: string,\n options?: LifecycleAuthOptions,\n ): Promise<AdvancedTransactionResult> {\n if (!this.payerAddress) await this.init();\n\n try {\n const wirePaymentInfo = {\n operator: paymentInfo.operator,\n receiver: paymentInfo.receiver,\n token: paymentInfo.token,\n maxAmount: paymentInfo.maxAmount,\n preApprovalExpiry: paymentInfo.preApprovalExpiry,\n authorizationExpiry: paymentInfo.authorizationExpiry,\n refundExpiry: paymentInfo.refundExpiry,\n minFeeBps: paymentInfo.minFeeBps,\n maxFeeBps: paymentInfo.maxFeeBps,\n feeReceiver: paymentInfo.feeReceiver,\n salt: paymentInfo.salt,\n };\n const refundAmount = amount || paymentInfo.maxAmount;\n\n // Same optional order as `releaseViaFacilitator`, with the caveat that\n // the accepted signers differ: the receiver, the operator owner, or the\n // payer once `authorizationExpiry` has passed.\n const lifecycleAuth = await resolveLifecycleAuth('refundInEscrow', options, {\n paymentInfo: wirePaymentInfo,\n payer: this.payerAddress,\n amount: refundAmount,\n chainId: this.chainId,\n });\n\n const payload = {\n x402Version: 2,\n scheme: 'escrow',\n action: 'refundInEscrow',\n payload: {\n paymentInfo: wirePaymentInfo,\n payer: this.payerAddress,\n amount: refundAmount,\n ...(lifecycleAuth ? { lifecycleAuth } : {}),\n },\n paymentRequirements: {\n scheme: 'escrow',\n network: `eip155:${this.chainId}`,\n extra: {\n escrowAddress: this.contracts.escrow,\n operatorAddress: this.contracts.operator,\n tokenCollector: this.contracts.tokenCollector,\n },\n },\n };\n\n try {\n // The non-2xx branch used to be missing entirely: `response.json()` on\n // a 503 body yields `{error, reason}`, `result.success` is undefined,\n // and the refund was reported as failed. That is a recoverable escrow\n // declared lost on a facilitator hiccup.\n const { response, error } = await facilitatorFetch(\n `${this.facilitatorUrl}/settle`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(payload),\n },\n { timeoutMs: this.timeout, retries: this.retries },\n );\n if (error) {\n return { success: false, error: error.error, ...failureFields(error) };\n }\n const result = await response.json();\n\n if (result.success) {\n return {\n success: true,\n transactionHash: result.transaction || result.transactionHash || result.transaction_hash,\n };\n }\n return {\n success: false,\n error:\n result.errorReason ||\n result.error ||\n `Refund refused with no reason (HTTP ${response.status}, body keys: ${Object.keys(result ?? {}).sort().join(', ') || 'none'})`,\n };\n } catch (fetchErr: any) {\n // On timeout, check on-chain state as fallback\n if (fetchErr.name === 'AbortError') {\n try {\n const state = await this.queryEscrowState(paymentInfo);\n if (state.refundableAmount === '0') {\n return { success: true };\n }\n } catch { /* fallback query failed */ }\n return { success: false, error: `Gasless refund timed out after ${this.timeout}ms. Check escrow state on-chain.` };\n }\n throw fetchErr;\n }\n } catch (e: any) {\n return { success: false, error: e.message || String(e) };\n }\n }\n\n /**\n * QUERY ESCROW STATE: Read on-chain escrow state via the facilitator.\n *\n * This is a read-only operation that queries the facilitator for the\n * current escrow state without requiring gas or a signer.\n *\n * @param paymentInfo - PaymentInfo to query state for\n * @returns Escrow state including capturable/refundable amounts\n *\n * @example\n * ```typescript\n * const pi = client.buildPaymentInfo('0xWorker...', '5000000', 'standard');\n * await client.authorize(pi);\n *\n * const state = await client.queryEscrowState(pi);\n * console.log(`Capturable: ${state.capturableAmount}`);\n * console.log(`Refundable: ${state.refundableAmount}`);\n * console.log(`Already collected: ${state.hasCollectedPayment}`);\n * ```\n */\n async queryEscrowState(paymentInfo: AdvancedPaymentInfo): Promise<EscrowStateResponse> {\n if (!this.payerAddress) await this.init();\n\n const payload = {\n paymentInfo: {\n operator: paymentInfo.operator,\n receiver: paymentInfo.receiver,\n token: paymentInfo.token,\n maxAmount: paymentInfo.maxAmount,\n preApprovalExpiry: paymentInfo.preApprovalExpiry,\n authorizationExpiry: paymentInfo.authorizationExpiry,\n refundExpiry: paymentInfo.refundExpiry,\n minFeeBps: paymentInfo.minFeeBps,\n maxFeeBps: paymentInfo.maxFeeBps,\n feeReceiver: paymentInfo.feeReceiver,\n salt: paymentInfo.salt,\n },\n payer: this.payerAddress,\n network: `eip155:${this.chainId}`,\n extra: {\n escrowAddress: this.contracts.escrow,\n operatorAddress: this.contracts.operator,\n tokenCollector: this.contracts.tokenCollector,\n },\n };\n\n const response = await fetch(`${this.facilitatorUrl}/escrow/state`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Escrow state query failed: ${response.status} - ${errorText}`);\n }\n\n return await response.json() as EscrowStateResponse;\n }\n\n /**\n * CHARGE: Direct instant payment (no escrow hold).\n *\n * Calls PaymentOperator.charge() -> escrow.charge()\n * Funds go directly from payer to receiver.\n *\n * Not available on a `'v3'` operator (Arc, Arc Testnet): it returns\n * {@link ESCROW_UNSUPPORTED_ON_GENERATION} without signing or sending.\n *\n * @param paymentInfo - PaymentInfo with receiver and amount\n * @param amount - Amount to charge (defaults to maxAmount)\n */\n async charge(paymentInfo: AdvancedPaymentInfo, amount?: string): Promise<AdvancedTransactionResult> {\n const unsupported = this.unsupportedOnV3('charge');\n if (unsupported) return unsupported;\n if (!this.payerAddress) await this.init();\n\n try {\n const { ethers } = await import('ethers');\n const nonce = await this.computeNonce(paymentInfo);\n const amt = amount || paymentInfo.maxAmount;\n\n const auth = {\n from: this.payerAddress,\n to: this.contracts.tokenCollector,\n value: String(amt),\n validAfter: '0',\n validBefore: String(paymentInfo.preApprovalExpiry),\n nonce,\n };\n const signature = await this.signErc3009(auth);\n // Pass raw signature bytes as collectorData (ethers handles hex -> bytes)\n const collectorData = ethers.getBytes(signature);\n\n const tuple = this.buildTuple(paymentInfo);\n\n // OWS wallet adapter mode\n if (this.walletAdapter) {\n return this.sendViaAdapter(ethers, OPERATOR_ABI, (iface) => {\n return iface.encodeFunctionData('charge', [\n tuple, amt, this.contracts.tokenCollector, collectorData,\n ]);\n });\n }\n\n // Legacy ethers.Signer mode\n const contract = new ethers.Contract(this.contracts.operator, OPERATOR_ABI, this.signer);\n const tx = await contract.charge(\n tuple,\n amt,\n this.contracts.tokenCollector,\n collectorData,\n { gasLimit: this.gasLimit },\n );\n const receipt = await tx.wait();\n\n return {\n success: receipt.status === 1,\n transactionHash: receipt.hash,\n gasUsed: Number(receipt.gasUsed),\n error: receipt.status !== 1 ? 'Transaction reverted' : undefined,\n };\n } catch (e: any) {\n return { success: false, error: e.message || String(e) };\n }\n }\n\n /**\n * REFUND POST ESCROW: Dispute refund after funds were released.\n *\n * Calls PaymentOperator.refundPostEscrow() -> escrow.refund()\n *\n * WARNING: NOT FUNCTIONAL IN PRODUCTION (as of 2026-02-03).\n * The protocol team has not implemented the required tokenCollector\n * contract. This call will fail on-chain.\n *\n * For dispute resolution, use refundInEscrow() instead: keep funds\n * in escrow and refund before releasing. This guarantees funds are\n * available and under arbiter control.\n *\n * Kept for future use when tokenCollector is implemented.\n *\n * On a `'v3'` operator (Arc, Arc Testnet) it calls\n * `PaymentOperator.refund(paymentInfo, amount, tokenCollector, collectorData)`\n * -> escrow.refund(), the same arguments, after checking that the operator\n * has code ({@link ESCROW_OPERATOR_NOT_DEPLOYED}).\n *\n * @param paymentInfo - PaymentInfo from the original authorization\n * @param amount - Amount to refund (defaults to maxAmount)\n * @param tokenCollector - Address of token collector for refund sourcing\n * @param collectorData - Data for the token collector\n */\n async refundPostEscrow(\n paymentInfo: AdvancedPaymentInfo,\n amount?: string,\n tokenCollector?: string,\n collectorData?: string,\n ): Promise<AdvancedTransactionResult> {\n if (!this.payerAddress) await this.init();\n\n try {\n const { ethers } = await import('ethers');\n const amt = amount || paymentInfo.maxAmount;\n const tuple = this.buildTuple(paymentInfo);\n\n if (getEscrowOperatorGeneration(this.chainId) === 'v3') {\n return await this.sendV3OperatorCall(ethers, this.v3Provider(ethers), 'refund', [\n tuple, amt, tokenCollector || ZERO_ADDRESS, collectorData || '0x',\n ]);\n }\n\n // OWS wallet adapter mode\n if (this.walletAdapter) {\n return this.sendViaAdapter(ethers, OPERATOR_ABI, (iface) => {\n return iface.encodeFunctionData('refundPostEscrow', [\n tuple, amt, tokenCollector || ZERO_ADDRESS, collectorData || '0x',\n ]);\n });\n }\n\n // Legacy ethers.Signer mode\n const contract = new ethers.Contract(this.contracts.operator, OPERATOR_ABI, this.signer);\n const tx = await contract.refundPostEscrow(\n tuple,\n amt,\n tokenCollector || ZERO_ADDRESS,\n collectorData || '0x',\n { gasLimit: this.gasLimit },\n );\n const receipt = await tx.wait();\n\n return {\n success: receipt.status === 1,\n transactionHash: receipt.hash,\n gasUsed: Number(receipt.gasUsed),\n error: receipt.status !== 1 ? 'Transaction reverted' : undefined,\n };\n } catch (e: any) {\n return { success: false, error: e.message || String(e) };\n }\n }\n\n // ==========================================================================\n // INTERNAL: 'v3' operator (Arc, Arc Testnet)\n // ==========================================================================\n\n /** The refusal of a call a 'v3' operator does not have, or null elsewhere. */\n private unsupportedOnV3(method: 'charge'): AdvancedTransactionResult | null {\n if (getEscrowOperatorGeneration(this.chainId) !== 'v3') return null;\n return {\n success: false,\n errorCode: ESCROW_UNSUPPORTED_ON_GENERATION,\n error:\n `${method} is not available on the v3 escrow operator of chain ${this.chainId} ` +\n `(OPERATOR_ABI_V3). Nothing was signed or sent.`,\n };\n }\n\n /** The provider a 'v3' call reads with before it sends anything. */\n private v3Provider(ethersModule: any): any {\n const provider = this.walletAdapter\n ? new ethersModule.JsonRpcProvider(this.rpcUrl)\n : this.signer?.provider;\n if (!provider) {\n throw new Error(\n `AdvancedEscrowClient: chain ${this.chainId} uses a v3 escrow operator, which is read ` +\n 'on-chain before any call; the signer has no provider to read with.',\n );\n }\n return provider;\n }\n\n /**\n * Send one OPERATOR_ABI_V3 call, once the operator is known to have code.\n * A call to an address with no code succeeds and moves nothing, and would be\n * reported as a success.\n */\n private async sendV3OperatorCall(\n ethersModule: any,\n provider: any,\n method: 'capture' | 'void' | 'refund',\n args: unknown[],\n ): Promise<AdvancedTransactionResult> {\n const code: string = await provider.getCode(this.contracts.operator);\n if (!code || code === '0x') {\n return {\n success: false,\n errorCode: ESCROW_OPERATOR_NOT_DEPLOYED,\n error:\n `The escrow operator ${this.contracts.operator} has no code on chain ${this.chainId}. ` +\n 'Nothing was sent.',\n };\n }\n\n if (this.walletAdapter) {\n return await this.sendViaAdapter(ethersModule, OPERATOR_ABI_V3, (iface) =>\n iface.encodeFunctionData(method, args),\n );\n }\n\n const contract = new ethersModule.Contract(this.contracts.operator, OPERATOR_ABI_V3, this.signer);\n const tx = await contract.getFunction(method)(...args, { gasLimit: this.gasLimit });\n const receipt = await tx.wait();\n\n return {\n success: receipt.status === 1,\n transactionHash: receipt.hash,\n gasUsed: Number(receipt.gasUsed),\n error: receipt.status !== 1 ? 'Transaction reverted' : undefined,\n };\n }\n\n /**\n * `refundInEscrow` on a 'v3' operator: `void` returns the whole capturable\n * amount, so it is sent only when that is exactly what was asked for.\n */\n private async voidWholeCapturable(\n ethersModule: any,\n tuple: any[],\n amount: string,\n ): Promise<AdvancedTransactionResult> {\n const requested = BigInt(amount);\n if (requested <= 0n) {\n return { success: false, error: `refundInEscrow amount must be positive, got ${amount}. Nothing was sent.` };\n }\n\n const provider = this.v3Provider(ethersModule);\n const escrow = new ethersModule.Contract(this.contracts.escrow, AUTH_CAPTURE_ESCROW_STATE_ABI, provider);\n const paymentInfoHash = await escrow.getHash(tuple);\n const [, capturable] = await escrow.paymentState(paymentInfoHash);\n const capturableAmount = BigInt(capturable);\n\n if (capturableAmount === 0n) {\n return {\n success: false,\n errorCode: ESCROW_NOTHING_TO_VOID,\n error:\n `Nothing to void on chain ${this.chainId}: capturableAmount is 0 for payment ` +\n `${paymentInfoHash}. Nothing was sent.`,\n };\n }\n if (requested !== capturableAmount) {\n return {\n success: false,\n errorCode: ESCROW_VOID_AMOUNT_MISMATCH,\n error:\n `refundInEscrow asked for ${requested} but the v3 operator's void() returns the whole ` +\n `capturableAmount, ${capturableAmount}. Pass ${capturableAmount}, or release the part the ` +\n 'receiver keeps first. Nothing was sent.',\n };\n }\n\n return await this.sendV3OperatorCall(ethersModule, provider, 'void', [tuple, '0x']);\n }\n\n // ==========================================================================\n // INTERNAL: Adapter-based transaction signing and broadcast\n // ==========================================================================\n\n /**\n * Build an unsigned transaction, sign via SigningWalletAdapter, and broadcast.\n *\n * Used by release(), refundInEscrow(), charge(), refundPostEscrow() when\n * operating in OWS wallet adapter mode. The adapter signs the serialized\n * transaction offline; the RPC provider broadcasts the signed raw TX.\n *\n * @param ethersModule - ethers namespace (from `const { ethers } = await import('ethers')`)\n * @param abi - Contract ABI (OPERATOR_ABI or OPERATOR_ABI_CREATE3)\n * @param encodeCalldata - Function that encodes the calldata using the interface\n * @returns Transaction result\n */\n private async sendViaAdapter(\n ethersModule: any,\n abi: string[],\n encodeCalldata: (iface: any) => string,\n ): Promise<AdvancedTransactionResult> {\n const provider = new ethersModule.JsonRpcProvider(this.rpcUrl);\n const iface = new ethersModule.Interface(abi);\n const data = encodeCalldata(iface);\n\n // Build unsigned transaction\n const nonce = await provider.getTransactionCount(this.payerAddress);\n const feeData = await provider.getFeeData();\n\n const unsignedTx = ethersModule.Transaction.from({\n to: this.contracts.operator,\n data,\n gasLimit: this.gasLimit,\n nonce,\n chainId: this.chainId,\n maxFeePerGas: feeData.maxFeePerGas,\n maxPriorityFeePerGas: feeData.maxPriorityFeePerGas,\n type: 2, // EIP-1559\n });\n\n // Sign via adapter\n const signedTxHex = await this.walletAdapter!.signTransaction(unsignedTx.unsignedSerialized);\n\n // Broadcast\n const txResponse = await provider.broadcastTransaction(signedTxHex);\n const receipt = await txResponse.wait();\n\n return {\n success: receipt !== null && receipt.status === 1,\n transactionHash: txResponse.hash,\n gasUsed: receipt ? Number(receipt.gasUsed) : undefined,\n error: receipt && receipt.status !== 1 ? 'Transaction reverted' : undefined,\n };\n }\n}\n","/**\n * Reading a facilitator refusal as DATA instead of prose.\n *\n * # Why this file exists\n *\n * `402` and `503` say opposite things and the SDK used to collapse both into\n * `success: false` plus an English sentence.\n *\n * - **402** means the payment was REJECTED. The credential is spent; sign a new\n * authorization.\n * - **503** means NO VERDICT WAS REACHED. Nothing was rejected and nothing was\n * executed; retry the SAME credential.\n *\n * Turning a 503 into a 402 makes the buyer sign and send a second payment for a\n * money movement that was never refused — they pay twice. That is the most\n * expensive mistake this SDK can make, so every facilitator edge now reports the\n * status, the facilitator's own `reason`, and whether the request may be\n * replayed.\n *\n * # The writer lease\n *\n * The facilitator serialises every EVM write through the one process that holds\n * the EVM writer lease, because they all spend gas from the same EOA and the\n * nonce for it is allocated in memory. A task that does not hold the lease\n * forwards the request to the one that does; when it cannot, it answers\n * `503` + `Retry-After: 5` + `{\"error\": \"...\", \"reason\": \"<why>\"}`.\n *\n * The five reasons do NOT share retry semantics, which is the whole point of\n * surfacing them:\n *\n * | reason | did the write run? | replay? |\n * |----------------------------|--------------------|---------|\n * | `holder_unknown` | no | yes |\n * | `forwarding_disabled` | no | yes |\n * | `forwarded_but_not_writer` | no | yes |\n * | `body_unreadable` | no | yes |\n * | `forward_failed` | **maybe** | **no** |\n *\n * `forward_failed` is emitted after the forward was attempted: the holder may\n * have executed the write and the response been lost on the way back. It is a\n * timeout wearing a status code. Replaying a `/register` on it is exactly the\n * sequence that once minted five duplicate agents — reconcile with\n * `GET /identity/{network}/owner/{recipient}` or `getRegisterStatus` instead.\n *\n * # The two `502`s of `/settle`, which mean opposite things\n *\n * | body `error` | `Retry-After` | did the money move? | retry? |\n * |----------------------------|---------------|---------------------|-----------|\n * | `upstream_rpc_unavailable` | `30` | no, never broadcast | **yes** |\n * | `settlement_unconfirmed` | **absent** | **maybe — mined?** | **NEVER** |\n *\n * `settlement_unconfirmed` is answered after the transaction was broadcast and\n * no receipt ever arrived, so it MAY be mined. Retrying re-signs a new\n * authorization with a fresh nonce, which the chain accepts as a second,\n * perfectly valid payment for the same purchase — the buyer pays twice, in\n * exactly the case the facilitator emits it to prevent. The `transaction` hash\n * and `paymentId` travel in the body so the caller can LOOK AT THE CHAIN; they\n * are not an invitation to send it again.\n *\n * The status cannot tell the two apart, which is why this file used to get it\n * wrong: every `502` was retryable, and until `settlement_unconfirmed` existed\n * that was correct. **Branch on the body.**\n *\n * The general form of that rule — **a 5xx whose body carries a transaction hash\n * was broadcast, whatever the error is called** — is adopted from the Python\n * SDK, which has carried it as its anti-double-settle guard\n * (`uvd_x402_sdk/client.py`, `_is_retryable_settle_error`) while this one had\n * only the status to go on.\n *\n * # The `409`s of an authorization the facilitator already admitted\n *\n * On networks with durable receipts the facilitator answers a resend of an\n * admitted authorization with its ORIGINAL answer only when the resend carries\n * the purchase binding that admitted it: the same `Idempotency-Key`, or the\n * same `X-UVD-Purchase` capability. That answer is marked\n * `Idempotent-Replayed: true`. Possession of the signed payment alone is not a\n * binding, so a resend without one is refused:\n *\n * | code (`/settle` 409 `error`, `/verify` `invalidReason`) | payment state | serve it? | retry? |\n * |-----------------------------------|--------------------|-----------|------------------------------------------|\n * | `authorization_already_settled` | confirmed | **no** | no — this X-PAYMENT was already used |\n * | `authorization_in_flight` | pending / unknown | **no** | yes, the SAME request, to learn the verdict; only the admitting binding gets the original answer |\n * | `receipt_request_conflict` | another purchase | **no** | no |\n *\n * None of them is a rejection of the signature, so none may be answered `402`\n * (the buyer would sign a second payment for a purchase whose first payment\n * settled or is settling), and none is a server fault, so none is a `500`.\n * The facilitator never admits a replacement payment for any of them.\n *\n * Read from x402-rs `src/receipts/mod.rs` (`replay`, `verify`,\n * `admitted_reason`) and `docs/facilitator-receipts.md`, \"Replays of an\n * admitted authorization\" (facilitator 2.39.0).\n *\n * Source of the other shapes: x402-rs `src/handlers.rs` `writer_lease_unavailable()`\n * and `require_writer_lease()`; `SettlementUnconfirmedResponse` in\n * `src/types.rs`, built in the `IntoResponse` of `FacilitatorLocalError`.\n */\n\n/**\n * A `reason` the facilitator attaches to a writer-lease 503.\n *\n * Typed as a union for discrimination but never used to VALIDATE: the fields\n * that carry it are plain `string`, so a reason added on the server does not\n * break compilation here.\n */\nexport type WriterLeaseReason =\n | 'holder_unknown'\n | 'forwarding_disabled'\n | 'forwarded_but_not_writer'\n | 'body_unreadable'\n | 'forward_failed';\n\n/** Every writer-lease reason the facilitator emits today. */\nexport const WRITER_LEASE_REASONS: readonly WriterLeaseReason[] = [\n 'holder_unknown',\n 'forwarding_disabled',\n 'forwarded_but_not_writer',\n 'body_unreadable',\n 'forward_failed',\n];\n\n/**\n * The reasons returned BEFORE the write is handed to anyone.\n *\n * The facilitator refuses these in its router, so the request provably did not\n * execute and re-sending the identical body is safe — including a mint.\n */\nexport const REPLAYABLE_LEASE_REASONS: readonly WriterLeaseReason[] = [\n 'holder_unknown',\n 'forwarding_disabled',\n 'forwarded_but_not_writer',\n 'body_unreadable',\n];\n\n/**\n * The reason that is ambiguous: the write may already have happened.\n *\n * Still `retryable` — the credential was not rejected — but never replayed\n * automatically. Resolve it by reading state, not by re-POSTing.\n */\nexport const AMBIGUOUS_LEASE_REASONS: readonly WriterLeaseReason[] = ['forward_failed'];\n\n/**\n * The facilitator's `error` code for a settle it broadcast and could not confirm.\n *\n * The transaction may be mined. This is the one upstream failure that must\n * never be retried; reconcile with `transaction` / `paymentId` instead.\n */\nexport const SETTLEMENT_UNCONFIRMED = 'settlement_unconfirmed';\n\n/**\n * The authorization was already admitted and its payment is confirmed; this\n * request does not carry the binding that admitted it. This X-PAYMENT was\n * used: do not serve the purchase again and do not ask for a new signature.\n */\nexport const AUTHORIZATION_ALREADY_SETTLED = 'authorization_already_settled';\n\n/**\n * The authorization was already admitted and its payment is still pending or\n * unknown; this request does not carry the binding that admitted it. Resend\n * the SAME request later to learn the verdict, never a new signature. Only the\n * admitting `Idempotency-Key` or `X-UVD-Purchase` gets the original answer.\n */\nexport const AUTHORIZATION_IN_FLIGHT = 'authorization_in_flight';\n\n/**\n * The authorization, purchase capability or idempotency key already belongs\n * to a different request. Nothing was admitted and nothing will be.\n */\nexport const RECEIPT_REQUEST_CONFLICT = 'receipt_request_conflict';\n\n/** The codes of an authorization the facilitator admitted for another request. */\nexport type AdmittedAuthorizationCode =\n | typeof AUTHORIZATION_ALREADY_SETTLED\n | typeof AUTHORIZATION_IN_FLIGHT\n | typeof RECEIPT_REQUEST_CONFLICT;\n\n/**\n * Ceiling, in seconds, on how long an automatic retry will wait.\n *\n * `Retry-After` is a hint from a server that may be misconfigured. Honouring a\n * literal `Retry-After: 3600` would hang the caller's request for an hour\n * inside a function documented as returning promptly, so the header is honoured\n * only up to this bound.\n */\nexport const MAX_RETRY_AFTER_SECONDS = 15;\n\n/** Wait used when a 503 carries no usable `Retry-After`. */\nexport const DEFAULT_RETRY_AFTER_SECONDS = 5;\n\n/** How many EXTRA attempts a retryable facilitator refusal gets by default. */\nexport const DEFAULT_FACILITATOR_RETRIES = 2;\n\n/**\n * A non-2xx answer from the facilitator, kept structured.\n *\n * `error` is byte-identical to the string this SDK has always produced, so\n * callers matching on it keep working; everything else is new and optional.\n */\nexport interface FacilitatorErrorInfo {\n /** Legacy flattened message: `Facilitator error: <status> - <body>`. */\n error: string;\n /** HTTP status the facilitator answered with. */\n status: number;\n /** The facilitator's own `reason`, when the body carried one. */\n reason?: string;\n /**\n * The facilitator's machine-readable `error` code, verbatim.\n *\n * Some codes carry a `(ref: <uuid>)` suffix, so compare with care —\n * {@link SETTLEMENT_UNCONFIRMED} is emitted bare. Branch on this rather than\n * on the status: `/settle` has two `502`s that mean opposite things.\n */\n errorCode?: string;\n /**\n * The hash of a transaction that WAS broadcast, in that chain's own encoding.\n *\n * Present on {@link SETTLEMENT_UNCONFIRMED}. Not always `0x`-prefixed:\n * Algorand prints base32 and Solana base58, and reformatting it makes it\n * unpasteable in an explorer — which is the entire remedy on offer.\n */\n transaction?: string;\n /** `keccak256(caip2 ‖ txHash)`, the same id a successful settle would print. */\n paymentId?: string;\n /**\n * Seconds to wait before retrying, already clamped to\n * {@link MAX_RETRY_AFTER_SECONDS}. Absent when the answer is not retryable.\n */\n retryAfterSeconds?: number;\n /**\n * The request reached no verdict; the credential is untouched and the SAME\n * request may be sent again. Never surface this as a payment rejection.\n */\n retryable: boolean;\n /**\n * The facilitator NAMED a reason that proves it executed nothing, so an\n * automatic replay cannot double-write.\n *\n * False for `forward_failed`, whose write may already have landed, and false\n * for an unattributed 5xx from a proxy — \"something in front answered\" is not\n * evidence that nothing ran.\n */\n safeToReplay: boolean;\n /** Raw response body, for logs. */\n body: string;\n}\n\n/** Fields every facilitator response type gained so a 503 stops looking terminal. */\nexport interface FacilitatorFailureFields {\n /** HTTP status, when the failure was transport-level rather than a verdict. */\n status?: number;\n /** The facilitator's `reason` for the refusal (see {@link WriterLeaseReason}). */\n reason?: string;\n /** The facilitator's machine-readable `error` code (see {@link FacilitatorErrorInfo.errorCode}). */\n errorCode?: string;\n /**\n * A transaction that WAS broadcast and could not be confirmed. Look it up on\n * chain; do NOT send the payment again. See {@link SETTLEMENT_UNCONFIRMED}.\n */\n transaction?: string;\n /** The payment id for that transaction, identical to the one a settle prints. */\n paymentId?: string;\n /** True when the same request may be sent again without re-signing anything. */\n retryable?: boolean;\n /** Seconds to wait before retrying, clamped to {@link MAX_RETRY_AFTER_SECONDS}. */\n retryAfterSeconds?: number;\n /** True when the facilitator provably executed nothing. */\n safeToReplay?: boolean;\n}\n\n/** A 503/429 that carries a reason known to be pre-execution. */\nexport function isReplayableLeaseReason(reason?: string): boolean {\n return REPLAYABLE_LEASE_REASONS.includes(reason as WriterLeaseReason);\n}\n\n/** A 503 whose write may already have run. Reconcile, do not re-POST. */\nexport function isAmbiguousLeaseReason(reason?: string): boolean {\n return AMBIGUOUS_LEASE_REASONS.includes(reason as WriterLeaseReason);\n}\n\n/**\n * Read `Retry-After` and clamp it.\n *\n * Tolerates a `Response`-shaped object with no `headers` at all: test doubles\n * and non-standard fetch polyfills routinely omit it, and throwing there would\n * turn a readable refusal into an unreadable crash.\n */\nexport function parseRetryAfterSeconds(response: {\n headers?: { get?: (name: string) => string | null };\n}): number | undefined {\n let raw: string | null | undefined;\n try {\n raw = response?.headers?.get?.('retry-after');\n } catch {\n return undefined;\n }\n if (raw === null || raw === undefined || raw === '') return undefined;\n const seconds = Number(raw);\n if (!Number.isFinite(seconds) || seconds < 0) return undefined;\n return Math.min(seconds, MAX_RETRY_AFTER_SECONDS);\n}\n\n/** Everything this SDK reads out of a facilitator error body. */\nexport interface ParsedFacilitatorErrorBody {\n /** The `error` code, verbatim. */\n errorCode?: string;\n /** The writer-lease `reason`. */\n reason?: string;\n /** A broadcast transaction hash, in its own chain's encoding. */\n transaction?: string;\n /** The payment id for that hash. */\n paymentId?: string;\n /**\n * The facilitator's OWN retry verdict, when it stated one.\n *\n * `undefined` on every body that does not carry the field — which is most of\n * them, so absence means \"the facilitator did not say\", never \"no\".\n */\n retryable?: boolean;\n}\n\n/** A body field is only usable when it is a non-empty string. */\nfunction stringField(source: Record<string, unknown>, key: string): string | undefined {\n const value = source[key];\n return typeof value === 'string' && value !== '' ? value : undefined;\n}\n\n/**\n * Find a broadcast transaction hash anywhere the facilitator spells one.\n *\n * All five spellings, because the endpoint and the error path disagree:\n * `{\"transaction\": \"0x…\"}`, `{\"transaction\": {\"hash\": \"0x…\"}}`, `txHash`,\n * `tx_hash`, `transaction_hash`. `settle()` already read three of them on the\n * SUCCESS path — after a consumer failed closed on an unreadable receipt and\n * revoked access to a payment that had settled — and the error path reading\n * fewer is the same defect with the stakes reversed.\n *\n * Ported from the Python SDK's `_extract_tx_hash_from_body`\n * (`uvd_x402_sdk/client.py`), which had the wider read first.\n */\nfunction transactionHashIn(source: Record<string, unknown>): string | undefined {\n const tx = source.transaction;\n if (tx && typeof tx === 'object') {\n const hash = (tx as Record<string, unknown>).hash;\n if (typeof hash === 'string' && hash !== '') return hash;\n }\n if (typeof tx === 'string' && tx !== '') return tx;\n for (const key of ['txHash', 'tx_hash', 'transaction_hash']) {\n const value = stringField(source, key);\n if (value !== undefined) return value;\n }\n return undefined;\n}\n\n/**\n * Read a JSON error body, tolerating anything that is not one.\n *\n * Exported so {@link FacilitatorErrorInfo} and `Erc8004LookupError` read the\n * SAME fields the same way. Two subtly different parses of the same body is how\n * one code path stops honouring a `retryable: false` the other one honours.\n */\nexport function parseFacilitatorErrorBody(body: string): ParsedFacilitatorErrorBody {\n let parsed: Record<string, unknown>;\n try {\n parsed = JSON.parse(body) as Record<string, unknown>;\n } catch {\n /* an HTML 503 from a load balancer is still a 503 */\n return {};\n }\n if (!parsed || typeof parsed !== 'object') return {};\n return {\n errorCode: stringField(parsed, 'error'),\n reason: stringField(parsed, 'reason'),\n transaction: transactionHashIn(parsed),\n paymentId: stringField(parsed, 'paymentId'),\n retryable: typeof parsed.retryable === 'boolean' ? parsed.retryable : undefined,\n };\n}\n\n/**\n * The facilitator said, or showed, that this refusal must not be retried.\n *\n * THREE independent signals, because the cost of missing one is a second\n * payment for the same purchase:\n *\n * 1. an explicit `retryable: false` — the facilitator answering the question;\n * 2. the named code {@link SETTLEMENT_UNCONFIRMED};\n * 3. **any 5xx body that carries a transaction hash at all.** A hash in a\n * failure means the facilitator got as far as BROADCASTING before it failed,\n * whatever it decided to call the error. This one is the general rule and it\n * holds for codes that do not exist yet.\n *\n * Signal 3 is adopted from the Python SDK, whose `_is_retryable_settle_error`\n * has carried it as the anti-double-settle guard while this SDK had only the\n * status to go on (`uvd_x402_sdk/client.py`). It is deliberately kept ALONGSIDE\n * the first two rather than replacing them: a facilitator that answers\n * `retryable: false` with no hash must still be obeyed.\n */\nfunction isDeclaredUnretryable(parsed: ParsedFacilitatorErrorBody): boolean {\n return (\n parsed.retryable === false ||\n parsed.errorCode === SETTLEMENT_UNCONFIRMED ||\n parsed.transaction !== undefined\n );\n}\n\n/**\n * This refusal reports a transaction that may already be mined.\n *\n * The caller's move is to look up `transaction` / `paymentId` on chain. Sending\n * the payment again is the double-charge.\n */\nexport function isSettlementUnconfirmed(failure: {\n errorCode?: string;\n}): boolean {\n return failure.errorCode === SETTLEMENT_UNCONFIRMED;\n}\n\n/**\n * This payment authorization was already used for another request.\n *\n * True for {@link AUTHORIZATION_ALREADY_SETTLED} and\n * {@link RECEIPT_REQUEST_CONFLICT}, on `/settle` and on `/verify` alike. Do not\n * serve the purchase again, and do not answer `402`: the buyer's payment was\n * not refused, and a new signature would pay a second time.\n */\nexport function isAuthorizationAlreadyUsed(failure: { errorCode?: string }): boolean {\n return (\n failure.errorCode === AUTHORIZATION_ALREADY_SETTLED ||\n failure.errorCode === RECEIPT_REQUEST_CONFLICT\n );\n}\n\n/**\n * This payment authorization is being settled for another request.\n *\n * `retryable` is true: the same request may be resent to learn the verdict.\n * The purchase is served only to the binding that admitted it.\n */\nexport function isAuthorizationInFlight(failure: { errorCode?: string }): boolean {\n return failure.errorCode === AUTHORIZATION_IN_FLIGHT;\n}\n\n/**\n * Turn a non-2xx facilitator response into {@link FacilitatorErrorInfo}.\n *\n * Reads the body exactly once. The `error` string keeps the historical format\n * verbatim; reformatting it would break callers that match on it.\n */\nexport async function readFacilitatorError(response: {\n status: number;\n text: () => Promise<string>;\n headers?: { get?: (name: string) => string | null };\n}): Promise<FacilitatorErrorInfo> {\n let body = '';\n try {\n body = await response.text();\n } catch {\n body = '';\n }\n const status = response.status;\n const parsed = parseFacilitatorErrorBody(body);\n const reason = parsed.reason;\n // 429 is admission control and 502/503/504 are \"no verdict\". None of them is\n // a rejection of the payment, so none of them may be reported as one.\n const transportRetryable =\n status === 429 || status === 502 || status === 503 || status === 504;\n // ...unless the facilitator SAID otherwise in the body. `settlement_unconfirmed`\n // is a 502 whose transaction was already broadcast and may be mined: retrying\n // signs a second authorization, with a fresh nonce, that the chain will\n // happily accept as another payment for the same purchase.\n //\n // Only ever DOWNGRADES. A body claiming `retryable: true` on a 402 must not\n // make this SDK resend a credential the facilitator genuinely refused, so the\n // status stays the ceiling and the body is only allowed to lower it.\n //\n // The one exception is NAMED, not read from a flag: `409\n // authorization_in_flight`. Its body says `retryable: false` because this\n // request will never get the original answer, but the verdict is still\n // coming, and resending the SAME request is how a caller without the\n // admitting binding learns it: the facilitator admits no replacement\n // payment for an admitted authorization, so the resend can only come back\n // as `authorization_already_settled` or as the original rejection.\n const inFlight = status === 409 && parsed.errorCode === AUTHORIZATION_IN_FLIGHT;\n const retryable = inFlight || (transportRetryable && !isDeclaredUnretryable(parsed));\n const retryAfterSeconds = retryable\n ? (parseRetryAfterSeconds(response) ?? DEFAULT_RETRY_AFTER_SECONDS)\n : undefined;\n // Replay only what the facilitator SAID it did not execute.\n //\n // A 429 is admission control: the request was counted, never handled. A 503\n // that names one of the pre-execution writer-lease reasons is refused in the\n // router before any signing. Everything else — an unattributed 503 from a\n // load balancer, a 502, a 504, `forward_failed` — is merely retryable: the\n // caller may resend after reconciling, but this SDK will not do it for them,\n // because \"a proxy answered\" is not evidence that nothing ran.\n //\n // Gated on `retryable` so the two can never disagree: a refusal this SDK will\n // not even retry must never be described as safe to replay automatically.\n const safeToReplay =\n retryable && (status === 429 || (status === 503 && isReplayableLeaseReason(reason)));\n\n return {\n error: `Facilitator error: ${status} - ${body}`,\n status,\n reason,\n errorCode: parsed.errorCode,\n transaction: parsed.transaction,\n paymentId: parsed.paymentId,\n retryAfterSeconds,\n retryable,\n safeToReplay,\n body,\n };\n}\n\n/** The subset of {@link FacilitatorErrorInfo} that is copied onto a response. */\nexport function failureFields(info: FacilitatorErrorInfo): Required<\n Pick<FacilitatorFailureFields, 'status' | 'retryable' | 'safeToReplay'>\n> &\n FacilitatorFailureFields {\n return {\n status: info.status,\n retryable: info.retryable,\n safeToReplay: info.safeToReplay,\n ...(info.reason !== undefined ? { reason: info.reason } : {}),\n ...(info.errorCode !== undefined ? { errorCode: info.errorCode } : {}),\n // Without these the caller is told \"do not retry\" and given nothing to do\n // instead — an error that swallows the hash is the same defect one layer up.\n ...(info.transaction !== undefined ? { transaction: info.transaction } : {}),\n ...(info.paymentId !== undefined ? { paymentId: info.paymentId } : {}),\n ...(info.retryAfterSeconds !== undefined\n ? { retryAfterSeconds: info.retryAfterSeconds }\n : {}),\n };\n}\n\n/**\n * Copy the failure fields off one response onto another.\n *\n * Used where a wrapper returns its own shape: without this the wrapper flattens\n * a `503` back into a bare failure and reintroduces, one level up, exactly the\n * ambiguity the fields exist to remove.\n */\nexport function carryFailureFields(\n source: FacilitatorFailureFields,\n): FacilitatorFailureFields {\n return {\n ...(source.status !== undefined ? { status: source.status } : {}),\n ...(source.reason !== undefined ? { reason: source.reason } : {}),\n ...(source.errorCode !== undefined ? { errorCode: source.errorCode } : {}),\n ...(source.transaction !== undefined ? { transaction: source.transaction } : {}),\n ...(source.paymentId !== undefined ? { paymentId: source.paymentId } : {}),\n ...(source.retryable !== undefined ? { retryable: source.retryable } : {}),\n ...(source.retryAfterSeconds !== undefined\n ? { retryAfterSeconds: source.retryAfterSeconds }\n : {}),\n ...(source.safeToReplay !== undefined ? { safeToReplay: source.safeToReplay } : {}),\n };\n}\n\n/** Options for {@link facilitatorFetch}. */\nexport interface FacilitatorFetchOptions {\n /** Abort the request after this many milliseconds. */\n timeoutMs: number;\n /** Extra attempts after the first. Default {@link DEFAULT_FACILITATOR_RETRIES}. */\n retries?: number;\n /**\n * Whether this particular refusal may be replayed.\n *\n * Default: only when the facilitator proved it executed nothing\n * (`info.safeToReplay`). Pass a stricter predicate on paths where even a\n * proven-safe replay is unwanted.\n */\n canReplay?: (info: FacilitatorErrorInfo) => boolean;\n /** Injected for tests. */\n fetchImpl?: typeof fetch;\n /** Injected for tests, so a retry does not really sleep. */\n sleepImpl?: (ms: number) => Promise<void>;\n}\n\nconst defaultSleep = (ms: number): Promise<void> =>\n new Promise((resolve) => setTimeout(resolve, ms));\n\n/**\n * POST/GET the facilitator, replaying a refusal that provably executed nothing.\n *\n * Returns the response plus, when it was not ok, the structured refusal — the\n * body has already been consumed to build it, so callers must not read it\n * again.\n *\n * Network errors and timeouts still THROW, exactly as before: callers already\n * have `catch` blocks that turn them into `{ success: false }`, and an\n * `AbortError` on the escrow paths triggers an on-chain reconciliation that\n * must keep firing.\n */\nexport async function facilitatorFetch(\n url: string,\n init: RequestInit,\n options: FacilitatorFetchOptions,\n): Promise<{ response: Response; error?: FacilitatorErrorInfo }> {\n const retries = options.retries ?? DEFAULT_FACILITATOR_RETRIES;\n const canReplay = options.canReplay ?? ((info: FacilitatorErrorInfo) => info.safeToReplay);\n const doFetch = options.fetchImpl ?? fetch;\n const sleep = options.sleepImpl ?? defaultSleep;\n\n let attempt = 0;\n for (;;) {\n // A fresh controller per attempt: an aborted signal stays aborted, so\n // reusing one would make every retry fail instantly.\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), options.timeoutMs);\n let response: Response;\n try {\n response = await doFetch(url, { ...init, signal: controller.signal });\n } finally {\n clearTimeout(timeoutId);\n }\n\n if (response.ok) return { response };\n\n const error = await readFacilitatorError(response);\n if (attempt >= retries || !error.retryable || !canReplay(error)) {\n return { response, error };\n }\n\n attempt += 1;\n await sleep((error.retryAfterSeconds ?? DEFAULT_RETRY_AFTER_SECONDS) * 1000);\n }\n}\n"]}
|