@dexterai/x402 1.0.1 → 1.0.3

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 (34) hide show
  1. package/README.md +3 -0
  2. package/dist/adapters/index.d.cts +4 -4
  3. package/dist/adapters/index.d.ts +4 -4
  4. package/dist/client/index.cjs +12 -1
  5. package/dist/client/index.cjs.map +1 -1
  6. package/dist/client/index.d.cts +4 -4
  7. package/dist/client/index.d.ts +4 -4
  8. package/dist/client/index.js +12 -1
  9. package/dist/client/index.js.map +1 -1
  10. package/dist/{evm-av6iEAW7.d.ts → evm-C04nksK1.d.ts} +2 -2
  11. package/dist/{evm-B4mhmeNZ.d.cts → evm-Duoj03yG.d.cts} +2 -2
  12. package/dist/react/index.cjs +12 -1
  13. package/dist/react/index.cjs.map +1 -1
  14. package/dist/react/index.d.cts +3 -3
  15. package/dist/react/index.d.ts +3 -3
  16. package/dist/react/index.js +12 -1
  17. package/dist/react/index.js.map +1 -1
  18. package/dist/server/index.cjs.map +1 -1
  19. package/dist/server/index.d.cts +2 -2
  20. package/dist/server/index.d.ts +2 -2
  21. package/dist/server/index.js.map +1 -1
  22. package/dist/{types-vWD8uj2B.d.cts → types-BFqfw6Mp.d.cts} +1 -1
  23. package/dist/{types-DkTxHOns.d.cts → types-CNPXknHK.d.cts} +1 -1
  24. package/dist/{types-DkTxHOns.d.ts → types-CNPXknHK.d.ts} +1 -1
  25. package/dist/{types-uljmYAuY.d.ts → types-DxszTTWX.d.ts} +1 -1
  26. package/dist/utils/index.cjs +110 -0
  27. package/dist/utils/index.cjs.map +1 -0
  28. package/dist/utils/index.d.cts +67 -0
  29. package/dist/utils/index.d.ts +67 -0
  30. package/dist/utils/index.js +79 -0
  31. package/dist/utils/index.js.map +1 -0
  32. package/dist/{x402-client-BSWNMJbm.d.ts → x402-client-CnkVetdK.d.ts} +1 -1
  33. package/dist/{x402-client-DUipGiRr.d.cts → x402-client-XUVndW_S.d.cts} +1 -1
  34. package/package.json +8 -3
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/types.ts","../../src/utils.ts","../../src/server/facilitator-client.ts","../../src/server/x402-server.ts"],"sourcesContent":["/**\n * x402 v2 SDK — Shared Types\n *\n * Chain-agnostic types for x402 v2 payments.\n * Works with Solana, Base, and any future x402-compatible networks.\n */\n\n// ============================================================================\n// Network Constants\n// ============================================================================\n\n/** CAIP-2 network identifier for Solana mainnet */\nexport const SOLANA_MAINNET_NETWORK = 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp';\n\n/** CAIP-2 network identifier for Base mainnet */\nexport const BASE_MAINNET_NETWORK = 'eip155:8453';\n\n/** Alias for Solana mainnet */\nexport const SOLANA_MAINNET = SOLANA_MAINNET_NETWORK;\n\n/** Alias for Base mainnet */\nexport const BASE_MAINNET = BASE_MAINNET_NETWORK;\n\n// ============================================================================\n// Asset Constants\n// ============================================================================\n\n/** USDC mint on Solana mainnet */\nexport const USDC_MINT = 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v';\n\n/** USDC address on Base mainnet */\nexport const USDC_BASE = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913';\n\n// ============================================================================\n// Facilitator Constants\n// ============================================================================\n\n/** Dexter's public x402 v2 facilitator URL */\nexport const DEXTER_FACILITATOR_URL = 'https://x402.dexter.cash';\n\n// ============================================================================\n// Payment Types\n// ============================================================================\n\n/**\n * Asset configuration for payments\n */\nexport interface AssetConfig {\n /** Token address (mint on Solana, contract on EVM) */\n address: string;\n /** Token decimals */\n decimals: number;\n /** Optional: Human-readable symbol */\n symbol?: string;\n}\n\n/**\n * Resource info included in payment requirements\n */\nexport interface ResourceInfo {\n /** Resource URL */\n url: string;\n /** Human-readable description */\n description?: string;\n /** MIME type of the resource */\n mimeType?: string;\n}\n\n/**\n * Extra fields in payment requirements\n * Chain-specific fields may vary\n */\nexport interface AcceptsExtra {\n /** Facilitator address that pays tx fees (required) */\n feePayer: string;\n /** Token decimals (required) */\n decimals: number;\n /** EIP-712: Token name (EVM only) */\n name?: string;\n /** EIP-712: Token version (EVM only) */\n version?: string;\n /** Additional chain-specific fields */\n [key: string]: unknown;\n}\n\n/**\n * A single payment option in the accepts array\n */\nexport interface PaymentAccept {\n /** Payment scheme (always 'exact' for x402 v2) */\n scheme: 'exact';\n /** CAIP-2 network identifier */\n network: string;\n /** Payment amount in atomic units (as string to avoid precision loss) */\n amount: string;\n /** Token address */\n asset: string;\n /** Seller's address to receive payment */\n payTo: string;\n /** Maximum seconds until payment expires */\n maxTimeoutSeconds: number;\n /** Chain-specific extra data */\n extra: AcceptsExtra;\n}\n\n/**\n * Full PaymentRequired structure (sent in PAYMENT-REQUIRED header)\n */\nexport interface PaymentRequired {\n /** x402 version (always 2) */\n x402Version: 2;\n /** Resource being accessed */\n resource: ResourceInfo;\n /** Available payment options */\n accepts: PaymentAccept[];\n /** Optional error message */\n error?: string;\n}\n\n/**\n * PaymentSignature structure (sent in PAYMENT-SIGNATURE header)\n */\nexport interface PaymentSignature {\n /** x402 version (always 2) */\n x402Version: 2;\n /** Resource being accessed */\n resource: ResourceInfo;\n /** The payment option that was accepted */\n accepted: PaymentAccept;\n /** The signed payment */\n payload: {\n /** Signed transaction (base64 for Solana, JSON for EVM) */\n transaction: string;\n };\n}\n\n// ============================================================================\n// Facilitator Response Types\n// ============================================================================\n\n/**\n * Response from /verify endpoint\n */\nexport interface VerifyResponse {\n /** Whether the payment is valid */\n isValid: boolean;\n /** Reason for invalidity (if invalid) */\n invalidReason?: string;\n /** Payer address */\n payer?: string;\n}\n\n/**\n * Response from /settle endpoint\n */\nexport interface SettleResponse {\n /** Whether settlement succeeded */\n success: boolean;\n /** Transaction signature/hash */\n transaction?: string;\n /** Network the payment was made on */\n network: string;\n /** Error reason (if failed) */\n errorReason?: string;\n /** Error code (if failed) */\n errorCode?: string;\n /** Payer address */\n payer?: string;\n}\n\n// ============================================================================\n// Error Types\n// ============================================================================\n\n/**\n * SDK error codes\n */\nexport type X402ErrorCode =\n // Client errors\n | 'missing_payment_required_header'\n | 'invalid_payment_required'\n | 'unsupported_network'\n | 'no_matching_payment_option'\n | 'no_solana_accept' // Legacy, kept for compatibility\n | 'missing_fee_payer'\n | 'missing_decimals'\n | 'amount_exceeds_max'\n | 'wallet_missing_sign_transaction'\n | 'wallet_not_connected'\n | 'transaction_build_failed'\n | 'payment_rejected'\n // Server errors\n | 'invalid_payment_signature'\n | 'facilitator_verify_failed'\n | 'facilitator_settle_failed'\n | 'facilitator_request_failed'\n | 'no_matching_requirement';\n\n/**\n * Custom error class for x402 operations\n */\nexport class X402Error extends Error {\n /** Error code for programmatic handling */\n code: X402ErrorCode;\n /** Additional error details */\n details?: unknown;\n\n constructor(code: X402ErrorCode, message: string, details?: unknown) {\n super(message);\n this.name = 'X402Error';\n this.code = code;\n this.details = details;\n // Maintain proper prototype chain\n Object.setPrototypeOf(this, X402Error.prototype);\n }\n}\n","/**\n * Utility Functions\n *\n * Chain-agnostic helpers for x402 payments.\n */\n\nimport { SOLANA_MAINNET_NETWORK, BASE_MAINNET_NETWORK } from './types';\n\n// ============================================================================\n// Amount Conversion\n// ============================================================================\n\n/**\n * Convert human-readable amount to atomic units\n *\n * @param amount - Human-readable amount (e.g., 0.05 for $0.05)\n * @param decimals - Token decimals (e.g., 6 for USDC)\n * @returns Amount in atomic units as string\n *\n * @example\n * ```typescript\n * toAtomicUnits(0.05, 6) // '50000'\n * toAtomicUnits(1.50, 6) // '1500000'\n * ```\n */\nexport function toAtomicUnits(amount: number, decimals: number): string {\n const multiplier = Math.pow(10, decimals);\n return Math.floor(amount * multiplier).toString();\n}\n\n/**\n * Convert atomic units to human-readable amount\n *\n * @param atomicUnits - Amount in smallest units\n * @param decimals - Token decimals\n * @returns Human-readable amount\n *\n * @example\n * ```typescript\n * fromAtomicUnits('50000', 6) // 0.05\n * fromAtomicUnits(1500000n, 6) // 1.5\n * ```\n */\nexport function fromAtomicUnits(\n atomicUnits: string | bigint | number,\n decimals: number\n): number {\n const divisor = Math.pow(10, decimals);\n return Number(atomicUnits) / divisor;\n}\n\n// ============================================================================\n// Network Helpers\n// ============================================================================\n\n/**\n * Network type\n */\nexport type ChainFamily = 'solana' | 'evm' | 'unknown';\n\n/**\n * Get the chain family from a CAIP-2 network identifier\n *\n * @param network - CAIP-2 network identifier\n * @returns Chain family\n *\n * @example\n * ```typescript\n * getChainFamily('solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp') // 'solana'\n * getChainFamily('eip155:8453') // 'evm'\n * ```\n */\nexport function getChainFamily(network: string): ChainFamily {\n if (network.startsWith('solana:') || network === 'solana') {\n return 'solana';\n }\n if (network.startsWith('eip155:') || ['base', 'ethereum', 'arbitrum'].includes(network)) {\n return 'evm';\n }\n return 'unknown';\n}\n\n/**\n * Get default RPC URL for a network\n *\n * @param network - CAIP-2 network identifier\n * @returns Default RPC URL\n */\nexport function getDefaultRpcUrl(network: string): string {\n const family = getChainFamily(network);\n\n if (family === 'solana') {\n if (network.includes('devnet') || network === 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1') {\n return 'https://api.devnet.solana.com';\n }\n if (network.includes('testnet') || network === 'solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z') {\n return 'https://api.testnet.solana.com';\n }\n return 'https://api.mainnet-beta.solana.com';\n }\n\n if (family === 'evm') {\n // Extract chain ID from CAIP-2\n if (network.startsWith('eip155:')) {\n const chainId = network.split(':')[1];\n switch (chainId) {\n case '8453': return 'https://mainnet.base.org';\n case '84532': return 'https://sepolia.base.org';\n case '1': return 'https://eth.llamarpc.com';\n case '42161': return 'https://arb1.arbitrum.io/rpc';\n default: return 'https://mainnet.base.org';\n }\n }\n // Legacy names\n if (network === 'base') return 'https://mainnet.base.org';\n if (network === 'ethereum') return 'https://eth.llamarpc.com';\n if (network === 'arbitrum') return 'https://arb1.arbitrum.io/rpc';\n return 'https://mainnet.base.org';\n }\n\n // Unknown - return a generic\n return 'https://api.mainnet-beta.solana.com';\n}\n\n/**\n * Get human-readable chain name\n *\n * @param network - CAIP-2 network identifier\n * @returns Human-readable name\n */\nexport function getChainName(network: string): string {\n const mapping: Record<string, string> = {\n [SOLANA_MAINNET_NETWORK]: 'Solana',\n 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1': 'Solana Devnet',\n 'solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z': 'Solana Testnet',\n 'solana': 'Solana',\n [BASE_MAINNET_NETWORK]: 'Base',\n 'eip155:84532': 'Base Sepolia',\n 'eip155:1': 'Ethereum',\n 'eip155:42161': 'Arbitrum One',\n 'base': 'Base',\n 'ethereum': 'Ethereum',\n 'arbitrum': 'Arbitrum',\n };\n return mapping[network] || network;\n}\n\n// ============================================================================\n// Transaction URL Helpers\n// ============================================================================\n\n/**\n * Get explorer URL for a transaction\n *\n * @param txSignature - Transaction signature/hash\n * @param network - CAIP-2 network identifier\n * @returns Explorer URL\n */\nexport function getExplorerUrl(txSignature: string, network: string): string {\n const family = getChainFamily(network);\n\n if (family === 'solana') {\n const isDevnet = network.includes('devnet') || network === 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1';\n if (isDevnet) {\n return `https://solscan.io/tx/${txSignature}?cluster=devnet`;\n }\n // Prefer Orb Markets for mainnet\n return `https://www.orbmarkets.io/tx/${txSignature}`;\n }\n\n if (family === 'evm') {\n // Extract chain ID\n let chainId = '8453'; // Default to Base\n if (network.startsWith('eip155:')) {\n chainId = network.split(':')[1];\n } else if (network === 'ethereum') {\n chainId = '1';\n } else if (network === 'arbitrum') {\n chainId = '42161';\n }\n\n switch (chainId) {\n case '8453': return `https://basescan.org/tx/${txSignature}`;\n case '84532': return `https://sepolia.basescan.org/tx/${txSignature}`;\n case '1': return `https://etherscan.io/tx/${txSignature}`;\n case '42161': return `https://arbiscan.io/tx/${txSignature}`;\n default: return `https://basescan.org/tx/${txSignature}`;\n }\n }\n\n return `https://solscan.io/tx/${txSignature}`;\n}\n\n// ============================================================================\n// Encoding Helpers\n// ============================================================================\n\n/**\n * Encode an object as base64 JSON\n */\nexport function encodeBase64Json(obj: unknown): string {\n return btoa(JSON.stringify(obj));\n}\n\n/**\n * Decode base64 JSON to object\n */\nexport function decodeBase64Json<T>(encoded: string): T {\n return JSON.parse(atob(encoded)) as T;\n}\n","/**\n * Facilitator Client\n *\n * Communicates with the x402 facilitator for:\n * - /supported - Get supported payment schemes and fee payer addresses\n * - /verify - Verify a payment signature before processing\n * - /settle - Submit the payment for execution\n *\n * Works with any x402 v2 facilitator (Dexter or others).\n */\n\nimport type { PaymentAccept, PaymentSignature, VerifyResponse, SettleResponse } from '../types';\nimport { DEXTER_FACILITATOR_URL } from '../types';\nimport { decodeBase64Json } from '../utils';\n\n/**\n * Supported payment kind from facilitator /supported endpoint\n */\nexport interface SupportedKind {\n x402Version: number;\n scheme: string;\n network: string;\n extra?: {\n feePayer?: string;\n decimals?: number;\n name?: string;\n version?: string;\n [key: string]: unknown;\n };\n}\n\n/**\n * Response from facilitator /supported endpoint\n */\nexport interface SupportedResponse {\n kinds: SupportedKind[];\n}\n\n/**\n * Client for communicating with an x402 v2 facilitator\n */\nexport class FacilitatorClient {\n private facilitatorUrl: string;\n private cachedSupported: SupportedResponse | null = null;\n private cacheTime: number = 0;\n private readonly CACHE_TTL_MS = 60_000; // 1 minute cache\n\n constructor(facilitatorUrl: string = DEXTER_FACILITATOR_URL) {\n this.facilitatorUrl = facilitatorUrl.replace(/\\/$/, ''); // Remove trailing slash\n }\n\n /**\n * Get supported payment kinds from the facilitator\n * Results are cached for 1 minute to reduce network calls\n */\n async getSupported(): Promise<SupportedResponse> {\n const now = Date.now();\n if (this.cachedSupported && now - this.cacheTime < this.CACHE_TTL_MS) {\n return this.cachedSupported;\n }\n\n const response = await fetch(`${this.facilitatorUrl}/supported`);\n if (!response.ok) {\n throw new Error(`Facilitator /supported returned ${response.status}`);\n }\n\n this.cachedSupported = (await response.json()) as SupportedResponse;\n this.cacheTime = now;\n return this.cachedSupported;\n }\n\n /**\n * Get the fee payer address for a specific network\n *\n * @param network - CAIP-2 network identifier\n * @returns Fee payer address\n */\n async getFeePayer(network: string): Promise<string> {\n const supported = await this.getSupported();\n\n // Find matching network support (exact match or v2)\n const kind = supported.kinds.find(\n (k) =>\n k.x402Version === 2 &&\n k.scheme === 'exact' &&\n k.network === network\n );\n\n if (!kind?.extra?.feePayer) {\n throw new Error(\n `Facilitator does not support network \"${network}\" with scheme \"exact\", or feePayer not provided`\n );\n }\n\n return kind.extra.feePayer;\n }\n\n /**\n * Get extra data for a network (feePayer, decimals, EIP-712 data, etc.)\n *\n * @param network - CAIP-2 network identifier\n * @returns Extra data from /supported\n */\n async getNetworkExtra(network: string): Promise<SupportedKind['extra']> {\n const supported = await this.getSupported();\n\n const kind = supported.kinds.find(\n (k) =>\n k.x402Version === 2 &&\n k.scheme === 'exact' &&\n k.network === network\n );\n\n return kind?.extra;\n }\n\n /**\n * Verify a payment with the facilitator\n *\n * @param paymentSignatureHeader - Base64-encoded PAYMENT-SIGNATURE header value\n * @param requirements - The payment requirements that were sent to the client\n * @returns Verification response\n */\n async verifyPayment(\n paymentSignatureHeader: string,\n requirements: PaymentAccept\n ): Promise<VerifyResponse> {\n try {\n const paymentPayload = decodeBase64Json<PaymentSignature>(paymentSignatureHeader);\n\n const verifyPayload = {\n paymentPayload,\n paymentRequirements: requirements,\n };\n\n const response = await fetch(`${this.facilitatorUrl}/verify`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(verifyPayload),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n console.error(`Facilitator /verify returned ${response.status}:`, errorText);\n return {\n isValid: false,\n invalidReason: `facilitator_error_${response.status}`,\n };\n }\n\n return (await response.json()) as VerifyResponse;\n } catch (error) {\n console.error('Payment verification failed:', error);\n return {\n isValid: false,\n invalidReason: error instanceof Error ? error.message : 'unexpected_verify_error',\n };\n }\n }\n\n /**\n * Settle a payment with the facilitator\n *\n * @param paymentSignatureHeader - Base64-encoded PAYMENT-SIGNATURE header value\n * @param requirements - The payment requirements that were sent to the client\n * @returns Settlement response with transaction signature on success\n */\n async settlePayment(\n paymentSignatureHeader: string,\n requirements: PaymentAccept\n ): Promise<SettleResponse> {\n try {\n const paymentPayload = decodeBase64Json<PaymentSignature>(paymentSignatureHeader);\n\n const settlePayload = {\n paymentPayload,\n paymentRequirements: requirements,\n };\n\n const response = await fetch(`${this.facilitatorUrl}/settle`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(settlePayload),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n console.error(`Facilitator /settle returned ${response.status}:`, errorText);\n return {\n success: false,\n network: requirements.network,\n errorReason: `facilitator_error_${response.status}`,\n };\n }\n\n const result = (await response.json()) as SettleResponse;\n return {\n ...result,\n network: requirements.network,\n };\n } catch (error) {\n console.error('Payment settlement failed:', error);\n return {\n success: false,\n network: requirements.network,\n errorReason: error instanceof Error ? error.message : 'unexpected_settle_error',\n };\n }\n }\n}\n","/**\n * x402 v2 Server\n *\n * Server-side helpers for accepting x402 payments.\n * Chain-agnostic - works with Solana, Base, and any x402-compatible network.\n *\n * @example\n * ```typescript\n * import { createX402Server } from '@dexterai/x402/server';\n *\n * const server = createX402Server({\n * payTo: 'YourAddress...',\n * network: 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp',\n * });\n *\n * // Handle 402 responses\n * if (!paymentSignature) {\n * const requirements = await server.buildRequirements({\n * amountAtomic: '50000',\n * resourceUrl: '/api/protected',\n * });\n * res.setHeader('PAYMENT-REQUIRED', server.encodeRequirements(requirements));\n * res.status(402).json({});\n * return;\n * }\n *\n * // Verify and settle\n * const verify = await server.verifyPayment(paymentSignature);\n * if (!verify.isValid) throw new Error(verify.invalidReason);\n *\n * const settle = await server.settlePayment(paymentSignature);\n * if (!settle.success) throw new Error(settle.errorReason);\n *\n * // Payment successful!\n * res.json({ transaction: settle.transaction });\n * ```\n */\n\nimport type {\n PaymentRequired,\n PaymentAccept,\n ResourceInfo,\n AcceptsExtra,\n VerifyResponse,\n SettleResponse,\n} from '../types';\nimport {\n SOLANA_MAINNET_NETWORK,\n USDC_MINT,\n DEXTER_FACILITATOR_URL,\n} from '../types';\nimport { FacilitatorClient, type SupportedKind } from './facilitator-client';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Asset configuration\n */\nexport interface AssetConfig {\n /** Token address (mint on Solana, contract on EVM) */\n address: string;\n /** Token decimals */\n decimals: number;\n}\n\n/**\n * Server configuration\n */\nexport interface X402ServerConfig {\n /** Address to receive payments */\n payTo: string;\n /** Facilitator URL (defaults to Dexter) */\n facilitatorUrl?: string;\n /** CAIP-2 network identifier */\n network?: string;\n /** Asset configuration (defaults to USDC) */\n asset?: AssetConfig;\n /** Default payment timeout in seconds */\n defaultTimeoutSeconds?: number;\n}\n\n/**\n * Options for building payment requirements\n */\nexport interface BuildRequirementsOptions {\n /** Amount in atomic units (e.g., '50000' for 0.05 USDC) */\n amountAtomic: string;\n /** Full URL of the resource */\n resourceUrl: string;\n /** Human-readable description */\n description?: string;\n /** MIME type of the response */\n mimeType?: string;\n /** Override timeout for this request */\n timeoutSeconds?: number;\n}\n\n/**\n * x402 Server interface\n */\nexport interface X402Server {\n /** Build payment requirements (fetches feePayer from facilitator) */\n buildRequirements(options: BuildRequirementsOptions): Promise<PaymentRequired>;\n\n /** Encode requirements for PAYMENT-REQUIRED header */\n encodeRequirements(requirements: PaymentRequired): string;\n\n /** Create complete 402 response object */\n create402Response(requirements: PaymentRequired): {\n status: 402;\n headers: { 'PAYMENT-REQUIRED': string };\n body: Record<string, unknown>;\n };\n\n /** Verify payment with facilitator */\n verifyPayment(\n paymentSignatureHeader: string,\n requirements?: PaymentAccept\n ): Promise<VerifyResponse>;\n\n /** Settle payment via facilitator */\n settlePayment(\n paymentSignatureHeader: string,\n requirements?: PaymentAccept\n ): Promise<SettleResponse>;\n\n /** Get PaymentAccept for verify/settle */\n getPaymentAccept(options: BuildRequirementsOptions): Promise<PaymentAccept>;\n\n /** Get network this server is configured for */\n readonly network: string;\n\n /** Get facilitator client for advanced usage */\n readonly facilitator: FacilitatorClient;\n}\n\n// ============================================================================\n// Implementation\n// ============================================================================\n\n/**\n * Create an x402 server for accepting payments\n */\nexport function createX402Server(config: X402ServerConfig): X402Server {\n const {\n payTo,\n facilitatorUrl = DEXTER_FACILITATOR_URL,\n network = SOLANA_MAINNET_NETWORK,\n asset = { address: USDC_MINT, decimals: 6 },\n defaultTimeoutSeconds = 60,\n } = config;\n\n const facilitator = new FacilitatorClient(facilitatorUrl);\n\n // Cache for network extra data\n let cachedExtra: SupportedKind['extra'] | null = null;\n\n /**\n * Get extra data from facilitator (cached)\n */\n async function getNetworkExtra(): Promise<AcceptsExtra> {\n if (!cachedExtra) {\n cachedExtra = await facilitator.getNetworkExtra(network);\n }\n\n if (!cachedExtra?.feePayer) {\n throw new Error(`Facilitator does not provide feePayer for network \"${network}\"`);\n }\n\n return {\n feePayer: cachedExtra.feePayer,\n decimals: cachedExtra.decimals ?? asset.decimals,\n // Include any additional EIP-712 data for EVM chains\n name: cachedExtra.name,\n version: cachedExtra.version,\n };\n }\n\n /**\n * Build a PaymentAccept structure\n */\n async function getPaymentAccept(options: BuildRequirementsOptions): Promise<PaymentAccept> {\n const {\n amountAtomic,\n timeoutSeconds = defaultTimeoutSeconds,\n } = options;\n\n const extra = await getNetworkExtra();\n\n return {\n scheme: 'exact',\n network,\n amount: amountAtomic,\n asset: asset.address,\n payTo,\n maxTimeoutSeconds: timeoutSeconds,\n extra,\n };\n }\n\n /**\n * Build payment requirements for a 402 response\n */\n async function buildRequirements(options: BuildRequirementsOptions): Promise<PaymentRequired> {\n const {\n resourceUrl,\n description,\n mimeType = 'application/json',\n } = options;\n\n const resource: ResourceInfo = {\n url: resourceUrl,\n description,\n mimeType,\n };\n\n const accept = await getPaymentAccept(options);\n\n return {\n x402Version: 2,\n resource,\n accepts: [accept],\n error: 'Payment required',\n };\n }\n\n /**\n * Encode requirements for PAYMENT-REQUIRED header\n */\n function encodeRequirements(requirements: PaymentRequired): string {\n return btoa(JSON.stringify(requirements));\n }\n\n /**\n * Create complete 402 response object\n */\n function create402Response(requirements: PaymentRequired) {\n return {\n status: 402 as const,\n headers: {\n 'PAYMENT-REQUIRED': encodeRequirements(requirements),\n },\n body: {},\n };\n }\n\n /**\n * Verify payment with facilitator\n */\n async function verifyPayment(\n paymentSignatureHeader: string,\n requirements?: PaymentAccept\n ): Promise<VerifyResponse> {\n // If requirements not provided, build default\n const req = requirements || await getPaymentAccept({\n amountAtomic: '0',\n resourceUrl: '',\n });\n\n return facilitator.verifyPayment(paymentSignatureHeader, req);\n }\n\n /**\n * Settle payment via facilitator\n */\n async function settlePayment(\n paymentSignatureHeader: string,\n requirements?: PaymentAccept\n ): Promise<SettleResponse> {\n const req = requirements || await getPaymentAccept({\n amountAtomic: '0',\n resourceUrl: '',\n });\n\n return facilitator.settlePayment(paymentSignatureHeader, req);\n }\n\n return {\n buildRequirements,\n encodeRequirements,\n create402Response,\n verifyPayment,\n settlePayment,\n getPaymentAccept,\n network,\n facilitator,\n };\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/types.ts","../../src/utils.ts","../../src/server/facilitator-client.ts","../../src/server/x402-server.ts"],"sourcesContent":["/**\n * x402 v2 SDK — Shared Types\n *\n * Chain-agnostic types for x402 v2 payments.\n * Works with Solana, Base, and any future x402-compatible networks.\n */\n\n// ============================================================================\n// Network Constants\n// ============================================================================\n\n/** CAIP-2 network identifier for Solana mainnet */\nexport const SOLANA_MAINNET_NETWORK = 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp';\n\n/** CAIP-2 network identifier for Base mainnet */\nexport const BASE_MAINNET_NETWORK = 'eip155:8453';\n\n/** Alias for Solana mainnet */\nexport const SOLANA_MAINNET = SOLANA_MAINNET_NETWORK;\n\n/** Alias for Base mainnet */\nexport const BASE_MAINNET = BASE_MAINNET_NETWORK;\n\n// ============================================================================\n// Asset Constants\n// ============================================================================\n\n/** USDC mint on Solana mainnet */\nexport const USDC_MINT = 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v';\n\n/** USDC address on Base mainnet */\nexport const USDC_BASE = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913';\n\n// ============================================================================\n// Facilitator Constants\n// ============================================================================\n\n/** Dexter's public x402 v2 facilitator URL */\nexport const DEXTER_FACILITATOR_URL = 'https://x402.dexter.cash';\n\n// ============================================================================\n// Payment Types\n// ============================================================================\n\n/**\n * Asset configuration for payments\n */\nexport interface AssetConfig {\n /** Token address (mint on Solana, contract on EVM) */\n address: string;\n /** Token decimals */\n decimals: number;\n /** Optional: Human-readable symbol */\n symbol?: string;\n}\n\n/**\n * Resource info included in payment requirements\n */\nexport interface ResourceInfo {\n /** Resource URL */\n url: string;\n /** Human-readable description */\n description?: string;\n /** MIME type of the resource */\n mimeType?: string;\n}\n\n/**\n * Extra fields in payment requirements\n * Chain-specific fields may vary\n */\nexport interface AcceptsExtra {\n /** Facilitator address that pays tx fees (required) */\n feePayer: string;\n /** Token decimals (required) */\n decimals: number;\n /** EIP-712: Token name (EVM only) */\n name?: string;\n /** EIP-712: Token version (EVM only) */\n version?: string;\n /** Additional chain-specific fields */\n [key: string]: unknown;\n}\n\n/**\n * A single payment option in the accepts array\n */\nexport interface PaymentAccept {\n /** Payment scheme (always 'exact' for x402 v2) */\n scheme: 'exact';\n /** CAIP-2 network identifier */\n network: string;\n /** Payment amount in atomic units (as string to avoid precision loss) */\n amount: string;\n /** Token address */\n asset: string;\n /** Seller's address to receive payment */\n payTo: string;\n /** Maximum seconds until payment expires */\n maxTimeoutSeconds: number;\n /** Chain-specific extra data */\n extra: AcceptsExtra;\n}\n\n/**\n * Full PaymentRequired structure (sent in PAYMENT-REQUIRED header)\n */\nexport interface PaymentRequired {\n /** x402 version (always 2) */\n x402Version: 2;\n /** Resource being accessed */\n resource: ResourceInfo;\n /** Available payment options */\n accepts: PaymentAccept[];\n /** Optional error message */\n error?: string;\n}\n\n/**\n * PaymentSignature structure (sent in PAYMENT-SIGNATURE header)\n */\nexport interface PaymentSignature {\n /** x402 version (always 2) */\n x402Version: 2;\n /** Resource being accessed */\n resource: ResourceInfo;\n /** The payment option that was accepted */\n accepted: PaymentAccept;\n /** The signed payment */\n payload: {\n /** Signed transaction (base64 for Solana, JSON for EVM) */\n transaction: string;\n };\n}\n\n// ============================================================================\n// Facilitator Response Types\n// ============================================================================\n\n/**\n * Response from /verify endpoint\n */\nexport interface VerifyResponse {\n /** Whether the payment is valid */\n isValid: boolean;\n /** Reason for invalidity (if invalid) */\n invalidReason?: string;\n /** Payer address */\n payer?: string;\n}\n\n/**\n * Response from /settle endpoint\n */\nexport interface SettleResponse {\n /** Whether settlement succeeded */\n success: boolean;\n /** Transaction signature/hash */\n transaction?: string;\n /** Network the payment was made on */\n network: string;\n /** Error reason (if failed) */\n errorReason?: string;\n /** Error code (if failed) */\n errorCode?: string;\n /** Payer address */\n payer?: string;\n}\n\n// ============================================================================\n// Error Types\n// ============================================================================\n\n/**\n * SDK error codes\n */\nexport type X402ErrorCode =\n // Client errors\n | 'missing_payment_required_header'\n | 'invalid_payment_required'\n | 'unsupported_network'\n | 'no_matching_payment_option'\n | 'no_solana_accept' // Legacy, kept for compatibility\n | 'missing_fee_payer'\n | 'missing_decimals'\n | 'amount_exceeds_max'\n | 'insufficient_balance'\n | 'wallet_missing_sign_transaction'\n | 'wallet_not_connected'\n | 'transaction_build_failed'\n | 'payment_rejected'\n // Server errors\n | 'invalid_payment_signature'\n | 'facilitator_verify_failed'\n | 'facilitator_settle_failed'\n | 'facilitator_request_failed'\n | 'no_matching_requirement';\n\n/**\n * Custom error class for x402 operations\n */\nexport class X402Error extends Error {\n /** Error code for programmatic handling */\n code: X402ErrorCode;\n /** Additional error details */\n details?: unknown;\n\n constructor(code: X402ErrorCode, message: string, details?: unknown) {\n super(message);\n this.name = 'X402Error';\n this.code = code;\n this.details = details;\n // Maintain proper prototype chain\n Object.setPrototypeOf(this, X402Error.prototype);\n }\n}\n","/**\n * Utility Functions\n *\n * Chain-agnostic helpers for x402 payments.\n */\n\nimport { SOLANA_MAINNET_NETWORK, BASE_MAINNET_NETWORK } from './types';\n\n// ============================================================================\n// Amount Conversion\n// ============================================================================\n\n/**\n * Convert human-readable amount to atomic units\n *\n * @param amount - Human-readable amount (e.g., 0.05 for $0.05)\n * @param decimals - Token decimals (e.g., 6 for USDC)\n * @returns Amount in atomic units as string\n *\n * @example\n * ```typescript\n * toAtomicUnits(0.05, 6) // '50000'\n * toAtomicUnits(1.50, 6) // '1500000'\n * ```\n */\nexport function toAtomicUnits(amount: number, decimals: number): string {\n const multiplier = Math.pow(10, decimals);\n return Math.floor(amount * multiplier).toString();\n}\n\n/**\n * Convert atomic units to human-readable amount\n *\n * @param atomicUnits - Amount in smallest units\n * @param decimals - Token decimals\n * @returns Human-readable amount\n *\n * @example\n * ```typescript\n * fromAtomicUnits('50000', 6) // 0.05\n * fromAtomicUnits(1500000n, 6) // 1.5\n * ```\n */\nexport function fromAtomicUnits(\n atomicUnits: string | bigint | number,\n decimals: number\n): number {\n const divisor = Math.pow(10, decimals);\n return Number(atomicUnits) / divisor;\n}\n\n// ============================================================================\n// Network Helpers\n// ============================================================================\n\n/**\n * Network type\n */\nexport type ChainFamily = 'solana' | 'evm' | 'unknown';\n\n/**\n * Get the chain family from a CAIP-2 network identifier\n *\n * @param network - CAIP-2 network identifier\n * @returns Chain family\n *\n * @example\n * ```typescript\n * getChainFamily('solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp') // 'solana'\n * getChainFamily('eip155:8453') // 'evm'\n * ```\n */\nexport function getChainFamily(network: string): ChainFamily {\n if (network.startsWith('solana:') || network === 'solana') {\n return 'solana';\n }\n if (network.startsWith('eip155:') || ['base', 'ethereum', 'arbitrum'].includes(network)) {\n return 'evm';\n }\n return 'unknown';\n}\n\n/**\n * Get default RPC URL for a network\n *\n * @param network - CAIP-2 network identifier\n * @returns Default RPC URL\n */\nexport function getDefaultRpcUrl(network: string): string {\n const family = getChainFamily(network);\n\n if (family === 'solana') {\n if (network.includes('devnet') || network === 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1') {\n return 'https://api.devnet.solana.com';\n }\n if (network.includes('testnet') || network === 'solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z') {\n return 'https://api.testnet.solana.com';\n }\n return 'https://api.mainnet-beta.solana.com';\n }\n\n if (family === 'evm') {\n // Extract chain ID from CAIP-2\n if (network.startsWith('eip155:')) {\n const chainId = network.split(':')[1];\n switch (chainId) {\n case '8453': return 'https://mainnet.base.org';\n case '84532': return 'https://sepolia.base.org';\n case '1': return 'https://eth.llamarpc.com';\n case '42161': return 'https://arb1.arbitrum.io/rpc';\n default: return 'https://mainnet.base.org';\n }\n }\n // Legacy names\n if (network === 'base') return 'https://mainnet.base.org';\n if (network === 'ethereum') return 'https://eth.llamarpc.com';\n if (network === 'arbitrum') return 'https://arb1.arbitrum.io/rpc';\n return 'https://mainnet.base.org';\n }\n\n // Unknown - return a generic\n return 'https://api.mainnet-beta.solana.com';\n}\n\n/**\n * Get human-readable chain name\n *\n * @param network - CAIP-2 network identifier\n * @returns Human-readable name\n */\nexport function getChainName(network: string): string {\n const mapping: Record<string, string> = {\n [SOLANA_MAINNET_NETWORK]: 'Solana',\n 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1': 'Solana Devnet',\n 'solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z': 'Solana Testnet',\n 'solana': 'Solana',\n [BASE_MAINNET_NETWORK]: 'Base',\n 'eip155:84532': 'Base Sepolia',\n 'eip155:1': 'Ethereum',\n 'eip155:42161': 'Arbitrum One',\n 'base': 'Base',\n 'ethereum': 'Ethereum',\n 'arbitrum': 'Arbitrum',\n };\n return mapping[network] || network;\n}\n\n// ============================================================================\n// Transaction URL Helpers\n// ============================================================================\n\n/**\n * Get explorer URL for a transaction\n *\n * @param txSignature - Transaction signature/hash\n * @param network - CAIP-2 network identifier\n * @returns Explorer URL\n */\nexport function getExplorerUrl(txSignature: string, network: string): string {\n const family = getChainFamily(network);\n\n if (family === 'solana') {\n const isDevnet = network.includes('devnet') || network === 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1';\n if (isDevnet) {\n return `https://solscan.io/tx/${txSignature}?cluster=devnet`;\n }\n // Prefer Orb Markets for mainnet\n return `https://www.orbmarkets.io/tx/${txSignature}`;\n }\n\n if (family === 'evm') {\n // Extract chain ID\n let chainId = '8453'; // Default to Base\n if (network.startsWith('eip155:')) {\n chainId = network.split(':')[1];\n } else if (network === 'ethereum') {\n chainId = '1';\n } else if (network === 'arbitrum') {\n chainId = '42161';\n }\n\n switch (chainId) {\n case '8453': return `https://basescan.org/tx/${txSignature}`;\n case '84532': return `https://sepolia.basescan.org/tx/${txSignature}`;\n case '1': return `https://etherscan.io/tx/${txSignature}`;\n case '42161': return `https://arbiscan.io/tx/${txSignature}`;\n default: return `https://basescan.org/tx/${txSignature}`;\n }\n }\n\n return `https://solscan.io/tx/${txSignature}`;\n}\n\n// ============================================================================\n// Encoding Helpers\n// ============================================================================\n\n/**\n * Encode an object as base64 JSON\n */\nexport function encodeBase64Json(obj: unknown): string {\n return btoa(JSON.stringify(obj));\n}\n\n/**\n * Decode base64 JSON to object\n */\nexport function decodeBase64Json<T>(encoded: string): T {\n return JSON.parse(atob(encoded)) as T;\n}\n","/**\n * Facilitator Client\n *\n * Communicates with the x402 facilitator for:\n * - /supported - Get supported payment schemes and fee payer addresses\n * - /verify - Verify a payment signature before processing\n * - /settle - Submit the payment for execution\n *\n * Works with any x402 v2 facilitator (Dexter or others).\n */\n\nimport type { PaymentAccept, PaymentSignature, VerifyResponse, SettleResponse } from '../types';\nimport { DEXTER_FACILITATOR_URL } from '../types';\nimport { decodeBase64Json } from '../utils';\n\n/**\n * Supported payment kind from facilitator /supported endpoint\n */\nexport interface SupportedKind {\n x402Version: number;\n scheme: string;\n network: string;\n extra?: {\n feePayer?: string;\n decimals?: number;\n name?: string;\n version?: string;\n [key: string]: unknown;\n };\n}\n\n/**\n * Response from facilitator /supported endpoint\n */\nexport interface SupportedResponse {\n kinds: SupportedKind[];\n}\n\n/**\n * Client for communicating with an x402 v2 facilitator\n */\nexport class FacilitatorClient {\n private facilitatorUrl: string;\n private cachedSupported: SupportedResponse | null = null;\n private cacheTime: number = 0;\n private readonly CACHE_TTL_MS = 60_000; // 1 minute cache\n\n constructor(facilitatorUrl: string = DEXTER_FACILITATOR_URL) {\n this.facilitatorUrl = facilitatorUrl.replace(/\\/$/, ''); // Remove trailing slash\n }\n\n /**\n * Get supported payment kinds from the facilitator\n * Results are cached for 1 minute to reduce network calls\n */\n async getSupported(): Promise<SupportedResponse> {\n const now = Date.now();\n if (this.cachedSupported && now - this.cacheTime < this.CACHE_TTL_MS) {\n return this.cachedSupported;\n }\n\n const response = await fetch(`${this.facilitatorUrl}/supported`);\n if (!response.ok) {\n throw new Error(`Facilitator /supported returned ${response.status}`);\n }\n\n this.cachedSupported = (await response.json()) as SupportedResponse;\n this.cacheTime = now;\n return this.cachedSupported;\n }\n\n /**\n * Get the fee payer address for a specific network\n *\n * @param network - CAIP-2 network identifier\n * @returns Fee payer address\n */\n async getFeePayer(network: string): Promise<string> {\n const supported = await this.getSupported();\n\n // Find matching network support (exact match or v2)\n const kind = supported.kinds.find(\n (k) =>\n k.x402Version === 2 &&\n k.scheme === 'exact' &&\n k.network === network\n );\n\n if (!kind?.extra?.feePayer) {\n throw new Error(\n `Facilitator does not support network \"${network}\" with scheme \"exact\", or feePayer not provided`\n );\n }\n\n return kind.extra.feePayer;\n }\n\n /**\n * Get extra data for a network (feePayer, decimals, EIP-712 data, etc.)\n *\n * @param network - CAIP-2 network identifier\n * @returns Extra data from /supported\n */\n async getNetworkExtra(network: string): Promise<SupportedKind['extra']> {\n const supported = await this.getSupported();\n\n const kind = supported.kinds.find(\n (k) =>\n k.x402Version === 2 &&\n k.scheme === 'exact' &&\n k.network === network\n );\n\n return kind?.extra;\n }\n\n /**\n * Verify a payment with the facilitator\n *\n * @param paymentSignatureHeader - Base64-encoded PAYMENT-SIGNATURE header value\n * @param requirements - The payment requirements that were sent to the client\n * @returns Verification response\n */\n async verifyPayment(\n paymentSignatureHeader: string,\n requirements: PaymentAccept\n ): Promise<VerifyResponse> {\n try {\n const paymentPayload = decodeBase64Json<PaymentSignature>(paymentSignatureHeader);\n\n const verifyPayload = {\n paymentPayload,\n paymentRequirements: requirements,\n };\n\n const response = await fetch(`${this.facilitatorUrl}/verify`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(verifyPayload),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n console.error(`Facilitator /verify returned ${response.status}:`, errorText);\n return {\n isValid: false,\n invalidReason: `facilitator_error_${response.status}`,\n };\n }\n\n return (await response.json()) as VerifyResponse;\n } catch (error) {\n console.error('Payment verification failed:', error);\n return {\n isValid: false,\n invalidReason: error instanceof Error ? error.message : 'unexpected_verify_error',\n };\n }\n }\n\n /**\n * Settle a payment with the facilitator\n *\n * @param paymentSignatureHeader - Base64-encoded PAYMENT-SIGNATURE header value\n * @param requirements - The payment requirements that were sent to the client\n * @returns Settlement response with transaction signature on success\n */\n async settlePayment(\n paymentSignatureHeader: string,\n requirements: PaymentAccept\n ): Promise<SettleResponse> {\n try {\n const paymentPayload = decodeBase64Json<PaymentSignature>(paymentSignatureHeader);\n\n const settlePayload = {\n paymentPayload,\n paymentRequirements: requirements,\n };\n\n const response = await fetch(`${this.facilitatorUrl}/settle`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(settlePayload),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n console.error(`Facilitator /settle returned ${response.status}:`, errorText);\n return {\n success: false,\n network: requirements.network,\n errorReason: `facilitator_error_${response.status}`,\n };\n }\n\n const result = (await response.json()) as SettleResponse;\n return {\n ...result,\n network: requirements.network,\n };\n } catch (error) {\n console.error('Payment settlement failed:', error);\n return {\n success: false,\n network: requirements.network,\n errorReason: error instanceof Error ? error.message : 'unexpected_settle_error',\n };\n }\n }\n}\n","/**\n * x402 v2 Server\n *\n * Server-side helpers for accepting x402 payments.\n * Chain-agnostic - works with Solana, Base, and any x402-compatible network.\n *\n * @example\n * ```typescript\n * import { createX402Server } from '@dexterai/x402/server';\n *\n * const server = createX402Server({\n * payTo: 'YourAddress...',\n * network: 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp',\n * });\n *\n * // Handle 402 responses\n * if (!paymentSignature) {\n * const requirements = await server.buildRequirements({\n * amountAtomic: '50000',\n * resourceUrl: '/api/protected',\n * });\n * res.setHeader('PAYMENT-REQUIRED', server.encodeRequirements(requirements));\n * res.status(402).json({});\n * return;\n * }\n *\n * // Verify and settle\n * const verify = await server.verifyPayment(paymentSignature);\n * if (!verify.isValid) throw new Error(verify.invalidReason);\n *\n * const settle = await server.settlePayment(paymentSignature);\n * if (!settle.success) throw new Error(settle.errorReason);\n *\n * // Payment successful!\n * res.json({ transaction: settle.transaction });\n * ```\n */\n\nimport type {\n PaymentRequired,\n PaymentAccept,\n ResourceInfo,\n AcceptsExtra,\n VerifyResponse,\n SettleResponse,\n} from '../types';\nimport {\n SOLANA_MAINNET_NETWORK,\n USDC_MINT,\n DEXTER_FACILITATOR_URL,\n} from '../types';\nimport { FacilitatorClient, type SupportedKind } from './facilitator-client';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Asset configuration\n */\nexport interface AssetConfig {\n /** Token address (mint on Solana, contract on EVM) */\n address: string;\n /** Token decimals */\n decimals: number;\n}\n\n/**\n * Server configuration\n */\nexport interface X402ServerConfig {\n /** Address to receive payments */\n payTo: string;\n /** Facilitator URL (defaults to Dexter) */\n facilitatorUrl?: string;\n /** CAIP-2 network identifier */\n network?: string;\n /** Asset configuration (defaults to USDC) */\n asset?: AssetConfig;\n /** Default payment timeout in seconds */\n defaultTimeoutSeconds?: number;\n}\n\n/**\n * Options for building payment requirements\n */\nexport interface BuildRequirementsOptions {\n /** Amount in atomic units (e.g., '50000' for 0.05 USDC) */\n amountAtomic: string;\n /** Full URL of the resource */\n resourceUrl: string;\n /** Human-readable description */\n description?: string;\n /** MIME type of the response */\n mimeType?: string;\n /** Override timeout for this request */\n timeoutSeconds?: number;\n}\n\n/**\n * x402 Server interface\n */\nexport interface X402Server {\n /** Build payment requirements (fetches feePayer from facilitator) */\n buildRequirements(options: BuildRequirementsOptions): Promise<PaymentRequired>;\n\n /** Encode requirements for PAYMENT-REQUIRED header */\n encodeRequirements(requirements: PaymentRequired): string;\n\n /** Create complete 402 response object */\n create402Response(requirements: PaymentRequired): {\n status: 402;\n headers: { 'PAYMENT-REQUIRED': string };\n body: Record<string, unknown>;\n };\n\n /** Verify payment with facilitator */\n verifyPayment(\n paymentSignatureHeader: string,\n requirements?: PaymentAccept\n ): Promise<VerifyResponse>;\n\n /** Settle payment via facilitator */\n settlePayment(\n paymentSignatureHeader: string,\n requirements?: PaymentAccept\n ): Promise<SettleResponse>;\n\n /** Get PaymentAccept for verify/settle */\n getPaymentAccept(options: BuildRequirementsOptions): Promise<PaymentAccept>;\n\n /** Get network this server is configured for */\n readonly network: string;\n\n /** Get facilitator client for advanced usage */\n readonly facilitator: FacilitatorClient;\n}\n\n// ============================================================================\n// Implementation\n// ============================================================================\n\n/**\n * Create an x402 server for accepting payments\n */\nexport function createX402Server(config: X402ServerConfig): X402Server {\n const {\n payTo,\n facilitatorUrl = DEXTER_FACILITATOR_URL,\n network = SOLANA_MAINNET_NETWORK,\n asset = { address: USDC_MINT, decimals: 6 },\n defaultTimeoutSeconds = 60,\n } = config;\n\n const facilitator = new FacilitatorClient(facilitatorUrl);\n\n // Cache for network extra data\n let cachedExtra: SupportedKind['extra'] | null = null;\n\n /**\n * Get extra data from facilitator (cached)\n */\n async function getNetworkExtra(): Promise<AcceptsExtra> {\n if (!cachedExtra) {\n cachedExtra = await facilitator.getNetworkExtra(network);\n }\n\n if (!cachedExtra?.feePayer) {\n throw new Error(`Facilitator does not provide feePayer for network \"${network}\"`);\n }\n\n return {\n feePayer: cachedExtra.feePayer,\n decimals: cachedExtra.decimals ?? asset.decimals,\n // Include any additional EIP-712 data for EVM chains\n name: cachedExtra.name,\n version: cachedExtra.version,\n };\n }\n\n /**\n * Build a PaymentAccept structure\n */\n async function getPaymentAccept(options: BuildRequirementsOptions): Promise<PaymentAccept> {\n const {\n amountAtomic,\n timeoutSeconds = defaultTimeoutSeconds,\n } = options;\n\n const extra = await getNetworkExtra();\n\n return {\n scheme: 'exact',\n network,\n amount: amountAtomic,\n asset: asset.address,\n payTo,\n maxTimeoutSeconds: timeoutSeconds,\n extra,\n };\n }\n\n /**\n * Build payment requirements for a 402 response\n */\n async function buildRequirements(options: BuildRequirementsOptions): Promise<PaymentRequired> {\n const {\n resourceUrl,\n description,\n mimeType = 'application/json',\n } = options;\n\n const resource: ResourceInfo = {\n url: resourceUrl,\n description,\n mimeType,\n };\n\n const accept = await getPaymentAccept(options);\n\n return {\n x402Version: 2,\n resource,\n accepts: [accept],\n error: 'Payment required',\n };\n }\n\n /**\n * Encode requirements for PAYMENT-REQUIRED header\n */\n function encodeRequirements(requirements: PaymentRequired): string {\n return btoa(JSON.stringify(requirements));\n }\n\n /**\n * Create complete 402 response object\n */\n function create402Response(requirements: PaymentRequired) {\n return {\n status: 402 as const,\n headers: {\n 'PAYMENT-REQUIRED': encodeRequirements(requirements),\n },\n body: {},\n };\n }\n\n /**\n * Verify payment with facilitator\n */\n async function verifyPayment(\n paymentSignatureHeader: string,\n requirements?: PaymentAccept\n ): Promise<VerifyResponse> {\n // If requirements not provided, build default\n const req = requirements || await getPaymentAccept({\n amountAtomic: '0',\n resourceUrl: '',\n });\n\n return facilitator.verifyPayment(paymentSignatureHeader, req);\n }\n\n /**\n * Settle payment via facilitator\n */\n async function settlePayment(\n paymentSignatureHeader: string,\n requirements?: PaymentAccept\n ): Promise<SettleResponse> {\n const req = requirements || await getPaymentAccept({\n amountAtomic: '0',\n resourceUrl: '',\n });\n\n return facilitator.settlePayment(paymentSignatureHeader, req);\n }\n\n return {\n buildRequirements,\n encodeRequirements,\n create402Response,\n verifyPayment,\n settlePayment,\n getPaymentAccept,\n network,\n facilitator,\n };\n}\n"],"mappings":"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","names":[]}
@@ -1,4 +1,4 @@
1
- import { P as PaymentAccept } from './types-DkTxHOns.cjs';
1
+ import { P as PaymentAccept } from './types-CNPXknHK.cjs';
2
2
 
