@dexterai/x402 1.8.2 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/dist/adapters/index.cjs +15 -3
  2. package/dist/adapters/index.cjs.map +1 -1
  3. package/dist/adapters/index.d.cts +5 -5
  4. package/dist/adapters/index.d.ts +5 -5
  5. package/dist/adapters/index.js +5 -3
  6. package/dist/adapters/index.js.map +1 -1
  7. package/dist/client/index.cjs +22 -9
  8. package/dist/client/index.cjs.map +1 -1
  9. package/dist/client/index.d.cts +6 -6
  10. package/dist/client/index.d.ts +6 -6
  11. package/dist/client/index.js +12 -9
  12. package/dist/client/index.js.map +1 -1
  13. package/dist/react/index.cjs +24 -11
  14. package/dist/react/index.cjs.map +1 -1
  15. package/dist/react/index.d.cts +4 -4
  16. package/dist/react/index.d.ts +4 -4
  17. package/dist/react/index.js +14 -11
  18. package/dist/react/index.js.map +1 -1
  19. package/dist/server/index.cjs +27 -17
  20. package/dist/server/index.cjs.map +1 -1
  21. package/dist/server/index.d.cts +2 -2
  22. package/dist/server/index.d.ts +2 -2
  23. package/dist/server/index.js +25 -15
  24. package/dist/server/index.js.map +1 -1
  25. package/dist/{solana-BeGAqPta.d.cts → solana-CfHuiW2H.d.cts} +2 -2
  26. package/dist/{solana-CQD9yMju.d.ts → solana-kZcwbUK9.d.ts} +2 -2
  27. package/dist/{types-DYLi7SuF.d.cts → types-BQvaF8lB.d.cts} +7 -5
  28. package/dist/{types-DYLi7SuF.d.ts → types-BQvaF8lB.d.ts} +7 -5
  29. package/dist/{types-B477nBpg.d.cts → types-DmqH9yD8.d.cts} +1 -1
  30. package/dist/{types-BWnUAPvD.d.ts → types-ENcnkof8.d.ts} +1 -1
  31. package/dist/utils/index.cjs.map +1 -1
  32. package/dist/utils/index.js.map +1 -1
  33. package/dist/{x402-client-Dk9q2QQF.d.cts → x402-client-BDaOwfgE.d.cts} +2 -2
  34. package/dist/{x402-client-D9b3PHai.d.ts → x402-client-DIcp-PvX.d.ts} +2 -2
  35. package/package.json +1 -1
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
19
  };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
18
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
29
 
20
30
  // src/adapters/index.ts
@@ -136,7 +146,7 @@ var SolanaAdapter = class {
136
146
  const connection = new import_web3.Connection(url, "confirmed");
137
147
  const userPubkey = new import_web3.PublicKey(wallet.publicKey.toBase58());
138
148
  const { payTo, asset, extra } = accept;
139
- const amount = accept.amount || accept.maxAmountRequired;
149
+ const amount = accept.amount ?? accept.maxAmountRequired;
140
150
  if (!amount) {
141
151
  throw new Error("Missing amount in payment requirements");
142
152
  }
@@ -374,7 +384,7 @@ var EvmAdapter = class {
374
384
  throw new Error("Wallet not connected");
375
385
  }
376
386
  const { payTo, asset, extra } = accept;
377
- const amount = accept.amount || accept.maxAmountRequired;
387
+ const amount = accept.amount ?? accept.maxAmountRequired;
378
388
  if (!amount) {
379
389
  throw new Error("Missing amount in payment requirements");
380
390
  }
@@ -402,7 +412,9 @@ var EvmAdapter = class {
402
412
  { name: "nonce", type: "bytes32" }
403
413
  ]
404
414
  };
405
- const nonce = "0x" + [...Array(32)].map(() => Math.floor(Math.random() * 256).toString(16).padStart(2, "0")).join("");
415
+ const nonceBytes = new Uint8Array(32);
416
+ (globalThis.crypto ?? (await import("crypto")).webcrypto).getRandomValues(nonceBytes);
417
+ const nonce = "0x" + [...nonceBytes].map((b) => b.toString(16).padStart(2, "0")).join("");
406
418
  const now = Math.floor(Date.now() / 1e3);