3
3
  /**
4
4
  * Chain Adapter Interface
@@ -104,7 +104,7 @@ interface SettleResponse {
104
104
  /**
105
105
  * SDK error codes
106
106
  */
107
- type X402ErrorCode = 'missing_payment_required_header' | 'invalid_payment_required' | 'unsupported_network' | 'no_matching_payment_option' | 'no_solana_accept' | 'missing_fee_payer' | 'missing_decimals' | 'amount_exceeds_max' | 'wallet_missing_sign_transaction' | 'wallet_not_connected' | 'transaction_build_failed' | 'payment_rejected' | 'invalid_payment_signature' | 'facilitator_verify_failed' | 'facilitator_settle_failed' | 'facilitator_request_failed' | 'no_matching_requirement';
107
+ type X402ErrorCode = 'missing_payment_required_header' | 'invalid_payment_required' | 'unsupported_network' | 'no_matching_payment_option' | 'no_solana_accept' | 'missing_fee_payer' | 'missing_decimals' | 'amount_exceeds_max' | 'insufficient_balance' | 'wallet_missing_sign_transaction' | 'wallet_not_connected' | 'transaction_build_failed' | 'payment_rejected' | 'invalid_payment_signature' | 'facilitator_verify_failed' | 'facilitator_settle_failed' | 'facilitator_request_failed' | 'no_matching_requirement';
108
108
  /**
109
109
  * Custom error class for x402 operations
110
110
  */
@@ -104,7 +104,7 @@ interface SettleResponse {
104
104
  /**
105
105
  * SDK error codes
106
106
  */
107
- type X402ErrorCode = 'missing_payment_required_header' | 'invalid_payment_required' | 'unsupported_network' | 'no_matching_payment_option' | 'no_solana_accept' | 'missing_fee_payer' | 'missing_decimals' | 'amount_exceeds_max' | 'wallet_missing_sign_transaction' | 'wallet_not_connected' | 'transaction_build_failed' | 'payment_rejected' | 'invalid_payment_signature' | 'facilitator_verify_failed' | 'facilitator_settle_failed' | 'facilitator_request_failed' | 'no_matching_requirement';
107
+ type X402ErrorCode = 'missing_payment_required_header' | 'invalid_payment_required' | 'unsupported_network' | 'no_matching_payment_option' | 'no_solana_accept' | 'missing_fee_payer' | 'missing_decimals' | 'amount_exceeds_max' | 'insufficient_balance' | 'wallet_missing_sign_transaction' | 'wallet_not_connected' | 'transaction_build_failed' | 'payment_rejected' | 'invalid_payment_signature' | 'facilitator_verify_failed' | 'facilitator_settle_failed' | 'facilitator_request_failed' | 'no_matching_requirement';
108
108
  /**
109
109
  * Custom error class for x402 operations
110
110
  */
@@ -1,4 +1,4 @@
1
- import { P as PaymentAccept } from './types-DkTxHOns.js';
1
+ import { P as PaymentAccept } from './types-CNPXknHK.js';
2
2
 
3
3
  /**
4
4
  * Chain Adapter Interface
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/utils/index.ts
21
+ var utils_exports = {};
22
+ __export(utils_exports, {
23
+ fromAtomicUnits: () => fromAtomicUnits,
24
+ getChainFamily: () => getChainFamily,
25
+ getChainName: () => getChainName,
26
+ getExplorerUrl: () => getExplorerUrl,
27
+ toAtomicUnits: () => toAtomicUnits
28
+ });
29
+ module.exports = __toCommonJS(utils_exports);
30
+
31
+ // src/types.ts
32
+ var SOLANA_MAINNET_NETWORK = "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp";
33
+ var BASE_MAINNET_NETWORK = "eip155:8453";
34
+
35
+ // src/utils.ts
36
+ function toAtomicUnits(amount, decimals) {
37
+ const multiplier = Math.pow(10, decimals);
38
+ return Math.floor(amount * multiplier).toString();
39
+ }
40
+ function fromAtomicUnits(atomicUnits, decimals) {
41
+ const divisor = Math.pow(10, decimals);
42
+ return Number(atomicUnits) / divisor;
43
+ }
44
+ function getChainFamily(network) {
45
+ if (network.startsWith("solana:") || network === "solana") {
46
+ return "solana";
47
+ }
48
+ if (network.startsWith("eip155:") || ["base", "ethereum", "arbitrum"].includes(network)) {
49
+ return "evm";
50
+ }
51
+ return "unknown";
52
+ }
53
+ function getChainName(network) {
54
+ const mapping = {
55
+ [SOLANA_MAINNET_NETWORK]: "Solana",
56
+ "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1": "Solana Devnet",
57
+ "solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z": "Solana Testnet",
58
+ "solana": "Solana",
59
+ [BASE_MAINNET_NETWORK]: "Base",
60
+ "eip155:84532": "Base Sepolia",
61
+ "eip155:1": "Ethereum",
62
+ "eip155:42161": "Arbitrum One",
63
+ "base": "Base",
64
+ "ethereum": "Ethereum",
65
+ "arbitrum": "Arbitrum"
66
+ };
67
+ return mapping[network] || network;
68
+ }
69
+ function getExplorerUrl(txSignature, network) {
70
+ const family = getChainFamily(network);
71
+ if (family === "solana") {
72
+ const isDevnet = network.includes("devnet") || network === "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1";
73
+ if (isDevnet) {
74
+ return `https://solscan.io/tx/${txSignature}?cluster=devnet`;
75
+ }
76
+ return `https://www.orbmarkets.io/tx/${txSignature}`;
77
+ }
78
+ if (family === "evm") {
79
+ let chainId = "8453";
80
+ if (network.startsWith("eip155:")) {
81
+ chainId = network.split(":")[1];
82
+ } else if (network === "ethereum") {
83
+ chainId = "1";
84
+ } else if (network === "arbitrum") {
85
+ chainId = "42161";
86
+ }
87
+ switch (chainId) {
88
+ case "8453":
89
+ return `https://basescan.org/tx/${txSignature}`;
90
+ case "84532":
91
+ return `https://sepolia.basescan.org/tx/${txSignature}`;
92
+ case "1":
93
+ return `https://etherscan.io/tx/${txSignature}`;
94
+ case "42161":
95
+ return `https://arbiscan.io/tx/${txSignature}`;
96
+ default:
97
+ return `https://basescan.org/tx/${txSignature}`;
98
+ }
99
+ }
100
+ return `https://solscan.io/tx/${txSignature}`;
101
+ }
102
+ // Annotate the CommonJS export names for ESM import in node:
103
+ 0 && (module.exports = {
104
+ fromAtomicUnits,
105
+ getChainFamily,
106
+ getChainName,
107
+ getExplorerUrl,
108
+ toAtomicUnits
109
+ });
110
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/index.ts","../../src/types.ts","../../src/utils.ts"],"sourcesContent":["/**\n * @dexterai/x402 Utils\n *\n * Helper functions for x402 payments.\n *\n * @example\n * ```typescript\n * import { toAtomicUnits, fromAtomicUnits } from '@dexterai/x402/utils';\n *\n * const atomic = toAtomicUnits(0.05, 6); // '50000'\n * const human = fromAtomicUnits('50000', 6); // 0.05\n * ```\n */\n\nexport {\n toAtomicUnits,\n fromAtomicUnits,\n getChainFamily,\n getChainName,\n getExplorerUrl,\n type ChainFamily,\n} from '../utils';\n","/**\n * x402 v2 SDK — Shared Types\n *\n * Chain-agnostic types for x402 v2 payments.\n * Works with Solana, Base, and any future x402-compatible networks.\n */\n\n// ============================================================================\n// Network Constants\n// ============================================================================\n\n/** CAIP-2 network identifier for Solana mainnet */\nexport const SOLANA_MAINNET_NETWORK = 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp';\n\n/** CAIP-2 network identifier for Base mainnet */\nexport const BASE_MAINNET_NETWORK = 'eip155:8453';\n\n/** Alias for Solana mainnet */\nexport const SOLANA_MAINNET = SOLANA_MAINNET_NETWORK;\n\n/** Alias for Base mainnet */\nexport const BASE_MAINNET = BASE_MAINNET_NETWORK;\n\n// ============================================================================\n// Asset Constants\n// ============================================================================\n\n/** USDC mint on Solana mainnet */\nexport const USDC_MINT = 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v';\n\n/** USDC address on Base mainnet */\nexport const USDC_BASE = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913';\n\n// ============================================================================\n// Facilitator Constants\n// ============================================================================\n\n/** Dexter's public x402 v2 facilitator URL */\nexport const DEXTER_FACILITATOR_URL = 'https://x402.dexter.cash';\n\n// ============================================================================\n// Payment Types\n// ============================================================================\n\n/**\n * Asset configuration for payments\n */\nexport interface AssetConfig {\n /** Token address (mint on Solana, contract on EVM) */\n address: string;\n /** Token decimals */\n decimals: number;\n /** Optional: Human-readable symbol */\n symbol?: string;\n}\n\n/**\n * Resource info included in payment requirements\n */\nexport interface ResourceInfo {\n /** Resource URL */\n url: string;\n /** Human-readable description */\n description?: string;\n /** MIME type of the resource */\n mimeType?: string;\n}\n\n/**\n * Extra fields in payment requirements\n * Chain-specific fields may vary\n */\nexport interface AcceptsExtra {\n /** Facilitator address that pays tx fees (required) */\n feePayer: string;\n /** Token decimals (required) */\n decimals: number;\n /** EIP-712: Token name (EVM only) */\n name?: string;\n /** EIP-712: Token version (EVM only) */\n version?: string;\n /** Additional chain-specific fields */\n [key: string]: unknown;\n}\n\n/**\n * A single payment option in the accepts array\n */\nexport interface PaymentAccept {\n /** Payment scheme (always 'exact' for x402 v2) */\n scheme: 'exact';\n /** CAIP-2 network identifier */\n network: string;\n /** Payment amount in atomic units (as string to avoid precision loss) */\n amount: string;\n /** Token address */\n asset: string;\n /** Seller's address to receive payment */\n payTo: string;\n /** Maximum seconds until payment expires */\n maxTimeoutSeconds: number;\n /** Chain-specific extra data */\n extra: AcceptsExtra;\n}\n\n/**\n * Full PaymentRequired structure (sent in PAYMENT-REQUIRED header)\n */\nexport interface PaymentRequired {\n /** x402 version (always 2) */\n x402Version: 2;\n /** Resource being accessed */\n resource: ResourceInfo;\n /** Available payment options */\n accepts: PaymentAccept[];\n /** Optional error message */\n error?: string;\n}\n\n/**\n * PaymentSignature structure (sent in PAYMENT-SIGNATURE header)\n */\nexport interface PaymentSignature {\n /** x402 version (always 2) */\n x402Version: 2;\n /** Resource being accessed */\n resource: ResourceInfo;\n /** The payment option that was accepted */\n accepted: PaymentAccept;\n /** The signed payment */\n payload: {\n /** Signed transaction (base64 for Solana, JSON for EVM) */\n transaction: string;\n };\n}\n\n// ============================================================================\n// Facilitator Response Types\n// ============================================================================\n\n/**\n * Response from /verify endpoint\n */\nexport interface VerifyResponse {\n /** Whether the payment is valid */\n isValid: boolean;\n /** Reason for invalidity (if invalid) */\n invalidReason?: string;\n /** Payer address */\n payer?: string;\n}\n\n/**\n * Response from /settle endpoint\n */\nexport interface SettleResponse {\n /** Whether settlement succeeded */\n success: boolean;\n /** Transaction signature/hash */\n transaction?: string;\n /** Network the payment was made on */\n network: string;\n /** Error reason (if failed) */\n errorReason?: string;\n /** Error code (if failed) */\n errorCode?: string;\n /** Payer address */\n payer?: string;\n}\n\n// ============================================================================\n// Error Types\n// ============================================================================\n\n/**\n * SDK error codes\n */\nexport type X402ErrorCode =\n // Client errors\n | 'missing_payment_required_header'\n | 'invalid_payment_required'\n | 'unsupported_network'\n | 'no_matching_payment_option'\n | 'no_solana_accept' // Legacy, kept for compatibility\n | 'missing_fee_payer'\n | 'missing_decimals'\n | 'amount_exceeds_max'\n | 'insufficient_balance'\n | 'wallet_missing_sign_transaction'\n | 'wallet_not_connected'\n | 'transaction_build_failed'\n | 'payment_rejected'\n // Server errors\n | 'invalid_payment_signature'\n | 'facilitator_verify_failed'\n | 'facilitator_settle_failed'\n | 'facilitator_request_failed'\n | 'no_matching_requirement';\n\n/**\n * Custom error class for x402 operations\n */\nexport class X402Error extends Error {\n /** Error code for programmatic handling */\n code: X402ErrorCode;\n /** Additional error details */\n details?: unknown;\n\n constructor(code: X402ErrorCode, message: string, details?: unknown) {\n super(message);\n this.name = 'X402Error';\n this.code = code;\n this.details = details;\n // Maintain proper prototype chain\n Object.setPrototypeOf(this, X402Error.prototype);\n }\n}\n","/**\n * Utility Functions\n *\n * Chain-agnostic helpers for x402 payments.\n */\n\nimport { SOLANA_MAINNET_NETWORK, BASE_MAINNET_NETWORK } from './types';\n\n// ============================================================================\n// Amount Conversion\n// ============================================================================\n\n/**\n * Convert human-readable amount to atomic units\n *\n * @param amount - Human-readable amount (e.g., 0.05 for $0.05)\n * @param decimals - Token decimals (e.g., 6 for USDC)\n * @returns Amount in atomic units as string\n *\n * @example\n * ```typescript\n * toAtomicUnits(0.05, 6) // '50000'\n * toAtomicUnits(1.50, 6) // '1500000'\n * ```\n */\nexport function toAtomicUnits(amount: number, decimals: number): string {\n const multiplier = Math.pow(10, decimals);\n return Math.floor(amount * multiplier).toString();\n}\n\n/**\n * Convert atomic units to human-readable amount\n *\n * @param atomicUnits - Amount in smallest units\n * @param decimals - Token decimals\n * @returns Human-readable amount\n *\n * @example\n * ```typescript\n * fromAtomicUnits('50000', 6) // 0.05\n * fromAtomicUnits(1500000n, 6) // 1.5\n * ```\n */\nexport function fromAtomicUnits(\n atomicUnits: string | bigint | number,\n decimals: number\n): number {\n const divisor = Math.pow(10, decimals);\n return Number(atomicUnits) / divisor;\n}\n\n// ============================================================================\n// Network Helpers\n// ============================================================================\n\n/**\n * Network type\n */\nexport type ChainFamily = 'solana' | 'evm' | 'unknown';\n\n/**\n * Get the chain family from a CAIP-2 network identifier\n *\n * @param network - CAIP-2 network identifier\n * @returns Chain family\n *\n * @example\n * ```typescript\n * getChainFamily('solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp') // 'solana'\n * getChainFamily('eip155:8453') // 'evm'\n * ```\n */\nexport function getChainFamily(network: string): ChainFamily {\n if (network.startsWith('solana:') || network === 'solana') {\n return 'solana';\n }\n if (network.startsWith('eip155:') || ['base', 'ethereum', 'arbitrum'].includes(network)) {\n return 'evm';\n }\n return 'unknown';\n}\n\n/**\n * Get default RPC URL for a network\n *\n * @param network - CAIP-2 network identifier\n * @returns Default RPC URL\n */\nexport function getDefaultRpcUrl(network: string): string {\n const family = getChainFamily(network);\n\n if (family === 'solana') {\n if (network.includes('devnet') || network === 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1') {\n return 'https://api.devnet.solana.com';\n }\n if (network.includes('testnet') || network === 'solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z') {\n return 'https://api.testnet.solana.com';\n }\n return 'https://api.mainnet-beta.solana.com';\n }\n\n if (family === 'evm') {\n // Extract chain ID from CAIP-2\n if (network.startsWith('eip155:')) {\n const chainId = network.split(':')[1];\n switch (chainId) {\n case '8453': return 'https://mainnet.base.org';\n case '84532': return 'https://sepolia.base.org';\n case '1': return 'https://eth.llamarpc.com';\n case '42161': return 'https://arb1.arbitrum.io/rpc';\n default: return 'https://mainnet.base.org';\n }\n }\n // Legacy names\n if (network === 'base') return 'https://mainnet.base.org';\n if (network === 'ethereum') return 'https://eth.llamarpc.com';\n if (network === 'arbitrum') return 'https://arb1.arbitrum.io/rpc';\n return 'https://mainnet.base.org';\n }\n\n // Unknown - return a generic\n return 'https://api.mainnet-beta.solana.com';\n}\n\n/**\n * Get human-readable chain name\n *\n * @param network - CAIP-2 network identifier\n * @returns Human-readable name\n */\nexport function getChainName(network: string): string {\n const mapping: Record<string, string> = {\n [SOLANA_MAINNET_NETWORK]: 'Solana',\n 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1': 'Solana Devnet',\n 'solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z': 'Solana Testnet',\n 'solana': 'Solana',\n [BASE_MAINNET_NETWORK]: 'Base',\n 'eip155:84532': 'Base Sepolia',\n 'eip155:1': 'Ethereum',\n 'eip155:42161': 'Arbitrum One',\n 'base': 'Base',\n 'ethereum': 'Ethereum',\n 'arbitrum': 'Arbitrum',\n };\n return mapping[network] || network;\n}\n\n// ============================================================================\n// Transaction URL Helpers\n// ============================================================================\n\n/**\n * Get explorer URL for a transaction\n *\n * @param txSignature - Transaction signature/hash\n * @param network - CAIP-2 network identifier\n * @returns Explorer URL\n */\nexport function getExplorerUrl(txSignature: string, network: string): string {\n const family = getChainFamily(network);\n\n if (family === 'solana') {\n const isDevnet = network.includes('devnet') || network === 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1';\n if (isDevnet) {\n return `https://solscan.io/tx/${txSignature}?cluster=devnet`;\n }\n // Prefer Orb Markets for mainnet\n return `https://www.orbmarkets.io/tx/${txSignature}`;\n }\n\n if (family === 'evm') {\n // Extract chain ID\n let chainId = '8453'; // Default to Base\n if (network.startsWith('eip155:')) {\n chainId = network.split(':')[1];\n } else if (network === 'ethereum') {\n chainId = '1';\n } else if (network === 'arbitrum') {\n chainId = '42161';\n }\n\n switch (chainId) {\n case '8453': return `https://basescan.org/tx/${txSignature}`;\n case '84532': return `https://sepolia.basescan.org/tx/${txSignature}`;\n case '1': return `https://etherscan.io/tx/${txSignature}`;\n case '42161': return `https://arbiscan.io/tx/${txSignature}`;\n default: return `https://basescan.org/tx/${txSignature}`;\n }\n }\n\n return `https://solscan.io/tx/${txSignature}`;\n}\n\n// ============================================================================\n// Encoding Helpers\n// ============================================================================\n\n/**\n * Encode an object as base64 JSON\n */\nexport function encodeBase64Json(obj: unknown): string {\n return btoa(JSON.stringify(obj));\n}\n\n/**\n * Decode base64 JSON to object\n */\nexport function decodeBase64Json<T>(encoded: string): T {\n return JSON.parse(atob(encoded)) as T;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACYO,IAAM,yBAAyB;AAG/B,IAAM,uBAAuB;;;ACU7B,SAAS,cAAc,QAAgB,UAA0B;AACtE,QAAM,aAAa,KAAK,IAAI,IAAI,QAAQ;AACxC,SAAO,KAAK,MAAM,SAAS,UAAU,EAAE,SAAS;AAClD;AAeO,SAAS,gBACd,aACA,UACQ;AACR,QAAM,UAAU,KAAK,IAAI,IAAI,QAAQ;AACrC,SAAO,OAAO,WAAW,IAAI;AAC/B;AAuBO,SAAS,eAAe,SAA8B;AAC3D,MAAI,QAAQ,WAAW,SAAS,KAAK,YAAY,UAAU;AACzD,WAAO;AAAA,EACT;AACA,MAAI,QAAQ,WAAW,SAAS,KAAK,CAAC,QAAQ,YAAY,UAAU,EAAE,SAAS,OAAO,GAAG;AACvF,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAkDO,SAAS,aAAa,SAAyB;AACpD,QAAM,UAAkC;AAAA,IACtC,CAAC,sBAAsB,GAAG;AAAA,IAC1B,2CAA2C;AAAA,IAC3C,2CAA2C;AAAA,IAC3C,UAAU;AAAA,IACV,CAAC,oBAAoB,GAAG;AAAA,IACxB,gBAAgB;AAAA,IAChB,YAAY;AAAA,IACZ,gBAAgB;AAAA,IAChB,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,YAAY;AAAA,EACd;AACA,SAAO,QAAQ,OAAO,KAAK;AAC7B;AAaO,SAAS,eAAe,aAAqB,SAAyB;AAC3E,QAAM,SAAS,eAAe,OAAO;AAErC,MAAI,WAAW,UAAU;AACvB,UAAM,WAAW,QAAQ,SAAS,QAAQ,KAAK,YAAY;AAC3D,QAAI,UAAU;AACZ,aAAO,yBAAyB,WAAW;AAAA,IAC7C;AAEA,WAAO,gCAAgC,WAAW;AAAA,EACpD;AAEA,MAAI,WAAW,OAAO;AAEpB,QAAI,UAAU;AACd,QAAI,QAAQ,WAAW,SAAS,GAAG;AACjC,gBAAU,QAAQ,MAAM,GAAG,EAAE,CAAC;AAAA,IAChC,WAAW,YAAY,YAAY;AACjC,gBAAU;AAAA,IACZ,WAAW,YAAY,YAAY;AACjC,gBAAU;AAAA,IACZ;AAEA,YAAQ,SAAS;AAAA,MACf,KAAK;AAAQ,eAAO,2BAA2B,WAAW;AAAA,MAC1D,KAAK;AAAS,eAAO,mCAAmC,WAAW;AAAA,MACnE,KAAK;AAAK,eAAO,2BAA2B,WAAW;AAAA,MACvD,KAAK;AAAS,eAAO,0BAA0B,WAAW;AAAA,MAC1D;AAAS,eAAO,2BAA2B,WAAW;AAAA,IACxD;AAAA,EACF;AAEA,SAAO,yBAAyB,WAAW;AAC7C;","names":[]}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Utility Functions
3
+ *
4
+ * Chain-agnostic helpers for x402 payments.
5
+ */
6
+ /**
7
+ * Convert human-readable amount to atomic units
8
+ *
9
+ * @param amount - Human-readable amount (e.g., 0.05 for $0.05)
10
+ * @param decimals - Token decimals (e.g., 6 for USDC)
11
+ * @returns Amount in atomic units as string
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * toAtomicUnits(0.05, 6) // '50000'
16
+ * toAtomicUnits(1.50, 6) // '1500000'
17
+ * ```
18
+ */
19
+ declare function toAtomicUnits(amount: number, decimals: number): string;
20
+ /**
21
+ * Convert atomic units to human-readable amount
22
+ *
23
+ * @param atomicUnits - Amount in smallest units
24
+ * @param decimals - Token decimals
25
+ * @returns Human-readable amount
26
+ *
27
+ * @example
28
+ * ```typescript
29
+ * fromAtomicUnits('50000', 6) // 0.05
30
+ * fromAtomicUnits(1500000n, 6) // 1.5
31
+ * ```
32
+ */
33
+ declare function fromAtomicUnits(atomicUnits: string | bigint | number, decimals: number): number;
34
+ /**
35
+ * Network type
36
+ */
37
+ type ChainFamily = 'solana' | 'evm' | 'unknown';
38
+ /**
39
+ * Get the chain family from a CAIP-2 network identifier
40
+ *
41
+ * @param network - CAIP-2 network identifier
42
+ * @returns Chain family
43
+ *
44
+ * @example
45
+ * ```typescript
46
+ * getChainFamily('solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp') // 'solana'
47
+ * getChainFamily('eip155:8453') // 'evm'
48
+ * ```
49
+ */
50
+ declare function getChainFamily(network: string): ChainFamily;
51
+ /**
52
+ * Get human-readable chain name
53
+ *
54
+ * @param network - CAIP-2 network identifier
55
+ * @returns Human-readable name
56
+ */
57
+ declare function getChainName(network: string): string;
58
+ /**
59
+ * Get explorer URL for a transaction
60
+ *
61
+ * @param txSignature - Transaction signature/hash
62
+ * @param network - CAIP-2 network identifier
63
+ * @returns Explorer URL
64
+ */
65
+ declare function getExplorerUrl(txSignature: string, network: string): string;
66
+
67
+ export { type ChainFamily, fromAtomicUnits, getChainFamily, getChainName, getExplorerUrl, toAtomicUnits };
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Utility Functions
3
+ *
4
+ * Chain-agnostic helpers for x402 payments.
5
+ */
6
+ /**
7
+ * Convert human-readable amount to atomic units
8
+ *
9
+ * @param amount - Human-readable amount (e.g., 0.05 for $0.05)
10
+ * @param decimals - Token decimals (e.g., 6 for USDC)
11
+ * @returns Amount in atomic units as string
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * toAtomicUnits(0.05, 6) // '50000'
16
+ * toAtomicUnits(1.50, 6) // '1500000'
17
+ * ```
18
+ */
19
+ declare function toAtomicUnits(amount: number, decimals: number): string;
20
+ /**
21
+ * Convert atomic units to human-readable amount
22
+ *
23
+ * @param atomicUnits - Amount in smallest units
24
+ * @param decimals - Token decimals
25
+ * @returns Human-readable amount
26
+ *
27
+ * @example
28
+ * ```typescript
29
+ * fromAtomicUnits('50000', 6) // 0.05
30
+ * fromAtomicUnits(1500000n, 6) // 1.5
31
+ * ```
32
+ */
33
+ declare function fromAtomicUnits(atomicUnits: string | bigint | number, decimals: number): number;
34
+ /**
35
+ * Network type
36
+ */
37
+ type ChainFamily = 'solana' | 'evm' | 'unknown';
38
+ /**
39
+ * Get the chain family from a CAIP-2 network identifier
40
+ *
41
+ * @param network - CAIP-2 network identifier
42
+ * @returns Chain family
43
+ *
44
+ * @example
45
+ * ```typescript
46
+ * getChainFamily('solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp') // 'solana'
47
+ * getChainFamily('eip155:8453') // 'evm'
48
+ * ```
49
+ */
50
+ declare function getChainFamily(network: string): ChainFamily;
51
+ /**
52
+ * Get human-readable chain name
53
+ *
54
+ * @param network - CAIP-2 network identifier
55
+ * @returns Human-readable name
56
+ */
57
+ declare function getChainName(network: string): string;
58
+ /**
59
+ * Get explorer URL for a transaction
60
+ *
61
+ * @param txSignature - Transaction signature/hash
62
+ * @param network - CAIP-2 network identifier
63
+ * @returns Explorer URL
64
+ */
65
+ declare function getExplorerUrl(txSignature: string, network: string): string;
66
+
67
+ export { type ChainFamily, fromAtomicUnits, getChainFamily, getChainName, getExplorerUrl, toAtomicUnits };
@@ -0,0 +1,79 @@
1
+ // src/types.ts
2
+ var SOLANA_MAINNET_NETWORK = "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp";
3
+ var BASE_MAINNET_NETWORK = "eip155:8453";
4
+
5
+ // src/utils.ts
6
+ function toAtomicUnits(amount, decimals) {
7
+ const multiplier = Math.pow(10, decimals);
8
+ return Math.floor(amount * multiplier).toString();
9
+ }
10
+ function fromAtomicUnits(atomicUnits, decimals) {
11
+ const divisor = Math.pow(10, decimals);
12
+ return Number(atomicUnits) / divisor;
13
+ }
14
+ function getChainFamily(network) {
15
+ if (network.startsWith("solana:") || network === "solana") {
16
+ return "solana";
17
+ }
18
+ if (network.startsWith("eip155:") || ["base", "ethereum", "arbitrum"].includes(network)) {
19
+ return "evm";
20
+ }
21
+ return "unknown";
22
+ }
23
+ function getChainName(network) {
24
+ const mapping = {
25
+ [SOLANA_MAINNET_NETWORK]: "Solana",
26
+ "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1": "Solana Devnet",
27
+ "solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z": "Solana Testnet",
28
+ "solana": "Solana",
29
+ [BASE_MAINNET_NETWORK]: "Base",
30
+ "eip155:84532": "Base Sepolia",
31
+ "eip155:1": "Ethereum",
32
+ "eip155:42161": "Arbitrum One",
33
+ "base": "Base",
34
+ "ethereum": "Ethereum",
35
+ "arbitrum": "Arbitrum"
36
+ };
37
+ return mapping[network] || network;
38
+ }
39
+ function getExplorerUrl(txSignature, network) {
40
+ const family = getChainFamily(network);
41
+ if (family === "solana") {
42
+ const isDevnet = network.includes("devnet") || network === "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1";
43
+ if (isDevnet) {
44
+ return `https://solscan.io/tx/${txSignature}?cluster=devnet`;
45
+ }
46
+ return `https://www.orbmarkets.io/tx/${txSignature}`;
47
+ }
48
+ if (family === "evm") {
49
+ let chainId = "8453";
50
+ if (network.startsWith("eip155:")) {
51
+ chainId = network.split(":")[1];
52
+ } else if (network === "ethereum") {
53
+ chainId = "1";
54
+ } else if (network === "arbitrum") {
55
+ chainId = "42161";
56
+ }
57
+ switch (chainId) {
58
+ case "8453":
59
+ return `https://basescan.org/tx/${txSignature}`;
60
+ case "84532":
61
+ return `https://sepolia.basescan.org/tx/${txSignature}`;
62
+ case "1":
63
+ return `https://etherscan.io/tx/${txSignature}`;
64
+ case "42161":
65
+ return `https://arbiscan.io/tx/${txSignature}`;
66
+ default:
67
+ return `https://basescan.org/tx/${txSignature}`;
68
+ }
69
+ }
70
+ return `https://solscan.io/tx/${txSignature}`;
71
+ }
72
+ export {
73
+ fromAtomicUnits,
74
+ getChainFamily,
75
+ getChainName,
76
+ getExplorerUrl,
77
+ toAtomicUnits
78
+ };
79
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/types.ts","../../src/utils.ts"],"sourcesContent":["/**\n * x402 v2 SDK — Shared Types\n *\n * Chain-agnostic types for x402 v2 payments.\n * Works with Solana, Base, and any future x402-compatible networks.\n */\n\n// ============================================================================\n// Network Constants\n// ============================================================================\n\n/** CAIP-2 network identifier for Solana mainnet */\nexport const SOLANA_MAINNET_NETWORK = 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp';\n\n/** CAIP-2 network identifier for Base mainnet */\nexport const BASE_MAINNET_NETWORK = 'eip155:8453';\n\n/** Alias for Solana mainnet */\nexport const SOLANA_MAINNET = SOLANA_MAINNET_NETWORK;\n\n/** Alias for Base mainnet */\nexport const BASE_MAINNET = BASE_MAINNET_NETWORK;\n\n// ============================================================================\n// Asset Constants\n// ============================================================================\n\n/** USDC mint on Solana mainnet */\nexport const USDC_MINT = 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v';\n\n/** USDC address on Base mainnet */\nexport const USDC_BASE = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913';\n\n// ============================================================================\n// Facilitator Constants\n// ============================================================================\n\n/** Dexter's public x402 v2 facilitator URL */\nexport const DEXTER_FACILITATOR_URL = 'https://x402.dexter.cash';\n\n// ============================================================================\n// Payment Types\n// ============================================================================\n\n/**\n * Asset configuration for payments\n */\nexport interface AssetConfig {\n /** Token address (mint on Solana, contract on EVM) */\n address: string;\n /** Token decimals */\n decimals: number;\n /** Optional: Human-readable symbol */\n symbol?: string;\n}\n\n/**\n * Resource info included in payment requirements\n */\nexport interface ResourceInfo {\n /** Resource URL */\n url: string;\n /** Human-readable description */\n description?: string;\n /** MIME type of the resource */\n mimeType?: string;\n}\n\n/**\n * Extra fields in payment requirements\n * Chain-specific fields may vary\n */\nexport interface AcceptsExtra {\n /** Facilitator address that pays tx fees (required) */\n feePayer: string;\n /** Token decimals (required) */\n decimals: number;\n /** EIP-712: Token name (EVM only) */\n name?: string;\n /** EIP-712: Token version (EVM only) */\n version?: string;\n /** Additional chain-specific fields */\n [key: string]: unknown;\n}\n\n/**\n * A single payment option in the accepts array\n */\nexport interface PaymentAccept {\n /** Payment scheme (always 'exact' for x402 v2) */\n scheme: 'exact';\n /** CAIP-2 network identifier */\n network: string;\n /** Payment amount in atomic units (as string to avoid precision loss) */\n amount: string;\n /** Token address */\n asset: string;\n /** Seller's address to receive payment */\n payTo: string;\n /** Maximum seconds until payment expires */\n maxTimeoutSeconds: number;\n /** Chain-specific extra data */\n extra: AcceptsExtra;\n}\n\n/**\n * Full PaymentRequired structure (sent in PAYMENT-REQUIRED header)\n */\nexport interface PaymentRequired {\n /** x402 version (always 2) */\n x402Version: 2;\n /** Resource being accessed */\n resource: ResourceInfo;\n /** Available payment options */\n accepts: PaymentAccept[];\n /** Optional error message */\n error?: string;\n}\n\n/**\n * PaymentSignature structure (sent in PAYMENT-SIGNATURE header)\n */\nexport interface PaymentSignature {\n /** x402 version (always 2) */\n x402Version: 2;\n /** Resource being accessed */\n resource: ResourceInfo;\n /** The payment option that was accepted */\n accepted: PaymentAccept;\n /** The signed payment */\n payload: {\n /** Signed transaction (base64 for Solana, JSON for EVM) */\n transaction: string;\n };\n}\n\n// ============================================================================\n// Facilitator Response Types\n// ============================================================================\n\n/**\n * Response from /verify endpoint\n */\nexport interface VerifyResponse {\n /** Whether the payment is valid */\n isValid: boolean;\n /** Reason for invalidity (if invalid) */\n invalidReason?: string;\n /** Payer address */\n payer?: string;\n}\n\n/**\n * Response from /settle endpoint\n */\nexport interface SettleResponse {\n /** Whether settlement succeeded */\n success: boolean;\n /** Transaction signature/hash */\n transaction?: string;\n /** Network the payment was made on */\n network: string;\n /** Error reason (if failed) */\n errorReason?: string;\n /** Error code (if failed) */\n errorCode?: string;\n /** Payer address */\n payer?: string;\n}\n\n// ============================================================================\n// Error Types\n// ============================================================================\n\n/**\n * SDK error codes\n */\nexport type X402ErrorCode =\n // Client errors\n | 'missing_payment_required_header'\n | 'invalid_payment_required'\n | 'unsupported_network'\n | 'no_matching_payment_option'\n | 'no_solana_accept' // Legacy, kept for compatibility\n | 'missing_fee_payer'\n | 'missing_decimals'\n | 'amount_exceeds_max'\n | 'insufficient_balance'\n | 'wallet_missing_sign_transaction'\n | 'wallet_not_connected'\n | 'transaction_build_failed'\n | 'payment_rejected'\n // Server errors\n | 'invalid_payment_signature'\n | 'facilitator_verify_failed'\n | 'facilitator_settle_failed'\n | 'facilitator_request_failed'\n | 'no_matching_requirement';\n\n/**\n * Custom error class for x402 operations\n */\nexport class X402Error extends Error {\n /** Error code for programmatic handling */\n code: X402ErrorCode;\n /** Additional error details */\n details?: unknown;\n\n constructor(code: X402ErrorCode, message: string, details?: unknown) {\n super(message);\n this.name = 'X402Error';\n this.code = code;\n this.details = details;\n // Maintain proper prototype chain\n Object.setPrototypeOf(this, X402Error.prototype);\n }\n}\n","/**\n * Utility Functions\n *\n * Chain-agnostic helpers for x402 payments.\n */\n\nimport { SOLANA_MAINNET_NETWORK, BASE_MAINNET_NETWORK } from './types';\n\n// ============================================================================\n// Amount Conversion\n// ============================================================================\n\n/**\n * Convert human-readable amount to atomic units\n *\n * @param amount - Human-readable amount (e.g., 0.05 for $0.05)\n * @param decimals - Token decimals (e.g., 6 for USDC)\n * @returns Amount in atomic units as string\n *\n * @example\n * ```typescript\n * toAtomicUnits(0.05, 6) // '50000'\n * toAtomicUnits(1.50, 6) // '1500000'\n * ```\n */\nexport function toAtomicUnits(amount: number, decimals: number): string {\n const multiplier = Math.pow(10, decimals);\n return Math.floor(amount * multiplier).toString();\n}\n\n/**\n * Convert atomic units to human-readable amount\n *\n * @param atomicUnits - Amount in smallest units\n * @param decimals - Token decimals\n * @returns Human-readable amount\n *\n * @example\n * ```typescript\n * fromAtomicUnits('50000', 6) // 0.05\n * fromAtomicUnits(1500000n, 6) // 1.5\n * ```\n */\nexport function fromAtomicUnits(\n atomicUnits: string | bigint | number,\n decimals: number\n): number {\n const divisor = Math.pow(10, decimals);\n return Number(atomicUnits) / divisor;\n}\n\n// ============================================================================\n// Network Helpers\n// ============================================================================\n\n/**\n * Network type\n */\nexport type ChainFamily = 'solana' | 'evm' | 'unknown';\n\n/**\n * Get the chain family from a CAIP-2 network identifier\n *\n * @param network - CAIP-2 network identifier\n * @returns Chain family\n *\n * @example\n * ```typescript\n * getChainFamily('solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp') // 'solana'\n * getChainFamily('eip155:8453') // 'evm'\n * ```\n */\nexport function getChainFamily(network: string): ChainFamily {\n if (network.startsWith('solana:') || network === 'solana') {\n return 'solana';\n }\n if (network.startsWith('eip155:') || ['base', 'ethereum', 'arbitrum'].includes(network)) {\n return 'evm';\n }\n return 'unknown';\n}\n\n/**\n * Get default RPC URL for a network\n *\n * @param network - CAIP-2 network identifier\n * @returns Default RPC URL\n */\nexport function getDefaultRpcUrl(network: string): string {\n const family = getChainFamily(network);\n\n if (family === 'solana') {\n if (network.includes('devnet') || network === 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1') {\n return 'https://api.devnet.solana.com';\n }\n if (network.includes('testnet') || network === 'solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z') {\n return 'https://api.testnet.solana.com';\n }\n return 'https://api.mainnet-beta.solana.com';\n }\n\n if (family === 'evm') {\n // Extract chain ID from CAIP-2\n if (network.startsWith('eip155:')) {\n const chainId = network.split(':')[1];\n switch (chainId) {\n case '8453': return 'https://mainnet.base.org';\n case '84532': return 'https://sepolia.base.org';\n case '1': return 'https://eth.llamarpc.com';\n case '42161': return 'https://arb1.arbitrum.io/rpc';\n default: return 'https://mainnet.base.org';\n }\n }\n // Legacy names\n if (network === 'base') return 'https://mainnet.base.org';\n if (network === 'ethereum') return 'https://eth.llamarpc.com';\n if (network === 'arbitrum') return 'https://arb1.arbitrum.io/rpc';\n return 'https://mainnet.base.org';\n }\n\n // Unknown - return a generic\n return 'https://api.mainnet-beta.solana.com';\n}\n\n/**\n * Get human-readable chain name\n *\n * @param network - CAIP-2 network identifier\n * @returns Human-readable name\n */\nexport function getChainName(network: string): string {\n const mapping: Record<string, string> = {\n [SOLANA_MAINNET_NETWORK]: 'Solana',\n 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1': 'Solana Devnet',\n 'solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z': 'Solana Testnet',\n 'solana': 'Solana',\n [BASE_MAINNET_NETWORK]: 'Base',\n 'eip155:84532': 'Base Sepolia',\n 'eip155:1': 'Ethereum',\n 'eip155:42161': 'Arbitrum One',\n 'base': 'Base',\n 'ethereum': 'Ethereum',\n 'arbitrum': 'Arbitrum',\n };\n return mapping[network] || network;\n}\n\n// ============================================================================\n// Transaction URL Helpers\n// ============================================================================\n\n/**\n * Get explorer URL for a transaction\n *\n * @param txSignature - Transaction signature/hash\n * @param network - CAIP-2 network identifier\n * @returns Explorer URL\n */\nexport function getExplorerUrl(txSignature: string, network: string): string {\n const family = getChainFamily(network);\n\n if (family === 'solana') {\n const isDevnet = network.includes('devnet') || network === 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1';\n if (isDevnet) {\n return `https://solscan.io/tx/${txSignature}?cluster=devnet`;\n }\n // Prefer Orb Markets for mainnet\n return `https://www.orbmarkets.io/tx/${txSignature}`;\n }\n\n if (family === 'evm') {\n // Extract chain ID\n let chainId = '8453'; // Default to Base\n if (network.startsWith('eip155:')) {\n chainId = network.split(':')[1];\n } else if (network === 'ethereum') {\n chainId = '1';\n } else if (network === 'arbitrum') {\n chainId = '42161';\n }\n\n switch (chainId) {\n case '8453': return `https://basescan.org/tx/${txSignature}`;\n case '84532': return `https://sepolia.basescan.org/tx/${txSignature}`;\n case '1': return `https://etherscan.io/tx/${txSignature}`;\n case '42161': return `https://arbiscan.io/tx/${txSignature}`;\n default: return `https://basescan.org/tx/${txSignature}`;\n }\n }\n\n return `https://solscan.io/tx/${txSignature}`;\n}\n\n// ============================================================================\n// Encoding Helpers\n// ============================================================================\n\n/**\n * Encode an object as base64 JSON\n */\nexport function encodeBase64Json(obj: unknown): string {\n return btoa(JSON.stringify(obj));\n}\n\n/**\n * Decode base64 JSON to object\n */\nexport function decodeBase64Json<T>(encoded: string): T {\n return JSON.parse(atob(encoded)) as T;\n}\n"],"mappings":";AAYO,IAAM,yBAAyB;AAG/B,IAAM,uBAAuB;;;ACU7B,SAAS,cAAc,QAAgB,UAA0B;AACtE,QAAM,aAAa,KAAK,IAAI,IAAI,QAAQ;AACxC,SAAO,KAAK,MAAM,SAAS,UAAU,EAAE,SAAS;AAClD;AAeO,SAAS,gBACd,aACA,UACQ;AACR,QAAM,UAAU,KAAK,IAAI,IAAI,QAAQ;AACrC,SAAO,OAAO,WAAW,IAAI;AAC/B;AAuBO,SAAS,eAAe,SAA8B;AAC3D,MAAI,QAAQ,WAAW,SAAS,KAAK,YAAY,UAAU;AACzD,WAAO;AAAA,EACT;AACA,MAAI,QAAQ,WAAW,SAAS,KAAK,CAAC,QAAQ,YAAY,UAAU,EAAE,SAAS,OAAO,GAAG;AACvF,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAkDO,SAAS,aAAa,SAAyB;AACpD,QAAM,UAAkC;AAAA,IACtC,CAAC,sBAAsB,GAAG;AAAA,IAC1B,2CAA2C;AAAA,IAC3C,2CAA2C;AAAA,IAC3C,UAAU;AAAA,IACV,CAAC,oBAAoB,GAAG;AAAA,IACxB,gBAAgB;AAAA,IAChB,YAAY;AAAA,IACZ,gBAAgB;AAAA,IAChB,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,YAAY;AAAA,EACd;AACA,SAAO,QAAQ,OAAO,KAAK;AAC7B;AAaO,SAAS,eAAe,aAAqB,SAAyB;AAC3E,QAAM,SAAS,eAAe,OAAO;AAErC,MAAI,WAAW,UAAU;AACvB,UAAM,WAAW,QAAQ,SAAS,QAAQ,KAAK,YAAY;AAC3D,QAAI,UAAU;AACZ,aAAO,yBAAyB,WAAW;AAAA,IAC7C;AAEA,WAAO,gCAAgC,WAAW;AAAA,EACpD;AAEA,MAAI,WAAW,OAAO;AAEpB,QAAI,UAAU;AACd,QAAI,QAAQ,WAAW,SAAS,GAAG;AACjC,gBAAU,QAAQ,MAAM,GAAG,EAAE,CAAC;AAAA,IAChC,WAAW,YAAY,YAAY;AACjC,gBAAU;AAAA,IACZ,WAAW,YAAY,YAAY;AACjC,gBAAU;AAAA,IACZ;AAEA,YAAQ,SAAS;AAAA,MACf,KAAK;AAAQ,eAAO,2BAA2B,WAAW;AAAA,MAC1D,KAAK;AAAS,eAAO,mCAAmC,WAAW;AAAA,MACnE,KAAK;AAAK,eAAO,2BAA2B,WAAW;AAAA,MACvD,KAAK;AAAS,eAAO,0BAA0B,WAAW;AAAA,MAC1D;AAAS,eAAO,2BAA2B,WAAW;AAAA,IACxD;AAAA,EACF;AAEA,SAAO,yBAAyB,WAAW;AAC7C;","names":[]}
@@ -1,4 +1,4 @@
1
- import { C as ChainAdapter, W as WalletSet } from './types-uljmYAuY.js';
1
+ import { C as ChainAdapter, W as WalletSet } from './types-DxszTTWX.js';
2
2
 
3
3
  /**
4
4
  * x402 v2 Client
@@ -1,4 +1,4 @@
1
- import { C as ChainAdapter, W as WalletSet } from './types-vWD8uj2B.cjs';
1
+ import { C as ChainAdapter, W as WalletSet } from './types-BFqfw6Mp.cjs';
2
2
 
3
3
  /**
4
4
  * x402 v2 Client