407
419
  const authorization = {
408
420
  from: wallet.address,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/adapters/index.ts","../../src/adapters/solana.ts","../../src/adapters/evm.ts"],"sourcesContent":["/**\n * Chain Adapters\n *\n * x402 v2 is designed to be chain-agnostic. Each adapter handles\n * the specifics of transaction building and signing for its chain.\n *\n * @example\n * ```typescript\n * import { createSolanaAdapter, createEvmAdapter } from '@dexterai/x402/adapters';\n *\n * const adapters = [\n * createSolanaAdapter(),\n * createEvmAdapter(),\n * ];\n *\n * // Find adapter for a network\n * const adapter = adapters.find(a => a.canHandle('eip155:8453'));\n * ```\n */\n\nimport { createSolanaAdapter as _createSolanaAdapter } from './solana';\nimport { createEvmAdapter as _createEvmAdapter } from './evm';\nimport { USDC_ADDRESSES as _USDC_ADDRESSES } from './evm';\n\n// Types\nexport type {\n ChainAdapter,\n AdapterConfig,\n SignedTransaction,\n GenericWallet,\n WalletSet,\n BalanceInfo,\n} from './types';\n\n// Solana\nexport {\n SolanaAdapter,\n createSolanaAdapter,\n isSolanaWallet,\n SOLANA_MAINNET,\n SOLANA_DEVNET,\n SOLANA_TESTNET,\n} from './solana';\nexport type { SolanaWallet } from './solana';\n\n// EVM\nexport {\n EvmAdapter,\n createEvmAdapter,\n isEvmWallet,\n BASE_MAINNET,\n BASE_SEPOLIA,\n ARBITRUM_ONE,\n POLYGON,\n OPTIMISM,\n AVALANCHE,\n SKALE_BASE,\n SKALE_BASE_SEPOLIA,\n ETHEREUM_MAINNET,\n USDC_ADDRESSES,\n} from './evm';\nexport type { EvmWallet } from './evm';\n\n/**\n * Check if an asset address is a known USDC contract (any chain).\n * Single source of truth for decimal inference in the client.\n */\nexport function isKnownUSDC(asset: string): boolean {\n // Solana mints\n if (asset === 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v') return true; // mainnet\n if (asset === '4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU') return true; // devnet\n // All EVM USDC addresses (case-insensitive for EVM)\n const lc = asset.toLowerCase();\n for (const addr of Object.values(_USDC_ADDRESSES)) {\n if (addr.toLowerCase() === lc) return true;\n }\n return false;\n}\n\n/**\n * Create all default adapters\n */\nexport function createDefaultAdapters(verbose = false) {\n return [\n _createSolanaAdapter({ verbose }),\n _createEvmAdapter({ verbose }),\n ];\n}\n\n/**\n * Find adapter that can handle a network\n */\nexport function findAdapter(\n adapters: import('./types').ChainAdapter[],\n network: string\n): import('./types').ChainAdapter | undefined {\n return adapters.find(adapter => adapter.canHandle(network));\n}\n\n\n\n","/**\n * Solana Chain Adapter\n *\n * Implements the ChainAdapter interface for Solana networks.\n * Handles transaction building, signing, and balance queries.\n */\n\nimport {\n PublicKey,\n Connection,\n TransactionMessage,\n VersionedTransaction,\n ComputeBudgetProgram,\n type TransactionInstruction,\n} from '@solana/web3.js';\nimport {\n getAssociatedTokenAddress,\n getAccount,\n createTransferCheckedInstruction,\n getMint,\n TOKEN_PROGRAM_ID,\n TOKEN_2022_PROGRAM_ID,\n} from '@solana/spl-token';\nimport type { ChainAdapter, AdapterConfig, SignedTransaction } from './types';\nimport type { PaymentAccept } from '../types';\n\n/**\n * CAIP-2 network identifiers for Solana\n */\nexport const SOLANA_MAINNET = 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp';\nexport const SOLANA_DEVNET = 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1';\nexport const SOLANA_TESTNET = 'solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z';\n\n/**\n * Default RPC URLs\n * Mainnet uses Dexter's RPC proxy for reliability and zero-config setup\n */\nconst DEFAULT_RPC_URLS: Record<string, string> = {\n [SOLANA_MAINNET]: 'https://api.dexter.cash/api/solana/rpc',\n [SOLANA_DEVNET]: 'https://api.devnet.solana.com',\n [SOLANA_TESTNET]: 'https://api.testnet.solana.com',\n};\n\n/**\n * Dexter policy-safe compute budget settings\n */\nconst DEFAULT_COMPUTE_UNIT_LIMIT = 12_000;\nconst DEFAULT_COMPUTE_UNIT_PRICE_MICROLAMPORTS = 1;\n\n/**\n * Solana wallet interface (compatible with @solana/wallet-adapter)\n */\nexport interface SolanaWallet {\n publicKey: { toBase58(): string } | null;\n signTransaction<T>(tx: T): Promise<T>;\n}\n\n/**\n * Check if an object is a valid Solana wallet\n */\nexport function isSolanaWallet(wallet: unknown): wallet is SolanaWallet {\n if (!wallet || typeof wallet !== 'object') return false;\n const w = wallet as Record<string, unknown>;\n return (\n 'publicKey' in w &&\n 'signTransaction' in w &&\n typeof w.signTransaction === 'function'\n );\n}\n\n/**\n * Solana Chain Adapter\n */\nexport class SolanaAdapter implements ChainAdapter {\n readonly name = 'Solana';\n readonly networks = [SOLANA_MAINNET, SOLANA_DEVNET, SOLANA_TESTNET];\n\n private config: AdapterConfig;\n private log: (...args: unknown[]) => void;\n\n constructor(config: AdapterConfig = {}) {\n this.config = config;\n this.log = config.verbose\n ? console.log.bind(console, '[x402:solana]')\n : () => {};\n }\n\n canHandle(network: string): boolean {\n // Handle both exact CAIP-2 and legacy formats\n if (this.networks.includes(network)) return true;\n // Legacy format support\n if (network === 'solana') return true;\n if (network === 'solana-devnet') return true;\n if (network === 'solana-testnet') return true;\n // Check if it starts with 'solana:'\n if (network.startsWith('solana:')) return true;\n return false;\n }\n\n getDefaultRpcUrl(network: string): string {\n // Check custom config first\n if (this.config.rpcUrls?.[network]) {\n return this.config.rpcUrls[network];\n }\n // Check defaults\n if (DEFAULT_RPC_URLS[network]) {\n return DEFAULT_RPC_URLS[network];\n }\n // Normalize legacy networks\n if (network === 'solana') return DEFAULT_RPC_URLS[SOLANA_MAINNET];\n if (network === 'solana-devnet') return DEFAULT_RPC_URLS[SOLANA_DEVNET];\n if (network === 'solana-testnet') return DEFAULT_RPC_URLS[SOLANA_TESTNET];\n // Default to mainnet\n return DEFAULT_RPC_URLS[SOLANA_MAINNET];\n }\n\n getAddress(wallet: unknown): string | null {\n if (!isSolanaWallet(wallet)) return null;\n return wallet.publicKey?.toBase58() ?? null;\n }\n\n isConnected(wallet: unknown): boolean {\n if (!isSolanaWallet(wallet)) return false;\n return wallet.publicKey !== null;\n }\n\n async getBalance(\n accept: PaymentAccept,\n wallet: unknown,\n rpcUrl?: string\n ): Promise<number> {\n if (!isSolanaWallet(wallet) || !wallet.publicKey) {\n return 0;\n }\n\n const url = rpcUrl || this.getDefaultRpcUrl(accept.network);\n const connection = new Connection(url, 'confirmed');\n const userPubkey = new PublicKey(wallet.publicKey.toBase58());\n const mintPubkey = new PublicKey(accept.asset);\n\n try {\n // Determine token program\n const mintInfo = await connection.getAccountInfo(mintPubkey, 'confirmed');\n const programId =\n mintInfo?.owner.toBase58() === TOKEN_2022_PROGRAM_ID.toBase58()\n ? TOKEN_2022_PROGRAM_ID\n : TOKEN_PROGRAM_ID;\n\n const ata = await getAssociatedTokenAddress(\n mintPubkey,\n userPubkey,\n false,\n programId\n );\n\n const account = await getAccount(connection, ata, undefined, programId);\n const decimals = accept.extra?.decimals ?? 6;\n return Number(account.amount) / Math.pow(10, decimals);\n } catch {\n // Token account doesn't exist\n return 0;\n }\n }\n\n async buildTransaction(\n accept: PaymentAccept,\n wallet: unknown,\n rpcUrl?: string\n ): Promise<SignedTransaction> {\n if (!isSolanaWallet(wallet)) {\n throw new Error('Invalid Solana wallet');\n }\n if (!wallet.publicKey) {\n throw new Error('Wallet not connected');\n }\n\n const url = rpcUrl || this.getDefaultRpcUrl(accept.network);\n const connection = new Connection(url, 'confirmed');\n const userPubkey = new PublicKey(wallet.publicKey.toBase58());\n\n // Extract required fields (amount or maxAmountRequired for x402 spec compatibility)\n const { payTo, asset, extra } = accept;\n const amount = accept.amount || accept.maxAmountRequired;\n if (!amount) {\n throw new Error('Missing amount in payment requirements');\n }\n\n if (!extra?.feePayer) {\n throw new Error('Missing feePayer in payment requirements');\n }\n // Note: decimals is optional - we fetch from mint on-chain if not provided\n\n const feePayerPubkey = new PublicKey(extra.feePayer);\n const mintPubkey = new PublicKey(asset);\n const destinationPubkey = new PublicKey(payTo);\n\n this.log('Building transaction:', {\n from: userPubkey.toBase58(),\n to: payTo,\n amount,\n asset,\n feePayer: extra.feePayer,\n });\n\n // Build instructions\n const instructions: TransactionInstruction[] = [];\n\n // 1. ComputeBudget: Set compute unit limit\n instructions.push(\n ComputeBudgetProgram.setComputeUnitLimit({\n units: DEFAULT_COMPUTE_UNIT_LIMIT,\n })\n );\n\n // 2. ComputeBudget: Set compute unit price\n instructions.push(\n ComputeBudgetProgram.setComputeUnitPrice({\n microLamports: DEFAULT_COMPUTE_UNIT_PRICE_MICROLAMPORTS,\n })\n );\n\n // 3. Determine token program\n const mintInfo = await connection.getAccountInfo(mintPubkey, 'confirmed');\n if (!mintInfo) {\n throw new Error(`Token mint ${asset} not found`);\n }\n\n const programId =\n mintInfo.owner.toBase58() === TOKEN_2022_PROGRAM_ID.toBase58()\n ? TOKEN_2022_PROGRAM_ID\n : TOKEN_PROGRAM_ID;\n\n // Fetch mint to get decimals (required for TransferChecked)\n const mint = await getMint(connection, mintPubkey, undefined, programId);\n if (typeof extra?.decimals === 'number' && mint.decimals !== extra.decimals) {\n this.log(\n `Decimals mismatch: requirements say ${extra.decimals}, mint says ${mint.decimals}`\n );\n }\n\n // Derive Associated Token Accounts\n const sourceAta = await getAssociatedTokenAddress(\n mintPubkey,\n userPubkey,\n false,\n programId\n );\n const destinationAta = await getAssociatedTokenAddress(\n mintPubkey,\n destinationPubkey,\n false,\n programId\n );\n\n // Verify source ATA exists\n const sourceAtaInfo = await connection.getAccountInfo(sourceAta, 'confirmed');\n if (!sourceAtaInfo) {\n throw new Error(\n `No token account found for ${asset}. Please ensure you have USDC in your wallet.`\n );\n }\n\n // Verify destination ATA exists\n const destAtaInfo = await connection.getAccountInfo(destinationAta, 'confirmed');\n if (!destAtaInfo) {\n throw new Error(\n `Seller token account not found. The seller (${payTo}) must have a USDC account.`\n );\n }\n\n // 4. TransferChecked instruction\n const amountBigInt = BigInt(amount);\n instructions.push(\n createTransferCheckedInstruction(\n sourceAta,\n mintPubkey,\n destinationAta,\n userPubkey,\n amountBigInt,\n mint.decimals,\n [],\n programId\n )\n );\n\n // Get recent blockhash\n const { blockhash } = await connection.getLatestBlockhash('confirmed');\n\n // Compile to V0 message (feePayer is facilitator)\n const message = new TransactionMessage({\n payerKey: feePayerPubkey,\n recentBlockhash: blockhash,\n instructions,\n }).compileToV0Message();\n\n // Create and sign transaction\n const transaction = new VersionedTransaction(message);\n const signedTx = await wallet.signTransaction(transaction);\n\n this.log('Transaction signed successfully');\n\n return {\n serialized: Buffer.from(signedTx.serialize()).toString('base64'),\n };\n }\n}\n\n/**\n * Create a Solana adapter instance\n */\nexport function createSolanaAdapter(config?: AdapterConfig): SolanaAdapter {\n return new SolanaAdapter(config);\n}\n\n\n\n","/**\n * EVM Chain Adapter\n *\n * Implements the ChainAdapter interface for EVM networks (Base, Ethereum, Arbitrum, etc.)\n * Uses EIP-712 typed data signing for x402 v2 payments.\n */\n\nimport type { ChainAdapter, AdapterConfig, SignedTransaction } from './types';\nimport type { PaymentAccept } from '../types';\n\n/**\n * CAIP-2 network identifiers for EVM chains.\n * Mirrors dexter-facilitator/src/config/chains.ts — update both when adding chains.\n */\nexport const BASE_MAINNET = 'eip155:8453';\nexport const BASE_SEPOLIA = 'eip155:84532';\nexport const ARBITRUM_ONE = 'eip155:42161';\nexport const POLYGON = 'eip155:137';\nexport const OPTIMISM = 'eip155:10';\nexport const AVALANCHE = 'eip155:43114';\nexport const SKALE_BASE = 'eip155:1187947933';\nexport const SKALE_BASE_SEPOLIA = 'eip155:324705682';\n\n/** @deprecated Not supported by the Dexter facilitator. Use BASE_MAINNET for EVM payments. */\nexport const ETHEREUM_MAINNET = 'eip155:1';\n\n/**\n * Chain IDs by CAIP-2 network\n */\nconst CHAIN_IDS: Record<string, number> = {\n [BASE_MAINNET]: 8453,\n [BASE_SEPOLIA]: 84532,\n [ARBITRUM_ONE]: 42161,\n [POLYGON]: 137,\n [OPTIMISM]: 10,\n [AVALANCHE]: 43114,\n [SKALE_BASE]: 1187947933,\n [SKALE_BASE_SEPOLIA]: 324705682,\n [ETHEREUM_MAINNET]: 1,\n};\n\n/**\n * Default RPC URLs.\n * Base mainnet uses Dexter's RPC proxy for reliability and zero-config setup.\n * Source of truth: dexter-facilitator/src/config/chains.ts\n */\nconst DEFAULT_RPC_URLS: Record<string, string> = {\n [BASE_MAINNET]: 'https://api.dexter.cash/api/base/rpc',\n [BASE_SEPOLIA]: 'https://sepolia.base.org',\n [ARBITRUM_ONE]: 'https://arb1.arbitrum.io/rpc',\n [POLYGON]: 'https://polygon-rpc.com',\n [OPTIMISM]: 'https://mainnet.optimism.io',\n [AVALANCHE]: 'https://api.avax.network/ext/bc/C/rpc',\n [SKALE_BASE]: 'https://skale-base.skalenodes.com/v1/base',\n [SKALE_BASE_SEPOLIA]: 'https://base-sepolia-testnet.skalenodes.com/v1/jubilant-horrible-ancha',\n [ETHEREUM_MAINNET]: 'https://eth.llamarpc.com',\n};\n\n/**\n * USDC contract addresses by chain.\n * Source of truth: dexter-facilitator/src/config/chains.ts\n */\nexport const USDC_ADDRESSES: Record<string, string> = {\n [BASE_MAINNET]: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\n [BASE_SEPOLIA]: '0x036CbD53842c5426634e7929541eC2318f3dCF7e',\n [ARBITRUM_ONE]: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',\n [POLYGON]: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',\n [OPTIMISM]: '0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85',\n [AVALANCHE]: '0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E',\n [SKALE_BASE]: '0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20',\n [SKALE_BASE_SEPOLIA]: '0x2e08028E3C4c2356572E096d8EF835cD5C6030bD',\n [ETHEREUM_MAINNET]: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',\n};\n\n/**\n * EVM wallet interface (compatible with wagmi, ethers, viem)\n */\nexport interface EvmWallet {\n /** Wallet address */\n address: string;\n /** Chain ID currently connected to */\n chainId?: number;\n /**\n * Sign typed data (EIP-712)\n * This is the primary signing method for x402 EVM payments\n */\n signTypedData?(params: {\n domain: Record<string, unknown>;\n types: Record<string, unknown[]>;\n primaryType: string;\n message: Record<string, unknown>;\n }): Promise<string>;\n /**\n * Alternative: Send transaction directly\n * Used if signTypedData is not available\n */\n sendTransaction?(params: {\n to: string;\n data: string;\n value?: bigint;\n }): Promise<string>;\n}\n\n/**\n * Check if an object is a valid EVM wallet\n */\nexport function isEvmWallet(wallet: unknown): wallet is EvmWallet {\n if (!wallet || typeof wallet !== 'object') return false;\n const w = wallet as Record<string, unknown>;\n return (\n 'address' in w &&\n typeof w.address === 'string' &&\n w.address.startsWith('0x')\n );\n}\n\n// ERC20 balanceOf function selector: 0x70a08231\n\n/**\n * EVM Chain Adapter\n */\nexport class EvmAdapter implements ChainAdapter {\n readonly name = 'EVM';\n readonly networks = [BASE_MAINNET, BASE_SEPOLIA, ETHEREUM_MAINNET, ARBITRUM_ONE];\n\n private config: AdapterConfig;\n private log: (...args: unknown[]) => void;\n\n constructor(config: AdapterConfig = {}) {\n this.config = config;\n this.log = config.verbose\n ? console.log.bind(console, '[x402:evm]')\n : () => {};\n }\n\n canHandle(network: string): boolean {\n // Handle exact CAIP-2\n if (this.networks.includes(network)) return true;\n // Legacy format\n if (network === 'base') return true;\n if (network === 'ethereum') return true;\n if (network === 'arbitrum') return true;\n // Check if it starts with 'eip155:'\n if (network.startsWith('eip155:')) return true;\n return false;\n }\n\n getDefaultRpcUrl(network: string): string {\n if (this.config.rpcUrls?.[network]) {\n return this.config.rpcUrls[network];\n }\n if (DEFAULT_RPC_URLS[network]) {\n return DEFAULT_RPC_URLS[network];\n }\n // Normalize legacy\n if (network === 'base') return DEFAULT_RPC_URLS[BASE_MAINNET];\n if (network === 'ethereum') return DEFAULT_RPC_URLS[ETHEREUM_MAINNET];\n if (network === 'arbitrum') return DEFAULT_RPC_URLS[ARBITRUM_ONE];\n return DEFAULT_RPC_URLS[BASE_MAINNET];\n }\n\n getAddress(wallet: unknown): string | null {\n if (!isEvmWallet(wallet)) return null;\n return wallet.address;\n }\n\n isConnected(wallet: unknown): boolean {\n if (!isEvmWallet(wallet)) return false;\n return !!wallet.address;\n }\n\n private getChainId(network: string): number {\n if (CHAIN_IDS[network]) return CHAIN_IDS[network];\n // Try to extract from CAIP-2\n if (network.startsWith('eip155:')) {\n const chainIdStr = network.split(':')[1];\n return parseInt(chainIdStr, 10);\n }\n // Defaults\n if (network === 'base') return 8453;\n if (network === 'ethereum') return 1;\n if (network === 'arbitrum') return 42161;\n return 8453; // Default to Base\n }\n\n async getBalance(\n accept: PaymentAccept,\n wallet: unknown,\n rpcUrl?: string\n ): Promise<number> {\n if (!isEvmWallet(wallet) || !wallet.address) {\n return 0;\n }\n\n const url = rpcUrl || this.getDefaultRpcUrl(accept.network);\n\n try {\n // Use eth_call to check ERC20 balance\n const data = this.encodeBalanceOf(wallet.address);\n const response = 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_call',\n params: [\n {\n to: accept.asset,\n data,\n },\n 'latest',\n ],\n }),\n });\n\n const result = (await response.json()) as { error?: unknown; result?: string };\n if (result.error || !result.result) {\n return 0;\n }\n\n const balance = BigInt(result.result);\n const decimals = accept.extra?.decimals ?? 6;\n return Number(balance) / Math.pow(10, decimals);\n } catch {\n return 0;\n }\n }\n\n private encodeBalanceOf(address: string): string {\n // Function selector for balanceOf(address)\n const selector = '0x70a08231';\n // Pad address to 32 bytes\n const paddedAddress = address.slice(2).toLowerCase().padStart(64, '0');\n return selector + paddedAddress;\n }\n\n async buildTransaction(\n accept: PaymentAccept,\n wallet: unknown,\n _rpcUrl?: string\n ): Promise<SignedTransaction> {\n if (!isEvmWallet(wallet)) {\n throw new Error('Invalid EVM wallet');\n }\n if (!wallet.address) {\n throw new Error('Wallet not connected');\n }\n\n const { payTo, asset, extra } = accept;\n const amount = accept.amount || accept.maxAmountRequired;\n if (!amount) {\n throw new Error('Missing amount in payment requirements');\n }\n\n this.log('Building EVM transaction:', {\n from: wallet.address,\n to: payTo,\n amount,\n asset,\n network: accept.network,\n });\n\n // For x402 v2 EVM payments, we use EIP-712 typed data signing\n // The facilitator will execute the transfer on behalf of the user\n\n const chainId = this.getChainId(accept.network);\n\n // Build the EIP-712 typed data\n // This matches what Dexter's facilitator expects\n const domain = {\n name: extra?.name ?? 'USD Coin',\n version: extra?.version ?? '2',\n chainId: BigInt(chainId),\n verifyingContract: asset as `0x${string}`,\n };\n\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 // Generate a random nonce (32 bytes hex)\n const nonce = '0x' + [...Array(32)]\n .map(() => Math.floor(Math.random() * 256).toString(16).padStart(2, '0'))\n .join('') as `0x${string}`;\n\n const now = Math.floor(Date.now() / 1000);\n \n // Authorization object - values as strings for JSON, BigInts for signing\n const authorization = {\n from: wallet.address,\n to: payTo,\n value: amount, // string\n validAfter: String(now - 600), // 10 minutes before (matching upstream)\n validBefore: String(now + (accept.maxTimeoutSeconds || 60)),\n nonce,\n };\n\n // Message for signing uses BigInt values\n const message = {\n from: wallet.address,\n to: payTo,\n value: BigInt(amount),\n validAfter: BigInt(now - 600),\n validBefore: BigInt(now + (accept.maxTimeoutSeconds || 60)),\n nonce,\n };\n\n if (!wallet.signTypedData) {\n throw new Error('Wallet does not support signTypedData (EIP-712)');\n }\n\n const signature = await wallet.signTypedData({\n domain: domain as Record<string, unknown>,\n types: types as Record<string, unknown[]>,\n primaryType: 'TransferWithAuthorization',\n message: message as Record<string, unknown>,\n });\n\n this.log('EIP-712 signature obtained');\n\n // Payload structure matches upstream @x402/evm exactly\n const payload = {\n authorization,\n signature,\n };\n\n return {\n serialized: JSON.stringify(payload),\n signature,\n };\n }\n}\n\n/**\n * Create an EVM adapter instance\n */\nexport function createEvmAdapter(config?: AdapterConfig): EvmAdapter {\n return new EvmAdapter(config);\n}\n\n"],"mappings":"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","names":["DEFAULT_RPC_URLS"]}
1
+ {"version":3,"sources":["../../src/adapters/index.ts","../../src/adapters/solana.ts","../../src/adapters/evm.ts"],"sourcesContent":["/**\n * Chain Adapters\n *\n * x402 v2 is designed to be chain-agnostic. Each adapter handles\n * the specifics of transaction building and signing for its chain.\n *\n * @example\n * ```typescript\n * import { createSolanaAdapter, createEvmAdapter } from '@dexterai/x402/adapters';\n *\n * const adapters = [\n * createSolanaAdapter(),\n * createEvmAdapter(),\n * ];\n *\n * // Find adapter for a network\n * const adapter = adapters.find(a => a.canHandle('eip155:8453'));\n * ```\n */\n\nimport { createSolanaAdapter as _createSolanaAdapter } from './solana';\nimport { createEvmAdapter as _createEvmAdapter } from './evm';\nimport { USDC_ADDRESSES as _USDC_ADDRESSES } from './evm';\n\n// Types\nexport type {\n ChainAdapter,\n AdapterConfig,\n SignedTransaction,\n GenericWallet,\n WalletSet,\n BalanceInfo,\n} from './types';\n\n// Solana\nexport {\n SolanaAdapter,\n createSolanaAdapter,\n isSolanaWallet,\n SOLANA_MAINNET,\n SOLANA_DEVNET,\n SOLANA_TESTNET,\n} from './solana';\nexport type { SolanaWallet } from './solana';\n\n// EVM\nexport {\n EvmAdapter,\n createEvmAdapter,\n isEvmWallet,\n BASE_MAINNET,\n BASE_SEPOLIA,\n ARBITRUM_ONE,\n POLYGON,\n OPTIMISM,\n AVALANCHE,\n SKALE_BASE,\n SKALE_BASE_SEPOLIA,\n ETHEREUM_MAINNET,\n USDC_ADDRESSES,\n} from './evm';\nexport type { EvmWallet } from './evm';\n\n/**\n * Check if an asset address is a known USDC contract (any chain).\n * Single source of truth for decimal inference in the client.\n */\nexport function isKnownUSDC(asset: string): boolean {\n // Solana mints\n if (asset === 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v') return true; // mainnet\n if (asset === '4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU') return true; // devnet\n // All EVM USDC addresses (case-insensitive for EVM)\n const lc = asset.toLowerCase();\n for (const addr of Object.values(_USDC_ADDRESSES)) {\n if (addr.toLowerCase() === lc) return true;\n }\n return false;\n}\n\n/**\n * Create all default adapters\n */\nexport function createDefaultAdapters(verbose = false) {\n return [\n _createSolanaAdapter({ verbose }),\n _createEvmAdapter({ verbose }),\n ];\n}\n\n/**\n * Find adapter that can handle a network\n */\nexport function findAdapter(\n adapters: import('./types').ChainAdapter[],\n network: string\n): import('./types').ChainAdapter | undefined {\n return adapters.find(adapter => adapter.canHandle(network));\n}\n\n\n\n","/**\n * Solana Chain Adapter\n *\n * Implements the ChainAdapter interface for Solana networks.\n * Handles transaction building, signing, and balance queries.\n */\n\nimport {\n PublicKey,\n Connection,\n TransactionMessage,\n VersionedTransaction,\n ComputeBudgetProgram,\n type TransactionInstruction,\n} from '@solana/web3.js';\nimport {\n getAssociatedTokenAddress,\n getAccount,\n createTransferCheckedInstruction,\n getMint,\n TOKEN_PROGRAM_ID,\n TOKEN_2022_PROGRAM_ID,\n} from '@solana/spl-token';\nimport type { ChainAdapter, AdapterConfig, SignedTransaction } from './types';\nimport type { PaymentAccept } from '../types';\n\n/**\n * CAIP-2 network identifiers for Solana\n */\nexport const SOLANA_MAINNET = 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp';\nexport const SOLANA_DEVNET = 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1';\nexport const SOLANA_TESTNET = 'solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z';\n\n/**\n * Default RPC URLs\n * Mainnet uses Dexter's RPC proxy for reliability and zero-config setup\n */\nconst DEFAULT_RPC_URLS: Record<string, string> = {\n [SOLANA_MAINNET]: 'https://api.dexter.cash/api/solana/rpc',\n [SOLANA_DEVNET]: 'https://api.devnet.solana.com',\n [SOLANA_TESTNET]: 'https://api.testnet.solana.com',\n};\n\n/**\n * Dexter policy-safe compute budget settings\n */\nconst DEFAULT_COMPUTE_UNIT_LIMIT = 12_000;\nconst DEFAULT_COMPUTE_UNIT_PRICE_MICROLAMPORTS = 1;\n\n/**\n * Solana wallet interface (compatible with @solana/wallet-adapter)\n */\nexport interface SolanaWallet {\n publicKey: { toBase58(): string } | null;\n signTransaction<T>(tx: T): Promise<T>;\n}\n\n/**\n * Check if an object is a valid Solana wallet\n */\nexport function isSolanaWallet(wallet: unknown): wallet is SolanaWallet {\n if (!wallet || typeof wallet !== 'object') return false;\n const w = wallet as Record<string, unknown>;\n return (\n 'publicKey' in w &&\n 'signTransaction' in w &&\n typeof w.signTransaction === 'function'\n );\n}\n\n/**\n * Solana Chain Adapter\n */\nexport class SolanaAdapter implements ChainAdapter {\n readonly name = 'Solana';\n readonly networks = [SOLANA_MAINNET, SOLANA_DEVNET, SOLANA_TESTNET];\n\n private config: AdapterConfig;\n private log: (...args: unknown[]) => void;\n\n constructor(config: AdapterConfig = {}) {\n this.config = config;\n this.log = config.verbose\n ? console.log.bind(console, '[x402:solana]')\n : () => {};\n }\n\n canHandle(network: string): boolean {\n // Handle both exact CAIP-2 and legacy formats\n if (this.networks.includes(network)) return true;\n // Legacy format support\n if (network === 'solana') return true;\n if (network === 'solana-devnet') return true;\n if (network === 'solana-testnet') return true;\n // Check if it starts with 'solana:'\n if (network.startsWith('solana:')) return true;\n return false;\n }\n\n getDefaultRpcUrl(network: string): string {\n // Check custom config first\n if (this.config.rpcUrls?.[network]) {\n return this.config.rpcUrls[network];\n }\n // Check defaults\n if (DEFAULT_RPC_URLS[network]) {\n return DEFAULT_RPC_URLS[network];\n }\n // Normalize legacy networks\n if (network === 'solana') return DEFAULT_RPC_URLS[SOLANA_MAINNET];\n if (network === 'solana-devnet') return DEFAULT_RPC_URLS[SOLANA_DEVNET];\n if (network === 'solana-testnet') return DEFAULT_RPC_URLS[SOLANA_TESTNET];\n // Default to mainnet\n return DEFAULT_RPC_URLS[SOLANA_MAINNET];\n }\n\n getAddress(wallet: unknown): string | null {\n if (!isSolanaWallet(wallet)) return null;\n return wallet.publicKey?.toBase58() ?? null;\n }\n\n isConnected(wallet: unknown): boolean {\n if (!isSolanaWallet(wallet)) return false;\n return wallet.publicKey !== null;\n }\n\n async getBalance(\n accept: PaymentAccept,\n wallet: unknown,\n rpcUrl?: string\n ): Promise<number> {\n if (!isSolanaWallet(wallet) || !wallet.publicKey) {\n return 0;\n }\n\n const url = rpcUrl || this.getDefaultRpcUrl(accept.network);\n const connection = new Connection(url, 'confirmed');\n const userPubkey = new PublicKey(wallet.publicKey.toBase58());\n const mintPubkey = new PublicKey(accept.asset);\n\n try {\n // Determine token program\n const mintInfo = await connection.getAccountInfo(mintPubkey, 'confirmed');\n const programId =\n mintInfo?.owner.toBase58() === TOKEN_2022_PROGRAM_ID.toBase58()\n ? TOKEN_2022_PROGRAM_ID\n : TOKEN_PROGRAM_ID;\n\n const ata = await getAssociatedTokenAddress(\n mintPubkey,\n userPubkey,\n false,\n programId\n );\n\n const account = await getAccount(connection, ata, undefined, programId);\n const decimals = accept.extra?.decimals ?? 6;\n return Number(account.amount) / Math.pow(10, decimals);\n } catch {\n // Token account doesn't exist\n return 0;\n }\n }\n\n async buildTransaction(\n accept: PaymentAccept,\n wallet: unknown,\n rpcUrl?: string\n ): Promise<SignedTransaction> {\n if (!isSolanaWallet(wallet)) {\n throw new Error('Invalid Solana wallet');\n }\n if (!wallet.publicKey) {\n throw new Error('Wallet not connected');\n }\n\n const url = rpcUrl || this.getDefaultRpcUrl(accept.network);\n const connection = new Connection(url, 'confirmed');\n const userPubkey = new PublicKey(wallet.publicKey.toBase58());\n\n // Extract required fields — amount is the v2 spec field, maxAmountRequired is v1 fallback\n const { payTo, asset, extra } = accept;\n const amount = accept.amount ?? accept.maxAmountRequired;\n if (!amount) {\n throw new Error('Missing amount in payment requirements');\n }\n\n if (!extra?.feePayer) {\n throw new Error('Missing feePayer in payment requirements');\n }\n // Note: decimals is optional - we fetch from mint on-chain if not provided\n\n const feePayerPubkey = new PublicKey(extra.feePayer);\n const mintPubkey = new PublicKey(asset);\n const destinationPubkey = new PublicKey(payTo);\n\n this.log('Building transaction:', {\n from: userPubkey.toBase58(),\n to: payTo,\n amount,\n asset,\n feePayer: extra.feePayer,\n });\n\n // Build instructions\n const instructions: TransactionInstruction[] = [];\n\n // 1. ComputeBudget: Set compute unit limit\n instructions.push(\n ComputeBudgetProgram.setComputeUnitLimit({\n units: DEFAULT_COMPUTE_UNIT_LIMIT,\n })\n );\n\n // 2. ComputeBudget: Set compute unit price\n instructions.push(\n ComputeBudgetProgram.setComputeUnitPrice({\n microLamports: DEFAULT_COMPUTE_UNIT_PRICE_MICROLAMPORTS,\n })\n );\n\n // 3. Determine token program\n const mintInfo = await connection.getAccountInfo(mintPubkey, 'confirmed');\n if (!mintInfo) {\n throw new Error(`Token mint ${asset} not found`);\n }\n\n const programId =\n mintInfo.owner.toBase58() === TOKEN_2022_PROGRAM_ID.toBase58()\n ? TOKEN_2022_PROGRAM_ID\n : TOKEN_PROGRAM_ID;\n\n // Fetch mint to get decimals (required for TransferChecked)\n const mint = await getMint(connection, mintPubkey, undefined, programId);\n if (typeof extra?.decimals === 'number' && mint.decimals !== extra.decimals) {\n this.log(\n `Decimals mismatch: requirements say ${extra.decimals}, mint says ${mint.decimals}`\n );\n }\n\n // Derive Associated Token Accounts\n const sourceAta = await getAssociatedTokenAddress(\n mintPubkey,\n userPubkey,\n false,\n programId\n );\n const destinationAta = await getAssociatedTokenAddress(\n mintPubkey,\n destinationPubkey,\n false,\n programId\n );\n\n // Verify source ATA exists\n const sourceAtaInfo = await connection.getAccountInfo(sourceAta, 'confirmed');\n if (!sourceAtaInfo) {\n throw new Error(\n `No token account found for ${asset}. Please ensure you have USDC in your wallet.`\n );\n }\n\n // Verify destination ATA exists\n const destAtaInfo = await connection.getAccountInfo(destinationAta, 'confirmed');\n if (!destAtaInfo) {\n throw new Error(\n `Seller token account not found. The seller (${payTo}) must have a USDC account.`\n );\n }\n\n // 4. TransferChecked instruction\n const amountBigInt = BigInt(amount);\n instructions.push(\n createTransferCheckedInstruction(\n sourceAta,\n mintPubkey,\n destinationAta,\n userPubkey,\n amountBigInt,\n mint.decimals,\n [],\n programId\n )\n );\n\n // Get recent blockhash\n const { blockhash } = await connection.getLatestBlockhash('confirmed');\n\n // Compile to V0 message (feePayer is facilitator)\n const message = new TransactionMessage({\n payerKey: feePayerPubkey,\n recentBlockhash: blockhash,\n instructions,\n }).compileToV0Message();\n\n // Create and sign transaction\n const transaction = new VersionedTransaction(message);\n const signedTx = await wallet.signTransaction(transaction);\n\n this.log('Transaction signed successfully');\n\n return {\n serialized: Buffer.from(signedTx.serialize()).toString('base64'),\n };\n }\n}\n\n/**\n * Create a Solana adapter instance\n */\nexport function createSolanaAdapter(config?: AdapterConfig): SolanaAdapter {\n return new SolanaAdapter(config);\n}\n\n\n\n","/**\n * EVM Chain Adapter\n *\n * Implements the ChainAdapter interface for EVM networks (Base, Ethereum, Arbitrum, etc.)\n * Uses EIP-712 typed data signing for x402 v2 payments.\n */\n\nimport type { ChainAdapter, AdapterConfig, SignedTransaction } from './types';\nimport type { PaymentAccept } from '../types';\n\n/**\n * CAIP-2 network identifiers for EVM chains.\n * Mirrors dexter-facilitator/src/config/chains.ts — update both when adding chains.\n */\nexport const BASE_MAINNET = 'eip155:8453';\nexport const BASE_SEPOLIA = 'eip155:84532';\nexport const ARBITRUM_ONE = 'eip155:42161';\nexport const POLYGON = 'eip155:137';\nexport const OPTIMISM = 'eip155:10';\nexport const AVALANCHE = 'eip155:43114';\nexport const SKALE_BASE = 'eip155:1187947933';\nexport const SKALE_BASE_SEPOLIA = 'eip155:324705682';\n\n/** @deprecated Not supported by the Dexter facilitator. Use BASE_MAINNET for EVM payments. */\nexport const ETHEREUM_MAINNET = 'eip155:1';\n\n/**\n * Chain IDs by CAIP-2 network\n */\nconst CHAIN_IDS: Record<string, number> = {\n [BASE_MAINNET]: 8453,\n [BASE_SEPOLIA]: 84532,\n [ARBITRUM_ONE]: 42161,\n [POLYGON]: 137,\n [OPTIMISM]: 10,\n [AVALANCHE]: 43114,\n [SKALE_BASE]: 1187947933,\n [SKALE_BASE_SEPOLIA]: 324705682,\n [ETHEREUM_MAINNET]: 1,\n};\n\n/**\n * Default RPC URLs.\n * Base mainnet uses Dexter's RPC proxy for reliability and zero-config setup.\n * Source of truth: dexter-facilitator/src/config/chains.ts\n */\nconst DEFAULT_RPC_URLS: Record<string, string> = {\n [BASE_MAINNET]: 'https://api.dexter.cash/api/base/rpc',\n [BASE_SEPOLIA]: 'https://sepolia.base.org',\n [ARBITRUM_ONE]: 'https://arb1.arbitrum.io/rpc',\n [POLYGON]: 'https://polygon-rpc.com',\n [OPTIMISM]: 'https://mainnet.optimism.io',\n [AVALANCHE]: 'https://api.avax.network/ext/bc/C/rpc',\n [SKALE_BASE]: 'https://skale-base.skalenodes.com/v1/base',\n [SKALE_BASE_SEPOLIA]: 'https://base-sepolia-testnet.skalenodes.com/v1/jubilant-horrible-ancha',\n [ETHEREUM_MAINNET]: 'https://eth.llamarpc.com',\n};\n\n/**\n * USDC contract addresses by chain.\n * Source of truth: dexter-facilitator/src/config/chains.ts\n */\nexport const USDC_ADDRESSES: Record<string, string> = {\n [BASE_MAINNET]: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\n [BASE_SEPOLIA]: '0x036CbD53842c5426634e7929541eC2318f3dCF7e',\n [ARBITRUM_ONE]: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',\n [POLYGON]: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',\n [OPTIMISM]: '0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85',\n [AVALANCHE]: '0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E',\n [SKALE_BASE]: '0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20',\n [SKALE_BASE_SEPOLIA]: '0x2e08028E3C4c2356572E096d8EF835cD5C6030bD',\n [ETHEREUM_MAINNET]: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',\n};\n\n/**\n * EVM wallet interface (compatible with wagmi, ethers, viem)\n */\nexport interface EvmWallet {\n /** Wallet address */\n address: string;\n /** Chain ID currently connected to */\n chainId?: number;\n /**\n * Sign typed data (EIP-712)\n * This is the primary signing method for x402 EVM payments\n */\n signTypedData?(params: {\n domain: Record<string, unknown>;\n types: Record<string, unknown[]>;\n primaryType: string;\n message: Record<string, unknown>;\n }): Promise<string>;\n /**\n * Alternative: Send transaction directly\n * Used if signTypedData is not available\n */\n sendTransaction?(params: {\n to: string;\n data: string;\n value?: bigint;\n }): Promise<string>;\n}\n\n/**\n * Check if an object is a valid EVM wallet\n */\nexport function isEvmWallet(wallet: unknown): wallet is EvmWallet {\n if (!wallet || typeof wallet !== 'object') return false;\n const w = wallet as Record<string, unknown>;\n return (\n 'address' in w &&\n typeof w.address === 'string' &&\n w.address.startsWith('0x')\n );\n}\n\n// ERC20 balanceOf function selector: 0x70a08231\n\n/**\n * EVM Chain Adapter\n */\nexport class EvmAdapter implements ChainAdapter {\n readonly name = 'EVM';\n readonly networks = [BASE_MAINNET, BASE_SEPOLIA, ETHEREUM_MAINNET, ARBITRUM_ONE];\n\n private config: AdapterConfig;\n private log: (...args: unknown[]) => void;\n\n constructor(config: AdapterConfig = {}) {\n this.config = config;\n this.log = config.verbose\n ? console.log.bind(console, '[x402:evm]')\n : () => {};\n }\n\n canHandle(network: string): boolean {\n // Handle exact CAIP-2\n if (this.networks.includes(network)) return true;\n // Legacy format\n if (network === 'base') return true;\n if (network === 'ethereum') return true;\n if (network === 'arbitrum') return true;\n // Check if it starts with 'eip155:'\n if (network.startsWith('eip155:')) return true;\n return false;\n }\n\n getDefaultRpcUrl(network: string): string {\n if (this.config.rpcUrls?.[network]) {\n return this.config.rpcUrls[network];\n }\n if (DEFAULT_RPC_URLS[network]) {\n return DEFAULT_RPC_URLS[network];\n }\n // Normalize legacy\n if (network === 'base') return DEFAULT_RPC_URLS[BASE_MAINNET];\n if (network === 'ethereum') return DEFAULT_RPC_URLS[ETHEREUM_MAINNET];\n if (network === 'arbitrum') return DEFAULT_RPC_URLS[ARBITRUM_ONE];\n return DEFAULT_RPC_URLS[BASE_MAINNET];\n }\n\n getAddress(wallet: unknown): string | null {\n if (!isEvmWallet(wallet)) return null;\n return wallet.address;\n }\n\n isConnected(wallet: unknown): boolean {\n if (!isEvmWallet(wallet)) return false;\n return !!wallet.address;\n }\n\n private getChainId(network: string): number {\n if (CHAIN_IDS[network]) return CHAIN_IDS[network];\n // Try to extract from CAIP-2\n if (network.startsWith('eip155:')) {\n const chainIdStr = network.split(':')[1];\n return parseInt(chainIdStr, 10);\n }\n // Defaults\n if (network === 'base') return 8453;\n if (network === 'ethereum') return 1;\n if (network === 'arbitrum') return 42161;\n return 8453; // Default to Base\n }\n\n async getBalance(\n accept: PaymentAccept,\n wallet: unknown,\n rpcUrl?: string\n ): Promise<number> {\n if (!isEvmWallet(wallet) || !wallet.address) {\n return 0;\n }\n\n const url = rpcUrl || this.getDefaultRpcUrl(accept.network);\n\n try {\n // Use eth_call to check ERC20 balance\n const data = this.encodeBalanceOf(wallet.address);\n const response = 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_call',\n params: [\n {\n to: accept.asset,\n data,\n },\n 'latest',\n ],\n }),\n });\n\n const result = (await response.json()) as { error?: unknown; result?: string };\n if (result.error || !result.result) {\n return 0;\n }\n\n const balance = BigInt(result.result);\n const decimals = accept.extra?.decimals ?? 6;\n return Number(balance) / Math.pow(10, decimals);\n } catch {\n return 0;\n }\n }\n\n private encodeBalanceOf(address: string): string {\n // Function selector for balanceOf(address)\n const selector = '0x70a08231';\n // Pad address to 32 bytes\n const paddedAddress = address.slice(2).toLowerCase().padStart(64, '0');\n return selector + paddedAddress;\n }\n\n async buildTransaction(\n accept: PaymentAccept,\n wallet: unknown,\n _rpcUrl?: string\n ): Promise<SignedTransaction> {\n if (!isEvmWallet(wallet)) {\n throw new Error('Invalid EVM wallet');\n }\n if (!wallet.address) {\n throw new Error('Wallet not connected');\n }\n\n const { payTo, asset, extra } = accept;\n // amount is the v2 spec field, maxAmountRequired is v1 fallback\n const amount = accept.amount ?? accept.maxAmountRequired;\n if (!amount) {\n throw new Error('Missing amount in payment requirements');\n }\n\n this.log('Building EVM transaction:', {\n from: wallet.address,\n to: payTo,\n amount,\n asset,\n network: accept.network,\n });\n\n // For x402 v2 EVM payments, we use EIP-712 typed data signing\n // The facilitator will execute the transfer on behalf of the user\n\n const chainId = this.getChainId(accept.network);\n\n // Build the EIP-712 typed data\n // This matches what Dexter's facilitator expects\n const domain = {\n name: extra?.name ?? 'USD Coin',\n version: extra?.version ?? '2',\n chainId: BigInt(chainId),\n verifyingContract: asset as `0x${string}`,\n };\n\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 // Generate a cryptographically secure random nonce (32 bytes hex)\n const nonceBytes = new Uint8Array(32);\n (globalThis.crypto ?? (await import('crypto')).webcrypto).getRandomValues(nonceBytes);\n const nonce = ('0x' + [...nonceBytes].map(b => b.toString(16).padStart(2, '0')).join('')) as `0x${string}`;\n\n const now = Math.floor(Date.now() / 1000);\n \n // Authorization object - values as strings for JSON, BigInts for signing\n const authorization = {\n from: wallet.address,\n to: payTo,\n value: amount, // string\n validAfter: String(now - 600), // 10 minutes before (matching upstream)\n validBefore: String(now + (accept.maxTimeoutSeconds || 60)),\n nonce,\n };\n\n // Message for signing uses BigInt values\n const message = {\n from: wallet.address,\n to: payTo,\n value: BigInt(amount),\n validAfter: BigInt(now - 600),\n validBefore: BigInt(now + (accept.maxTimeoutSeconds || 60)),\n nonce,\n };\n\n if (!wallet.signTypedData) {\n throw new Error('Wallet does not support signTypedData (EIP-712)');\n }\n\n const signature = await wallet.signTypedData({\n domain: domain as Record<string, unknown>,\n types: types as Record<string, unknown[]>,\n primaryType: 'TransferWithAuthorization',\n message: message as Record<string, unknown>,\n });\n\n this.log('EIP-712 signature obtained');\n\n // Payload structure matches upstream @x402/evm exactly\n const payload = {\n authorization,\n signature,\n };\n\n return {\n serialized: JSON.stringify(payload),\n signature,\n };\n }\n}\n\n/**\n * Create an EVM adapter instance\n */\nexport function createEvmAdapter(config?: AdapterConfig): EvmAdapter {\n return new EvmAdapter(config);\n}\n\n"],"mappings":"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","names":["DEFAULT_RPC_URLS"]}
@@ -1,8 +1,8 @@
1
- import { C as ChainAdapter } from '../types-B477nBpg.cjs';
2
- export { A as AdapterConfig, B as BalanceInfo, G as GenericWallet, S as SignedTransaction, W as WalletSet } from '../types-B477nBpg.cjs';
3
- import { b as SolanaAdapter, d as EvmAdapter } from '../solana-BeGAqPta.cjs';
4
- export { A as ARBITRUM_ONE, k as AVALANCHE, B as BASE_MAINNET, j as BASE_SEPOLIA, n as ETHEREUM_MAINNET, E as EvmWallet, O as OPTIMISM, P as POLYGON, l as SKALE_BASE, m as SKALE_BASE_SEPOLIA, e as SOLANA_DEVNET, S as SOLANA_MAINNET, f as SOLANA_TESTNET, g as SolanaWallet, U as USDC_ADDRESSES, a as createEvmAdapter, c as createSolanaAdapter, h as isEvmWallet, i as isSolanaWallet } from '../solana-BeGAqPta.cjs';
5
- import '../types-DYLi7SuF.cjs';
1
+ import { C as ChainAdapter } from '../types-DmqH9yD8.cjs';
2
+ export { A as AdapterConfig, B as BalanceInfo, G as GenericWallet, S as SignedTransaction, W as WalletSet } from '../types-DmqH9yD8.cjs';
3
+ import { b as SolanaAdapter, d as EvmAdapter } from '../solana-CfHuiW2H.cjs';
4
+ export { A as ARBITRUM_ONE, k as AVALANCHE, B as BASE_MAINNET, j as BASE_SEPOLIA, n as ETHEREUM_MAINNET, E as EvmWallet, O as OPTIMISM, P as POLYGON, l as SKALE_BASE, m as SKALE_BASE_SEPOLIA, e as SOLANA_DEVNET, S as SOLANA_MAINNET, f as SOLANA_TESTNET, g as SolanaWallet, U as USDC_ADDRESSES, a as createEvmAdapter, c as createSolanaAdapter, h as isEvmWallet, i as isSolanaWallet } from '../solana-CfHuiW2H.cjs';
5
+ import '../types-BQvaF8lB.cjs';
6
6
 
7
7
  /**
8
8
  * Check if an asset address is a known USDC contract (any chain).
@@ -1,8 +1,8 @@
1
- import { C as ChainAdapter } from '../types-BWnUAPvD.js';
2
- export { A as AdapterConfig, B as BalanceInfo, G as GenericWallet, S as SignedTransaction, W as WalletSet } from '../types-BWnUAPvD.js';
3
- import { b as SolanaAdapter, d as EvmAdapter } from '../solana-CQD9yMju.js';
4
- export { A as ARBITRUM_ONE, k as AVALANCHE, B as BASE_MAINNET, j as BASE_SEPOLIA, n as ETHEREUM_MAINNET, E as EvmWallet, O as OPTIMISM, P as POLYGON, l as SKALE_BASE, m as SKALE_BASE_SEPOLIA, e as SOLANA_DEVNET, S as SOLANA_MAINNET, f as SOLANA_TESTNET, g as SolanaWallet, U as USDC_ADDRESSES, a as createEvmAdapter, c as createSolanaAdapter, h as isEvmWallet, i as isSolanaWallet } from '../solana-CQD9yMju.js';
5
- import '../types-DYLi7SuF.js';
1
+ import { C as ChainAdapter } from '../types-ENcnkof8.js';
2
+ export { A as AdapterConfig, B as BalanceInfo, G as GenericWallet, S as SignedTransaction, W as WalletSet } from '../types-ENcnkof8.js';
3
+ import { b as SolanaAdapter, d as EvmAdapter } from '../solana-kZcwbUK9.js';
4
+ export { A as ARBITRUM_ONE, k as AVALANCHE, B as BASE_MAINNET, j as BASE_SEPOLIA, n as ETHEREUM_MAINNET, E as EvmWallet, O as OPTIMISM, P as POLYGON, l as SKALE_BASE, m as SKALE_BASE_SEPOLIA, e as SOLANA_DEVNET, S as SOLANA_MAINNET, f as SOLANA_TESTNET, g as SolanaWallet, U as USDC_ADDRESSES, a as createEvmAdapter, c as createSolanaAdapter, h as isEvmWallet, i as isSolanaWallet } from '../solana-kZcwbUK9.js';
5
+ import '../types-BQvaF8lB.js';
6
6
 
7
7
  /**
8
8
  * Check if an asset address is a known USDC contract (any chain).
@@ -102,7 +102,7 @@ var SolanaAdapter = class {
102
102
  const connection = new Connection(url, "confirmed");
103
103
  const userPubkey = new PublicKey(wallet.publicKey.toBase58());
104
104
  const { payTo, asset, extra } = accept;
105
- const amount = accept.amount || accept.maxAmountRequired;
105
+ const amount = accept.amount ?? accept.maxAmountRequired;
106
106
  if (!amount) {
107
107
  throw new Error("Missing amount in payment requirements");
108
108
  }
@@ -340,7 +340,7 @@ var EvmAdapter = class {
340
340
  throw new Error("Wallet not connected");
341
341
  }
342
342
  const { payTo, asset, extra } = accept;
343
- const amount = accept.amount || accept.maxAmountRequired;
343
+ const amount = accept.amount ?? accept.maxAmountRequired;
344
344
  if (!amount) {
345
345
  throw new Error("Missing amount in payment requirements");
346
346
  }
@@ -368,7 +368,9 @@ var EvmAdapter = class {
368
368
  { name: "nonce", type: "bytes32" }
369
369
  ]
370
370
  };
371
- const nonce = "0x" + [...Array(32)].map(() => Math.floor(Math.random() * 256).toString(16).padStart(2, "0")).join("");
371
+ const nonceBytes = new Uint8Array(32);
372
+ (globalThis.crypto ?? (await import("crypto")).webcrypto).getRandomValues(nonceBytes);
373
+ const nonce = "0x" + [...nonceBytes].map((b) => b.toString(16).padStart(2, "0")).join("");
372
374
  const now = Math.floor(Date.now() / 1e3);
373
375
  const authorization = {
374
376
  from: wallet.address,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/adapters/solana.ts","../../src/adapters/evm.ts","../../src/adapters/index.ts"],"sourcesContent":["/**\n * Solana Chain Adapter\n *\n * Implements the ChainAdapter interface for Solana networks.\n * Handles transaction building, signing, and balance queries.\n */\n\nimport {\n PublicKey,\n Connection,\n TransactionMessage,\n VersionedTransaction,\n ComputeBudgetProgram,\n type TransactionInstruction,\n} from '@solana/web3.js';\nimport {\n getAssociatedTokenAddress,\n getAccount,\n createTransferCheckedInstruction,\n getMint,\n TOKEN_PROGRAM_ID,\n TOKEN_2022_PROGRAM_ID,\n} from '@solana/spl-token';\nimport type { ChainAdapter, AdapterConfig, SignedTransaction } from './types';\nimport type { PaymentAccept } from '../types';\n\n/**\n * CAIP-2 network identifiers for Solana\n */\nexport const SOLANA_MAINNET = 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp';\nexport const SOLANA_DEVNET = 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1';\nexport const SOLANA_TESTNET = 'solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z';\n\n/**\n * Default RPC URLs\n * Mainnet uses Dexter's RPC proxy for reliability and zero-config setup\n */\nconst DEFAULT_RPC_URLS: Record<string, string> = {\n [SOLANA_MAINNET]: 'https://api.dexter.cash/api/solana/rpc',\n [SOLANA_DEVNET]: 'https://api.devnet.solana.com',\n [SOLANA_TESTNET]: 'https://api.testnet.solana.com',\n};\n\n/**\n * Dexter policy-safe compute budget settings\n */\nconst DEFAULT_COMPUTE_UNIT_LIMIT = 12_000;\nconst DEFAULT_COMPUTE_UNIT_PRICE_MICROLAMPORTS = 1;\n\n/**\n * Solana wallet interface (compatible with @solana/wallet-adapter)\n */\nexport interface SolanaWallet {\n publicKey: { toBase58(): string } | null;\n signTransaction<T>(tx: T): Promise<T>;\n}\n\n/**\n * Check if an object is a valid Solana wallet\n */\nexport function isSolanaWallet(wallet: unknown): wallet is SolanaWallet {\n if (!wallet || typeof wallet !== 'object') return false;\n const w = wallet as Record<string, unknown>;\n return (\n 'publicKey' in w &&\n 'signTransaction' in w &&\n typeof w.signTransaction === 'function'\n );\n}\n\n/**\n * Solana Chain Adapter\n */\nexport class SolanaAdapter implements ChainAdapter {\n readonly name = 'Solana';\n readonly networks = [SOLANA_MAINNET, SOLANA_DEVNET, SOLANA_TESTNET];\n\n private config: AdapterConfig;\n private log: (...args: unknown[]) => void;\n\n constructor(config: AdapterConfig = {}) {\n this.config = config;\n this.log = config.verbose\n ? console.log.bind(console, '[x402:solana]')\n : () => {};\n }\n\n canHandle(network: string): boolean {\n // Handle both exact CAIP-2 and legacy formats\n if (this.networks.includes(network)) return true;\n // Legacy format support\n if (network === 'solana') return true;\n if (network === 'solana-devnet') return true;\n if (network === 'solana-testnet') return true;\n // Check if it starts with 'solana:'\n if (network.startsWith('solana:')) return true;\n return false;\n }\n\n getDefaultRpcUrl(network: string): string {\n // Check custom config first\n if (this.config.rpcUrls?.[network]) {\n return this.config.rpcUrls[network];\n }\n // Check defaults\n if (DEFAULT_RPC_URLS[network]) {\n return DEFAULT_RPC_URLS[network];\n }\n // Normalize legacy networks\n if (network === 'solana') return DEFAULT_RPC_URLS[SOLANA_MAINNET];\n if (network === 'solana-devnet') return DEFAULT_RPC_URLS[SOLANA_DEVNET];\n if (network === 'solana-testnet') return DEFAULT_RPC_URLS[SOLANA_TESTNET];\n // Default to mainnet\n return DEFAULT_RPC_URLS[SOLANA_MAINNET];\n }\n\n getAddress(wallet: unknown): string | null {\n if (!isSolanaWallet(wallet)) return null;\n return wallet.publicKey?.toBase58() ?? null;\n }\n\n isConnected(wallet: unknown): boolean {\n if (!isSolanaWallet(wallet)) return false;\n return wallet.publicKey !== null;\n }\n\n async getBalance(\n accept: PaymentAccept,\n wallet: unknown,\n rpcUrl?: string\n ): Promise<number> {\n if (!isSolanaWallet(wallet) || !wallet.publicKey) {\n return 0;\n }\n\n const url = rpcUrl || this.getDefaultRpcUrl(accept.network);\n const connection = new Connection(url, 'confirmed');\n const userPubkey = new PublicKey(wallet.publicKey.toBase58());\n const mintPubkey = new PublicKey(accept.asset);\n\n try {\n // Determine token program\n const mintInfo = await connection.getAccountInfo(mintPubkey, 'confirmed');\n const programId =\n mintInfo?.owner.toBase58() === TOKEN_2022_PROGRAM_ID.toBase58()\n ? TOKEN_2022_PROGRAM_ID\n : TOKEN_PROGRAM_ID;\n\n const ata = await getAssociatedTokenAddress(\n mintPubkey,\n userPubkey,\n false,\n programId\n );\n\n const account = await getAccount(connection, ata, undefined, programId);\n const decimals = accept.extra?.decimals ?? 6;\n return Number(account.amount) / Math.pow(10, decimals);\n } catch {\n // Token account doesn't exist\n return 0;\n }\n }\n\n async buildTransaction(\n accept: PaymentAccept,\n wallet: unknown,\n rpcUrl?: string\n ): Promise<SignedTransaction> {\n if (!isSolanaWallet(wallet)) {\n throw new Error('Invalid Solana wallet');\n }\n if (!wallet.publicKey) {\n throw new Error('Wallet not connected');\n }\n\n const url = rpcUrl || this.getDefaultRpcUrl(accept.network);\n const connection = new Connection(url, 'confirmed');\n const userPubkey = new PublicKey(wallet.publicKey.toBase58());\n\n // Extract required fields (amount or maxAmountRequired for x402 spec compatibility)\n const { payTo, asset, extra } = accept;\n const amount = accept.amount || accept.maxAmountRequired;\n if (!amount) {\n throw new Error('Missing amount in payment requirements');\n }\n\n if (!extra?.feePayer) {\n throw new Error('Missing feePayer in payment requirements');\n }\n // Note: decimals is optional - we fetch from mint on-chain if not provided\n\n const feePayerPubkey = new PublicKey(extra.feePayer);\n const mintPubkey = new PublicKey(asset);\n const destinationPubkey = new PublicKey(payTo);\n\n this.log('Building transaction:', {\n from: userPubkey.toBase58(),\n to: payTo,\n amount,\n asset,\n feePayer: extra.feePayer,\n });\n\n // Build instructions\n const instructions: TransactionInstruction[] = [];\n\n // 1. ComputeBudget: Set compute unit limit\n instructions.push(\n ComputeBudgetProgram.setComputeUnitLimit({\n units: DEFAULT_COMPUTE_UNIT_LIMIT,\n })\n );\n\n // 2. ComputeBudget: Set compute unit price\n instructions.push(\n ComputeBudgetProgram.setComputeUnitPrice({\n microLamports: DEFAULT_COMPUTE_UNIT_PRICE_MICROLAMPORTS,\n })\n );\n\n // 3. Determine token program\n const mintInfo = await connection.getAccountInfo(mintPubkey, 'confirmed');\n if (!mintInfo) {\n throw new Error(`Token mint ${asset} not found`);\n }\n\n const programId =\n mintInfo.owner.toBase58() === TOKEN_2022_PROGRAM_ID.toBase58()\n ? TOKEN_2022_PROGRAM_ID\n : TOKEN_PROGRAM_ID;\n\n // Fetch mint to get decimals (required for TransferChecked)\n const mint = await getMint(connection, mintPubkey, undefined, programId);\n if (typeof extra?.decimals === 'number' && mint.decimals !== extra.decimals) {\n this.log(\n `Decimals mismatch: requirements say ${extra.decimals}, mint says ${mint.decimals}`\n );\n }\n\n // Derive Associated Token Accounts\n const sourceAta = await getAssociatedTokenAddress(\n mintPubkey,\n userPubkey,\n false,\n programId\n );\n const destinationAta = await getAssociatedTokenAddress(\n mintPubkey,\n destinationPubkey,\n false,\n programId\n );\n\n // Verify source ATA exists\n const sourceAtaInfo = await connection.getAccountInfo(sourceAta, 'confirmed');\n if (!sourceAtaInfo) {\n throw new Error(\n `No token account found for ${asset}. Please ensure you have USDC in your wallet.`\n );\n }\n\n // Verify destination ATA exists\n const destAtaInfo = await connection.getAccountInfo(destinationAta, 'confirmed');\n if (!destAtaInfo) {\n throw new Error(\n `Seller token account not found. The seller (${payTo}) must have a USDC account.`\n );\n }\n\n // 4. TransferChecked instruction\n const amountBigInt = BigInt(amount);\n instructions.push(\n createTransferCheckedInstruction(\n sourceAta,\n mintPubkey,\n destinationAta,\n userPubkey,\n amountBigInt,\n mint.decimals,\n [],\n programId\n )\n );\n\n // Get recent blockhash\n const { blockhash } = await connection.getLatestBlockhash('confirmed');\n\n // Compile to V0 message (feePayer is facilitator)\n const message = new TransactionMessage({\n payerKey: feePayerPubkey,\n recentBlockhash: blockhash,\n instructions,\n }).compileToV0Message();\n\n // Create and sign transaction\n const transaction = new VersionedTransaction(message);\n const signedTx = await wallet.signTransaction(transaction);\n\n this.log('Transaction signed successfully');\n\n return {\n serialized: Buffer.from(signedTx.serialize()).toString('base64'),\n };\n }\n}\n\n/**\n * Create a Solana adapter instance\n */\nexport function createSolanaAdapter(config?: AdapterConfig): SolanaAdapter {\n return new SolanaAdapter(config);\n}\n\n\n\n","/**\n * EVM Chain Adapter\n *\n * Implements the ChainAdapter interface for EVM networks (Base, Ethereum, Arbitrum, etc.)\n * Uses EIP-712 typed data signing for x402 v2 payments.\n */\n\nimport type { ChainAdapter, AdapterConfig, SignedTransaction } from './types';\nimport type { PaymentAccept } from '../types';\n\n/**\n * CAIP-2 network identifiers for EVM chains.\n * Mirrors dexter-facilitator/src/config/chains.ts — update both when adding chains.\n */\nexport const BASE_MAINNET = 'eip155:8453';\nexport const BASE_SEPOLIA = 'eip155:84532';\nexport const ARBITRUM_ONE = 'eip155:42161';\nexport const POLYGON = 'eip155:137';\nexport const OPTIMISM = 'eip155:10';\nexport const AVALANCHE = 'eip155:43114';\nexport const SKALE_BASE = 'eip155:1187947933';\nexport const SKALE_BASE_SEPOLIA = 'eip155:324705682';\n\n/** @deprecated Not supported by the Dexter facilitator. Use BASE_MAINNET for EVM payments. */\nexport const ETHEREUM_MAINNET = 'eip155:1';\n\n/**\n * Chain IDs by CAIP-2 network\n */\nconst CHAIN_IDS: Record<string, number> = {\n [BASE_MAINNET]: 8453,\n [BASE_SEPOLIA]: 84532,\n [ARBITRUM_ONE]: 42161,\n [POLYGON]: 137,\n [OPTIMISM]: 10,\n [AVALANCHE]: 43114,\n [SKALE_BASE]: 1187947933,\n [SKALE_BASE_SEPOLIA]: 324705682,\n [ETHEREUM_MAINNET]: 1,\n};\n\n/**\n * Default RPC URLs.\n * Base mainnet uses Dexter's RPC proxy for reliability and zero-config setup.\n * Source of truth: dexter-facilitator/src/config/chains.ts\n */\nconst DEFAULT_RPC_URLS: Record<string, string> = {\n [BASE_MAINNET]: 'https://api.dexter.cash/api/base/rpc',\n [BASE_SEPOLIA]: 'https://sepolia.base.org',\n [ARBITRUM_ONE]: 'https://arb1.arbitrum.io/rpc',\n [POLYGON]: 'https://polygon-rpc.com',\n [OPTIMISM]: 'https://mainnet.optimism.io',\n [AVALANCHE]: 'https://api.avax.network/ext/bc/C/rpc',\n [SKALE_BASE]: 'https://skale-base.skalenodes.com/v1/base',\n [SKALE_BASE_SEPOLIA]: 'https://base-sepolia-testnet.skalenodes.com/v1/jubilant-horrible-ancha',\n [ETHEREUM_MAINNET]: 'https://eth.llamarpc.com',\n};\n\n/**\n * USDC contract addresses by chain.\n * Source of truth: dexter-facilitator/src/config/chains.ts\n */\nexport const USDC_ADDRESSES: Record<string, string> = {\n [BASE_MAINNET]: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\n [BASE_SEPOLIA]: '0x036CbD53842c5426634e7929541eC2318f3dCF7e',\n [ARBITRUM_ONE]: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',\n [POLYGON]: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',\n [OPTIMISM]: '0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85',\n [AVALANCHE]: '0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E',\n [SKALE_BASE]: '0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20',\n [SKALE_BASE_SEPOLIA]: '0x2e08028E3C4c2356572E096d8EF835cD5C6030bD',\n [ETHEREUM_MAINNET]: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',\n};\n\n/**\n * EVM wallet interface (compatible with wagmi, ethers, viem)\n */\nexport interface EvmWallet {\n /** Wallet address */\n address: string;\n /** Chain ID currently connected to */\n chainId?: number;\n /**\n * Sign typed data (EIP-712)\n * This is the primary signing method for x402 EVM payments\n */\n signTypedData?(params: {\n domain: Record<string, unknown>;\n types: Record<string, unknown[]>;\n primaryType: string;\n message: Record<string, unknown>;\n }): Promise<string>;\n /**\n * Alternative: Send transaction directly\n * Used if signTypedData is not available\n */\n sendTransaction?(params: {\n to: string;\n data: string;\n value?: bigint;\n }): Promise<string>;\n}\n\n/**\n * Check if an object is a valid EVM wallet\n */\nexport function isEvmWallet(wallet: unknown): wallet is EvmWallet {\n if (!wallet || typeof wallet !== 'object') return false;\n const w = wallet as Record<string, unknown>;\n return (\n 'address' in w &&\n typeof w.address === 'string' &&\n w.address.startsWith('0x')\n );\n}\n\n// ERC20 balanceOf function selector: 0x70a08231\n\n/**\n * EVM Chain Adapter\n */\nexport class EvmAdapter implements ChainAdapter {\n readonly name = 'EVM';\n readonly networks = [BASE_MAINNET, BASE_SEPOLIA, ETHEREUM_MAINNET, ARBITRUM_ONE];\n\n private config: AdapterConfig;\n private log: (...args: unknown[]) => void;\n\n constructor(config: AdapterConfig = {}) {\n this.config = config;\n this.log = config.verbose\n ? console.log.bind(console, '[x402:evm]')\n : () => {};\n }\n\n canHandle(network: string): boolean {\n // Handle exact CAIP-2\n if (this.networks.includes(network)) return true;\n // Legacy format\n if (network === 'base') return true;\n if (network === 'ethereum') return true;\n if (network === 'arbitrum') return true;\n // Check if it starts with 'eip155:'\n if (network.startsWith('eip155:')) return true;\n return false;\n }\n\n getDefaultRpcUrl(network: string): string {\n if (this.config.rpcUrls?.[network]) {\n return this.config.rpcUrls[network];\n }\n if (DEFAULT_RPC_URLS[network]) {\n return DEFAULT_RPC_URLS[network];\n }\n // Normalize legacy\n if (network === 'base') return DEFAULT_RPC_URLS[BASE_MAINNET];\n if (network === 'ethereum') return DEFAULT_RPC_URLS[ETHEREUM_MAINNET];\n if (network === 'arbitrum') return DEFAULT_RPC_URLS[ARBITRUM_ONE];\n return DEFAULT_RPC_URLS[BASE_MAINNET];\n }\n\n getAddress(wallet: unknown): string | null {\n if (!isEvmWallet(wallet)) return null;\n return wallet.address;\n }\n\n isConnected(wallet: unknown): boolean {\n if (!isEvmWallet(wallet)) return false;\n return !!wallet.address;\n }\n\n private getChainId(network: string): number {\n if (CHAIN_IDS[network]) return CHAIN_IDS[network];\n // Try to extract from CAIP-2\n if (network.startsWith('eip155:')) {\n const chainIdStr = network.split(':')[1];\n return parseInt(chainIdStr, 10);\n }\n // Defaults\n if (network === 'base') return 8453;\n if (network === 'ethereum') return 1;\n if (network === 'arbitrum') return 42161;\n return 8453; // Default to Base\n }\n\n async getBalance(\n accept: PaymentAccept,\n wallet: unknown,\n rpcUrl?: string\n ): Promise<number> {\n if (!isEvmWallet(wallet) || !wallet.address) {\n return 0;\n }\n\n const url = rpcUrl || this.getDefaultRpcUrl(accept.network);\n\n try {\n // Use eth_call to check ERC20 balance\n const data = this.encodeBalanceOf(wallet.address);\n const response = 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_call',\n params: [\n {\n to: accept.asset,\n data,\n },\n 'latest',\n ],\n }),\n });\n\n const result = (await response.json()) as { error?: unknown; result?: string };\n if (result.error || !result.result) {\n return 0;\n }\n\n const balance = BigInt(result.result);\n const decimals = accept.extra?.decimals ?? 6;\n return Number(balance) / Math.pow(10, decimals);\n } catch {\n return 0;\n }\n }\n\n private encodeBalanceOf(address: string): string {\n // Function selector for balanceOf(address)\n const selector = '0x70a08231';\n // Pad address to 32 bytes\n const paddedAddress = address.slice(2).toLowerCase().padStart(64, '0');\n return selector + paddedAddress;\n }\n\n async buildTransaction(\n accept: PaymentAccept,\n wallet: unknown,\n _rpcUrl?: string\n ): Promise<SignedTransaction> {\n if (!isEvmWallet(wallet)) {\n throw new Error('Invalid EVM wallet');\n }\n if (!wallet.address) {\n throw new Error('Wallet not connected');\n }\n\n const { payTo, asset, extra } = accept;\n const amount = accept.amount || accept.maxAmountRequired;\n if (!amount) {\n throw new Error('Missing amount in payment requirements');\n }\n\n this.log('Building EVM transaction:', {\n from: wallet.address,\n to: payTo,\n amount,\n asset,\n network: accept.network,\n });\n\n // For x402 v2 EVM payments, we use EIP-712 typed data signing\n // The facilitator will execute the transfer on behalf of the user\n\n const chainId = this.getChainId(accept.network);\n\n // Build the EIP-712 typed data\n // This matches what Dexter's facilitator expects\n const domain = {\n name: extra?.name ?? 'USD Coin',\n version: extra?.version ?? '2',\n chainId: BigInt(chainId),\n verifyingContract: asset as `0x${string}`,\n };\n\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 // Generate a random nonce (32 bytes hex)\n const nonce = '0x' + [...Array(32)]\n .map(() => Math.floor(Math.random() * 256).toString(16).padStart(2, '0'))\n .join('') as `0x${string}`;\n\n const now = Math.floor(Date.now() / 1000);\n \n // Authorization object - values as strings for JSON, BigInts for signing\n const authorization = {\n from: wallet.address,\n to: payTo,\n value: amount, // string\n validAfter: String(now - 600), // 10 minutes before (matching upstream)\n validBefore: String(now + (accept.maxTimeoutSeconds || 60)),\n nonce,\n };\n\n // Message for signing uses BigInt values\n const message = {\n from: wallet.address,\n to: payTo,\n value: BigInt(amount),\n validAfter: BigInt(now - 600),\n validBefore: BigInt(now + (accept.maxTimeoutSeconds || 60)),\n nonce,\n };\n\n if (!wallet.signTypedData) {\n throw new Error('Wallet does not support signTypedData (EIP-712)');\n }\n\n const signature = await wallet.signTypedData({\n domain: domain as Record<string, unknown>,\n types: types as Record<string, unknown[]>,\n primaryType: 'TransferWithAuthorization',\n message: message as Record<string, unknown>,\n });\n\n this.log('EIP-712 signature obtained');\n\n // Payload structure matches upstream @x402/evm exactly\n const payload = {\n authorization,\n signature,\n };\n\n return {\n serialized: JSON.stringify(payload),\n signature,\n };\n }\n}\n\n/**\n * Create an EVM adapter instance\n */\nexport function createEvmAdapter(config?: AdapterConfig): EvmAdapter {\n return new EvmAdapter(config);\n}\n\n","/**\n * Chain Adapters\n *\n * x402 v2 is designed to be chain-agnostic. Each adapter handles\n * the specifics of transaction building and signing for its chain.\n *\n * @example\n * ```typescript\n * import { createSolanaAdapter, createEvmAdapter } from '@dexterai/x402/adapters';\n *\n * const adapters = [\n * createSolanaAdapter(),\n * createEvmAdapter(),\n * ];\n *\n * // Find adapter for a network\n * const adapter = adapters.find(a => a.canHandle('eip155:8453'));\n * ```\n */\n\nimport { createSolanaAdapter as _createSolanaAdapter } from './solana';\nimport { createEvmAdapter as _createEvmAdapter } from './evm';\nimport { USDC_ADDRESSES as _USDC_ADDRESSES } from './evm';\n\n// Types\nexport type {\n ChainAdapter,\n AdapterConfig,\n SignedTransaction,\n GenericWallet,\n WalletSet,\n BalanceInfo,\n} from './types';\n\n// Solana\nexport {\n SolanaAdapter,\n createSolanaAdapter,\n isSolanaWallet,\n SOLANA_MAINNET,\n SOLANA_DEVNET,\n SOLANA_TESTNET,\n} from './solana';\nexport type { SolanaWallet } from './solana';\n\n// EVM\nexport {\n EvmAdapter,\n createEvmAdapter,\n isEvmWallet,\n BASE_MAINNET,\n BASE_SEPOLIA,\n ARBITRUM_ONE,\n POLYGON,\n OPTIMISM,\n AVALANCHE,\n SKALE_BASE,\n SKALE_BASE_SEPOLIA,\n ETHEREUM_MAINNET,\n USDC_ADDRESSES,\n} from './evm';\nexport type { EvmWallet } from './evm';\n\n/**\n * Check if an asset address is a known USDC contract (any chain).\n * Single source of truth for decimal inference in the client.\n */\nexport function isKnownUSDC(asset: string): boolean {\n // Solana mints\n if (asset === 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v') return true; // mainnet\n if (asset === '4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU') return true; // devnet\n // All EVM USDC addresses (case-insensitive for EVM)\n const lc = asset.toLowerCase();\n for (const addr of Object.values(_USDC_ADDRESSES)) {\n if (addr.toLowerCase() === lc) return true;\n }\n return false;\n}\n\n/**\n * Create all default adapters\n */\nexport function createDefaultAdapters(verbose = false) {\n return [\n _createSolanaAdapter({ verbose }),\n _createEvmAdapter({ verbose }),\n ];\n}\n\n/**\n * Find adapter that can handle a network\n */\nexport function findAdapter(\n adapters: import('./types').ChainAdapter[],\n network: string\n): import('./types').ChainAdapter | undefined {\n return adapters.find(adapter => adapter.canHandle(network));\n}\n\n\n\n"],"mappings":"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","names":["DEFAULT_RPC_URLS"]}
1
+ {"version":3,"sources":["../../src/adapters/solana.ts","../../src/adapters/evm.ts","../../src/adapters/index.ts"],"sourcesContent":["/**\n * Solana Chain Adapter\n *\n * Implements the ChainAdapter interface for Solana networks.\n * Handles transaction building, signing, and balance queries.\n */\n\nimport {\n PublicKey,\n Connection,\n TransactionMessage,\n VersionedTransaction,\n ComputeBudgetProgram,\n type TransactionInstruction,\n} from '@solana/web3.js';\nimport {\n getAssociatedTokenAddress,\n getAccount,\n createTransferCheckedInstruction,\n getMint,\n TOKEN_PROGRAM_ID,\n TOKEN_2022_PROGRAM_ID,\n} from '@solana/spl-token';\nimport type { ChainAdapter, AdapterConfig, SignedTransaction } from './types';\nimport type { PaymentAccept } from '../types';\n\n/**\n * CAIP-2 network identifiers for Solana\n */\nexport const SOLANA_MAINNET = 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp';\nexport const SOLANA_DEVNET = 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1';\nexport const SOLANA_TESTNET = 'solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z';\n\n/**\n * Default RPC URLs\n * Mainnet uses Dexter's RPC proxy for reliability and zero-config setup\n */\nconst DEFAULT_RPC_URLS: Record<string, string> = {\n [SOLANA_MAINNET]: 'https://api.dexter.cash/api/solana/rpc',\n [SOLANA_DEVNET]: 'https://api.devnet.solana.com',\n [SOLANA_TESTNET]: 'https://api.testnet.solana.com',\n};\n\n/**\n * Dexter policy-safe compute budget settings\n */\nconst DEFAULT_COMPUTE_UNIT_LIMIT = 12_000;\nconst DEFAULT_COMPUTE_UNIT_PRICE_MICROLAMPORTS = 1;\n\n/**\n * Solana wallet interface (compatible with @solana/wallet-adapter)\n */\nexport interface SolanaWallet {\n publicKey: { toBase58(): string } | null;\n signTransaction<T>(tx: T): Promise<T>;\n}\n\n/**\n * Check if an object is a valid Solana wallet\n */\nexport function isSolanaWallet(wallet: unknown): wallet is SolanaWallet {\n if (!wallet || typeof wallet !== 'object') return false;\n const w = wallet as Record<string, unknown>;\n return (\n 'publicKey' in w &&\n 'signTransaction' in w &&\n typeof w.signTransaction === 'function'\n );\n}\n\n/**\n * Solana Chain Adapter\n */\nexport class SolanaAdapter implements ChainAdapter {\n readonly name = 'Solana';\n readonly networks = [SOLANA_MAINNET, SOLANA_DEVNET, SOLANA_TESTNET];\n\n private config: AdapterConfig;\n private log: (...args: unknown[]) => void;\n\n constructor(config: AdapterConfig = {}) {\n this.config = config;\n this.log = config.verbose\n ? console.log.bind(console, '[x402:solana]')\n : () => {};\n }\n\n canHandle(network: string): boolean {\n // Handle both exact CAIP-2 and legacy formats\n if (this.networks.includes(network)) return true;\n // Legacy format support\n if (network === 'solana') return true;\n if (network === 'solana-devnet') return true;\n if (network === 'solana-testnet') return true;\n // Check if it starts with 'solana:'\n if (network.startsWith('solana:')) return true;\n return false;\n }\n\n getDefaultRpcUrl(network: string): string {\n // Check custom config first\n if (this.config.rpcUrls?.[network]) {\n return this.config.rpcUrls[network];\n }\n // Check defaults\n if (DEFAULT_RPC_URLS[network]) {\n return DEFAULT_RPC_URLS[network];\n }\n // Normalize legacy networks\n if (network === 'solana') return DEFAULT_RPC_URLS[SOLANA_MAINNET];\n if (network === 'solana-devnet') return DEFAULT_RPC_URLS[SOLANA_DEVNET];\n if (network === 'solana-testnet') return DEFAULT_RPC_URLS[SOLANA_TESTNET];\n // Default to mainnet\n return DEFAULT_RPC_URLS[SOLANA_MAINNET];\n }\n\n getAddress(wallet: unknown): string | null {\n if (!isSolanaWallet(wallet)) return null;\n return wallet.publicKey?.toBase58() ?? null;\n }\n\n isConnected(wallet: unknown): boolean {\n if (!isSolanaWallet(wallet)) return false;\n return wallet.publicKey !== null;\n }\n\n async getBalance(\n accept: PaymentAccept,\n wallet: unknown,\n rpcUrl?: string\n ): Promise<number> {\n if (!isSolanaWallet(wallet) || !wallet.publicKey) {\n return 0;\n }\n\n const url = rpcUrl || this.getDefaultRpcUrl(accept.network);\n const connection = new Connection(url, 'confirmed');\n const userPubkey = new PublicKey(wallet.publicKey.toBase58());\n const mintPubkey = new PublicKey(accept.asset);\n\n try {\n // Determine token program\n const mintInfo = await connection.getAccountInfo(mintPubkey, 'confirmed');\n const programId =\n mintInfo?.owner.toBase58() === TOKEN_2022_PROGRAM_ID.toBase58()\n ? TOKEN_2022_PROGRAM_ID\n : TOKEN_PROGRAM_ID;\n\n const ata = await getAssociatedTokenAddress(\n mintPubkey,\n userPubkey,\n false,\n programId\n );\n\n const account = await getAccount(connection, ata, undefined, programId);\n const decimals = accept.extra?.decimals ?? 6;\n return Number(account.amount) / Math.pow(10, decimals);\n } catch {\n // Token account doesn't exist\n return 0;\n }\n }\n\n async buildTransaction(\n accept: PaymentAccept,\n wallet: unknown,\n rpcUrl?: string\n ): Promise<SignedTransaction> {\n if (!isSolanaWallet(wallet)) {\n throw new Error('Invalid Solana wallet');\n }\n if (!wallet.publicKey) {\n throw new Error('Wallet not connected');\n }\n\n const url = rpcUrl || this.getDefaultRpcUrl(accept.network);\n const connection = new Connection(url, 'confirmed');\n const userPubkey = new PublicKey(wallet.publicKey.toBase58());\n\n // Extract required fields — amount is the v2 spec field, maxAmountRequired is v1 fallback\n const { payTo, asset, extra } = accept;\n const amount = accept.amount ?? accept.maxAmountRequired;\n if (!amount) {\n throw new Error('Missing amount in payment requirements');\n }\n\n if (!extra?.feePayer) {\n throw new Error('Missing feePayer in payment requirements');\n }\n // Note: decimals is optional - we fetch from mint on-chain if not provided\n\n const feePayerPubkey = new PublicKey(extra.feePayer);\n const mintPubkey = new PublicKey(asset);\n const destinationPubkey = new PublicKey(payTo);\n\n this.log('Building transaction:', {\n from: userPubkey.toBase58(),\n to: payTo,\n amount,\n asset,\n feePayer: extra.feePayer,\n });\n\n // Build instructions\n const instructions: TransactionInstruction[] = [];\n\n // 1. ComputeBudget: Set compute unit limit\n instructions.push(\n ComputeBudgetProgram.setComputeUnitLimit({\n units: DEFAULT_COMPUTE_UNIT_LIMIT,\n })\n );\n\n // 2. ComputeBudget: Set compute unit price\n instructions.push(\n ComputeBudgetProgram.setComputeUnitPrice({\n microLamports: DEFAULT_COMPUTE_UNIT_PRICE_MICROLAMPORTS,\n })\n );\n\n // 3. Determine token program\n const mintInfo = await connection.getAccountInfo(mintPubkey, 'confirmed');\n if (!mintInfo) {\n throw new Error(`Token mint ${asset} not found`);\n }\n\n const programId =\n mintInfo.owner.toBase58() === TOKEN_2022_PROGRAM_ID.toBase58()\n ? TOKEN_2022_PROGRAM_ID\n : TOKEN_PROGRAM_ID;\n\n // Fetch mint to get decimals (required for TransferChecked)\n const mint = await getMint(connection, mintPubkey, undefined, programId);\n if (typeof extra?.decimals === 'number' && mint.decimals !== extra.decimals) {\n this.log(\n `Decimals mismatch: requirements say ${extra.decimals}, mint says ${mint.decimals}`\n );\n }\n\n // Derive Associated Token Accounts\n const sourceAta = await getAssociatedTokenAddress(\n mintPubkey,\n userPubkey,\n false,\n programId\n );\n const destinationAta = await getAssociatedTokenAddress(\n mintPubkey,\n destinationPubkey,\n false,\n programId\n );\n\n // Verify source ATA exists\n const sourceAtaInfo = await connection.getAccountInfo(sourceAta, 'confirmed');\n if (!sourceAtaInfo) {\n throw new Error(\n `No token account found for ${asset}. Please ensure you have USDC in your wallet.`\n );\n }\n\n // Verify destination ATA exists\n const destAtaInfo = await connection.getAccountInfo(destinationAta, 'confirmed');\n if (!destAtaInfo) {\n throw new Error(\n `Seller token account not found. The seller (${payTo}) must have a USDC account.`\n );\n }\n\n // 4. TransferChecked instruction\n const amountBigInt = BigInt(amount);\n instructions.push(\n createTransferCheckedInstruction(\n sourceAta,\n mintPubkey,\n destinationAta,\n userPubkey,\n amountBigInt,\n mint.decimals,\n [],\n programId\n )\n );\n\n // Get recent blockhash\n const { blockhash } = await connection.getLatestBlockhash('confirmed');\n\n // Compile to V0 message (feePayer is facilitator)\n const message = new TransactionMessage({\n payerKey: feePayerPubkey,\n recentBlockhash: blockhash,\n instructions,\n }).compileToV0Message();\n\n // Create and sign transaction\n const transaction = new VersionedTransaction(message);\n const signedTx = await wallet.signTransaction(transaction);\n\n this.log('Transaction signed successfully');\n\n return {\n serialized: Buffer.from(signedTx.serialize()).toString('base64'),\n };\n }\n}\n\n/**\n * Create a Solana adapter instance\n */\nexport function createSolanaAdapter(config?: AdapterConfig): SolanaAdapter {\n return new SolanaAdapter(config);\n}\n\n\n\n","/**\n * EVM Chain Adapter\n *\n * Implements the ChainAdapter interface for EVM networks (Base, Ethereum, Arbitrum, etc.)\n * Uses EIP-712 typed data signing for x402 v2 payments.\n */\n\nimport type { ChainAdapter, AdapterConfig, SignedTransaction } from './types';\nimport type { PaymentAccept } from '../types';\n\n/**\n * CAIP-2 network identifiers for EVM chains.\n * Mirrors dexter-facilitator/src/config/chains.ts — update both when adding chains.\n */\nexport const BASE_MAINNET = 'eip155:8453';\nexport const BASE_SEPOLIA = 'eip155:84532';\nexport const ARBITRUM_ONE = 'eip155:42161';\nexport const POLYGON = 'eip155:137';\nexport const OPTIMISM = 'eip155:10';\nexport const AVALANCHE = 'eip155:43114';\nexport const SKALE_BASE = 'eip155:1187947933';\nexport const SKALE_BASE_SEPOLIA = 'eip155:324705682';\n\n/** @deprecated Not supported by the Dexter facilitator. Use BASE_MAINNET for EVM payments. */\nexport const ETHEREUM_MAINNET = 'eip155:1';\n\n/**\n * Chain IDs by CAIP-2 network\n */\nconst CHAIN_IDS: Record<string, number> = {\n [BASE_MAINNET]: 8453,\n [BASE_SEPOLIA]: 84532,\n [ARBITRUM_ONE]: 42161,\n [POLYGON]: 137,\n [OPTIMISM]: 10,\n [AVALANCHE]: 43114,\n [SKALE_BASE]: 1187947933,\n [SKALE_BASE_SEPOLIA]: 324705682,\n [ETHEREUM_MAINNET]: 1,\n};\n\n/**\n * Default RPC URLs.\n * Base mainnet uses Dexter's RPC proxy for reliability and zero-config setup.\n * Source of truth: dexter-facilitator/src/config/chains.ts\n */\nconst DEFAULT_RPC_URLS: Record<string, string> = {\n [BASE_MAINNET]: 'https://api.dexter.cash/api/base/rpc',\n [BASE_SEPOLIA]: 'https://sepolia.base.org',\n [ARBITRUM_ONE]: 'https://arb1.arbitrum.io/rpc',\n [POLYGON]: 'https://polygon-rpc.com',\n [OPTIMISM]: 'https://mainnet.optimism.io',\n [AVALANCHE]: 'https://api.avax.network/ext/bc/C/rpc',\n [SKALE_BASE]: 'https://skale-base.skalenodes.com/v1/base',\n [SKALE_BASE_SEPOLIA]: 'https://base-sepolia-testnet.skalenodes.com/v1/jubilant-horrible-ancha',\n [ETHEREUM_MAINNET]: 'https://eth.llamarpc.com',\n};\n\n/**\n * USDC contract addresses by chain.\n * Source of truth: dexter-facilitator/src/config/chains.ts\n */\nexport const USDC_ADDRESSES: Record<string, string> = {\n [BASE_MAINNET]: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\n [BASE_SEPOLIA]: '0x036CbD53842c5426634e7929541eC2318f3dCF7e',\n [ARBITRUM_ONE]: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',\n [POLYGON]: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',\n [OPTIMISM]: '0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85',\n [AVALANCHE]: '0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E',\n [SKALE_BASE]: '0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20',\n [SKALE_BASE_SEPOLIA]: '0x2e08028E3C4c2356572E096d8EF835cD5C6030bD',\n [ETHEREUM_MAINNET]: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',\n};\n\n/**\n * EVM wallet interface (compatible with wagmi, ethers, viem)\n */\nexport interface EvmWallet {\n /** Wallet address */\n address: string;\n /** Chain ID currently connected to */\n chainId?: number;\n /**\n * Sign typed data (EIP-712)\n * This is the primary signing method for x402 EVM payments\n */\n signTypedData?(params: {\n domain: Record<string, unknown>;\n types: Record<string, unknown[]>;\n primaryType: string;\n message: Record<string, unknown>;\n }): Promise<string>;\n /**\n * Alternative: Send transaction directly\n * Used if signTypedData is not available\n */\n sendTransaction?(params: {\n to: string;\n data: string;\n value?: bigint;\n }): Promise<string>;\n}\n\n/**\n * Check if an object is a valid EVM wallet\n */\nexport function isEvmWallet(wallet: unknown): wallet is EvmWallet {\n if (!wallet || typeof wallet !== 'object') return false;\n const w = wallet as Record<string, unknown>;\n return (\n 'address' in w &&\n typeof w.address === 'string' &&\n w.address.startsWith('0x')\n );\n}\n\n// ERC20 balanceOf function selector: 0x70a08231\n\n/**\n * EVM Chain Adapter\n */\nexport class EvmAdapter implements ChainAdapter {\n readonly name = 'EVM';\n readonly networks = [BASE_MAINNET, BASE_SEPOLIA, ETHEREUM_MAINNET, ARBITRUM_ONE];\n\n private config: AdapterConfig;\n private log: (...args: unknown[]) => void;\n\n constructor(config: AdapterConfig = {}) {\n this.config = config;\n this.log = config.verbose\n ? console.log.bind(console, '[x402:evm]')\n : () => {};\n }\n\n canHandle(network: string): boolean {\n // Handle exact CAIP-2\n if (this.networks.includes(network)) return true;\n // Legacy format\n if (network === 'base') return true;\n if (network === 'ethereum') return true;\n if (network === 'arbitrum') return true;\n // Check if it starts with 'eip155:'\n if (network.startsWith('eip155:')) return true;\n return false;\n }\n\n getDefaultRpcUrl(network: string): string {\n if (this.config.rpcUrls?.[network]) {\n return this.config.rpcUrls[network];\n }\n if (DEFAULT_RPC_URLS[network]) {\n return DEFAULT_RPC_URLS[network];\n }\n // Normalize legacy\n if (network === 'base') return DEFAULT_RPC_URLS[BASE_MAINNET];\n if (network === 'ethereum') return DEFAULT_RPC_URLS[ETHEREUM_MAINNET];\n if (network === 'arbitrum') return DEFAULT_RPC_URLS[ARBITRUM_ONE];\n return DEFAULT_RPC_URLS[BASE_MAINNET];\n }\n\n getAddress(wallet: unknown): string | null {\n if (!isEvmWallet(wallet)) return null;\n return wallet.address;\n }\n\n isConnected(wallet: unknown): boolean {\n if (!isEvmWallet(wallet)) return false;\n return !!wallet.address;\n }\n\n private getChainId(network: string): number {\n if (CHAIN_IDS[network]) return CHAIN_IDS[network];\n // Try to extract from CAIP-2\n if (network.startsWith('eip155:')) {\n const chainIdStr = network.split(':')[1];\n return parseInt(chainIdStr, 10);\n }\n // Defaults\n if (network === 'base') return 8453;\n if (network === 'ethereum') return 1;\n if (network === 'arbitrum') return 42161;\n return 8453; // Default to Base\n }\n\n async getBalance(\n accept: PaymentAccept,\n wallet: unknown,\n rpcUrl?: string\n ): Promise<number> {\n if (!isEvmWallet(wallet) || !wallet.address) {\n return 0;\n }\n\n const url = rpcUrl || this.getDefaultRpcUrl(accept.network);\n\n try {\n // Use eth_call to check ERC20 balance\n const data = this.encodeBalanceOf(wallet.address);\n const response = 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_call',\n params: [\n {\n to: accept.asset,\n data,\n },\n 'latest',\n ],\n }),\n });\n\n const result = (await response.json()) as { error?: unknown; result?: string };\n if (result.error || !result.result) {\n return 0;\n }\n\n const balance = BigInt(result.result);\n const decimals = accept.extra?.decimals ?? 6;\n return Number(balance) / Math.pow(10, decimals);\n } catch {\n return 0;\n }\n }\n\n private encodeBalanceOf(address: string): string {\n // Function selector for balanceOf(address)\n const selector = '0x70a08231';\n // Pad address to 32 bytes\n const paddedAddress = address.slice(2).toLowerCase().padStart(64, '0');\n return selector + paddedAddress;\n }\n\n async buildTransaction(\n accept: PaymentAccept,\n wallet: unknown,\n _rpcUrl?: string\n ): Promise<SignedTransaction> {\n if (!isEvmWallet(wallet)) {\n throw new Error('Invalid EVM wallet');\n }\n if (!wallet.address) {\n throw new Error('Wallet not connected');\n }\n\n const { payTo, asset, extra } = accept;\n // amount is the v2 spec field, maxAmountRequired is v1 fallback\n const amount = accept.amount ?? accept.maxAmountRequired;\n if (!amount) {\n throw new Error('Missing amount in payment requirements');\n }\n\n this.log('Building EVM transaction:', {\n from: wallet.address,\n to: payTo,\n amount,\n asset,\n network: accept.network,\n });\n\n // For x402 v2 EVM payments, we use EIP-712 typed data signing\n // The facilitator will execute the transfer on behalf of the user\n\n const chainId = this.getChainId(accept.network);\n\n // Build the EIP-712 typed data\n // This matches what Dexter's facilitator expects\n const domain = {\n name: extra?.name ?? 'USD Coin',\n version: extra?.version ?? '2',\n chainId: BigInt(chainId),\n verifyingContract: asset as `0x${string}`,\n };\n\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 // Generate a cryptographically secure random nonce (32 bytes hex)\n const nonceBytes = new Uint8Array(32);\n (globalThis.crypto ?? (await import('crypto')).webcrypto).getRandomValues(nonceBytes);\n const nonce = ('0x' + [...nonceBytes].map(b => b.toString(16).padStart(2, '0')).join('')) as `0x${string}`;\n\n const now = Math.floor(Date.now() / 1000);\n \n // Authorization object - values as strings for JSON, BigInts for signing\n const authorization = {\n from: wallet.address,\n to: payTo,\n value: amount, // string\n validAfter: String(now - 600), // 10 minutes before (matching upstream)\n validBefore: String(now + (accept.maxTimeoutSeconds || 60)),\n nonce,\n };\n\n // Message for signing uses BigInt values\n const message = {\n from: wallet.address,\n to: payTo,\n value: BigInt(amount),\n validAfter: BigInt(now - 600),\n validBefore: BigInt(now + (accept.maxTimeoutSeconds || 60)),\n nonce,\n };\n\n if (!wallet.signTypedData) {\n throw new Error('Wallet does not support signTypedData (EIP-712)');\n }\n\n const signature = await wallet.signTypedData({\n domain: domain as Record<string, unknown>,\n types: types as Record<string, unknown[]>,\n primaryType: 'TransferWithAuthorization',\n message: message as Record<string, unknown>,\n });\n\n this.log('EIP-712 signature obtained');\n\n // Payload structure matches upstream @x402/evm exactly\n const payload = {\n authorization,\n signature,\n };\n\n return {\n serialized: JSON.stringify(payload),\n signature,\n };\n }\n}\n\n/**\n * Create an EVM adapter instance\n */\nexport function createEvmAdapter(config?: AdapterConfig): EvmAdapter {\n return new EvmAdapter(config);\n}\n\n","/**\n * Chain Adapters\n *\n * x402 v2 is designed to be chain-agnostic. Each adapter handles\n * the specifics of transaction building and signing for its chain.\n *\n * @example\n * ```typescript\n * import { createSolanaAdapter, createEvmAdapter } from '@dexterai/x402/adapters';\n *\n * const adapters = [\n * createSolanaAdapter(),\n * createEvmAdapter(),\n * ];\n *\n * // Find adapter for a network\n * const adapter = adapters.find(a => a.canHandle('eip155:8453'));\n * ```\n */\n\nimport { createSolanaAdapter as _createSolanaAdapter } from './solana';\nimport { createEvmAdapter as _createEvmAdapter } from './evm';\nimport { USDC_ADDRESSES as _USDC_ADDRESSES } from './evm';\n\n// Types\nexport type {\n ChainAdapter,\n AdapterConfig,\n SignedTransaction,\n GenericWallet,\n WalletSet,\n BalanceInfo,\n} from './types';\n\n// Solana\nexport {\n SolanaAdapter,\n createSolanaAdapter,\n isSolanaWallet,\n SOLANA_MAINNET,\n SOLANA_DEVNET,\n SOLANA_TESTNET,\n} from './solana';\nexport type { SolanaWallet } from './solana';\n\n// EVM\nexport {\n EvmAdapter,\n createEvmAdapter,\n isEvmWallet,\n BASE_MAINNET,\n BASE_SEPOLIA,\n ARBITRUM_ONE,\n POLYGON,\n OPTIMISM,\n AVALANCHE,\n SKALE_BASE,\n SKALE_BASE_SEPOLIA,\n ETHEREUM_MAINNET,\n USDC_ADDRESSES,\n} from './evm';\nexport type { EvmWallet } from './evm';\n\n/**\n * Check if an asset address is a known USDC contract (any chain).\n * Single source of truth for decimal inference in the client.\n */\nexport function isKnownUSDC(asset: string): boolean {\n // Solana mints\n if (asset === 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v') return true; // mainnet\n if (asset === '4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU') return true; // devnet\n // All EVM USDC addresses (case-insensitive for EVM)\n const lc = asset.toLowerCase();\n for (const addr of Object.values(_USDC_ADDRESSES)) {\n if (addr.toLowerCase() === lc) return true;\n }\n return false;\n}\n\n/**\n * Create all default adapters\n */\nexport function createDefaultAdapters(verbose = false) {\n return [\n _createSolanaAdapter({ verbose }),\n _createEvmAdapter({ verbose }),\n ];\n}\n\n/**\n * Find adapter that can handle a network\n */\nexport function findAdapter(\n adapters: import('./types').ChainAdapter[],\n network: string\n): import('./types').ChainAdapter | undefined {\n return adapters.find(adapter => adapter.canHandle(network));\n}\n\n\n\n"],"mappings":"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","names":["DEFAULT_RPC_URLS"]}
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __esm = (fn, res) => function __init() {
7
9
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
@@ -18,6 +20,14 @@ var __copyProps = (to, from, except, desc) => {
18
20
  }
19
21
  return to;
20
22
  };
23
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
24
+ // If the importer is in node compatibility mode or this is not an ESM
25
+ // file that has been converted to a CommonJS file using a Babel-
26
+ // compatible transform (i.e. "__esModule" has not been set), then set
27
+ // "default" to the CommonJS "module.exports" for node compatibility.
28
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
29
+ mod
30
+ ));
21
31
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
22
32
 
23
33
  // node_modules/base-x/src/esm/index.js
@@ -300,7 +310,7 @@ var SolanaAdapter = class {
300
310
  const connection = new import_web3.Connection(url, "confirmed");
301
311
  const userPubkey = new import_web3.PublicKey(wallet.publicKey.toBase58());
302
312
  const { payTo, asset, extra } = accept;
303
- const amount = accept.amount || accept.maxAmountRequired;
313
+ const amount = accept.amount ?? accept.maxAmountRequired;
304
314
  if (!amount) {
305
315
  throw new Error("Missing amount in payment requirements");
306
316
  }
@@ -538,7 +548,7 @@ var EvmAdapter = class {
538
548
  throw new Error("Wallet not connected");
539
549
  }
540
550
  const { payTo, asset, extra } = accept;
541
- const amount = accept.amount || accept.maxAmountRequired;
551
+ const amount = accept.amount ?? accept.maxAmountRequired;
542
552
  if (!amount) {
543
553
  throw new Error("Missing amount in payment requirements");
544
554
  }
@@ -566,7 +576,9 @@ var EvmAdapter = class {
566
576
  { name: "nonce", type: "bytes32" }
567
577
  ]
568
578
  };
569
- const nonce = "0x" + [...Array(32)].map(() => Math.floor(Math.random() * 256).toString(16).padStart(2, "0")).join("");
579
+ const nonceBytes = new Uint8Array(32);
580
+ (globalThis.crypto ?? (await import("crypto")).webcrypto).getRandomValues(nonceBytes);
581
+ const nonce = "0x" + [...nonceBytes].map((b) => b.toString(16).padStart(2, "0")).join("");
570
582
  const now = Math.floor(Date.now() / 1e3);
571
583
  const authorization = {
572
584
  from: wallet.address,
@@ -661,10 +673,11 @@ function createX402Client(config) {
661
673
  const parts = jwt.split(".");
662
674
  if (parts.length === 3) {
663
675
  const payload = JSON.parse(atob(parts[1].replace(/-/g, "+").replace(/_/g, "/")));
664
- if (payload.exp) {
665
- passCache.set(host, { jwt, expiresAt: payload.exp });
666
- log("Access pass cached for", host, "| expires:", new Date(payload.exp * 1e3).toISOString());
667
- }
676
+ const now = Math.floor(Date.now() / 1e3);
677
+ const maxExp = now + 86400;
678
+ const expiresAt = Math.min(typeof payload.exp === "number" ? payload.exp : now, maxExp);
679
+ passCache.set(host, { jwt, expiresAt });
680
+ log("Access pass cached for", host, "| expires:", new Date(expiresAt * 1e3).toISOString());
668
681
  }
669
682
  } catch {
670
683
  log("Failed to cache access pass");
@@ -745,7 +758,7 @@ function createX402Client(config) {
745
758
  if (adapter.name === "Solana" && !accept.extra?.feePayer) return null;
746
759
  const decimals = accept.extra?.decimals ?? (isKnownUSDC(accept.asset) ? 6 : void 0);
747
760
  if (typeof decimals !== "number") return null;
748
- const paymentAmount = accept.amount || accept.maxAmountRequired;
761
+ const paymentAmount = accept.amount ?? accept.maxAmountRequired;
749
762
  if (!paymentAmount) return null;
750
763
  const rpcUrl = getRpcUrl(accept.network, adapter);
751
764
  const balance = await adapter.getBalance(accept, wallet, rpcUrl);
@@ -889,7 +902,7 @@ function createX402Client(config) {
889
902
  "Payment option missing decimals - provide in extra or use a known stablecoin"
890
903
  );
891
904
  }
892
- const paymentAmount = accept.amount || accept.maxAmountRequired;
905
+ const paymentAmount = accept.amount ?? accept.maxAmountRequired;
893
906
  if (!paymentAmount) {
894
907
  throw new X402Error("missing_amount", "Payment option missing amount");
895
908
  }