moltspay 1.3.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +221 -38
- package/dist/cdp/index.d.mts +4 -4
- package/dist/cdp/index.d.ts +4 -4
- package/dist/cdp/index.js +57 -0
- package/dist/cdp/index.js.map +1 -1
- package/dist/cdp/index.mjs +57 -0
- package/dist/cdp/index.mjs.map +1 -1
- package/dist/chains/index.d.mts +9 -8
- package/dist/chains/index.d.ts +9 -8
- package/dist/chains/index.js +57 -0
- package/dist/chains/index.js.map +1 -1
- package/dist/chains/index.mjs +57 -0
- package/dist/chains/index.mjs.map +1 -1
- package/dist/cli/index.js +1975 -273
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/index.mjs +1977 -265
- package/dist/cli/index.mjs.map +1 -1
- package/dist/client/index.d.mts +36 -3
- package/dist/client/index.d.ts +36 -3
- package/dist/client/index.js +540 -32
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +548 -30
- package/dist/client/index.mjs.map +1 -1
- package/dist/facilitators/index.d.mts +220 -1
- package/dist/facilitators/index.d.ts +220 -1
- package/dist/facilitators/index.js +664 -1
- package/dist/facilitators/index.js.map +1 -1
- package/dist/facilitators/index.mjs +670 -1
- package/dist/facilitators/index.mjs.map +1 -1
- package/dist/{index-On9ZaGDW.d.mts → index-D_2FkLwV.d.mts} +6 -2
- package/dist/{index-On9ZaGDW.d.ts → index-D_2FkLwV.d.ts} +6 -2
- package/dist/index.d.mts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +1413 -146
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1421 -144
- package/dist/index.mjs.map +1 -1
- package/dist/server/index.d.mts +13 -3
- package/dist/server/index.d.ts +13 -3
- package/dist/server/index.js +905 -52
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +915 -52
- package/dist/server/index.mjs.map +1 -1
- package/dist/verify/index.d.mts +1 -1
- package/dist/verify/index.d.ts +1 -1
- package/dist/verify/index.js +57 -0
- package/dist/verify/index.js.map +1 -1
- package/dist/verify/index.mjs +57 -0
- package/dist/verify/index.mjs.map +1 -1
- package/dist/wallet/index.d.mts +3 -3
- package/dist/wallet/index.d.ts +3 -3
- package/dist/wallet/index.js +57 -0
- package/dist/wallet/index.js.map +1 -1
- package/dist/wallet/index.mjs +57 -0
- package/dist/wallet/index.mjs.map +1 -1
- package/package.json +4 -1
- package/schemas/moltspay.services.schema.json +27 -132
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/facilitators/interface.ts","../../src/facilitators/cdp.ts","../../src/chains/index.ts","../../src/facilitators/tempo.ts","../../src/facilitators/registry.ts"],"sourcesContent":["/**\n * Facilitator Interface\n * \n * A facilitator is a service that handles x402 payment verification and settlement.\n * This abstraction allows MoltsPay to support multiple facilitators.\n * \n * @see https://www.x402.org/ecosystem?category=facilitators\n */\n\n/**\n * x402 Payment Payload (from client)\n */\nexport interface X402PaymentPayload {\n x402Version: number;\n scheme?: string;\n network?: string;\n accepted?: {\n scheme: string;\n network: string;\n asset: string;\n amount: string;\n payTo: string;\n maxTimeoutSeconds: number;\n extra?: Record<string, unknown>;\n };\n payload: unknown;\n}\n\n/**\n * x402 Payment Requirements (server specifies what it accepts)\n */\nexport interface X402PaymentRequirements {\n scheme: string;\n network: string;\n asset: string;\n amount: string;\n payTo: string;\n maxTimeoutSeconds: number;\n extra?: Record<string, unknown>;\n}\n\n/**\n * Result of payment verification\n */\nexport interface VerifyResult {\n valid: boolean;\n error?: string;\n details?: Record<string, unknown>;\n}\n\n/**\n * Result of payment settlement\n */\nexport interface SettleResult {\n success: boolean;\n transaction?: string;\n error?: string;\n status?: string;\n}\n\n/**\n * Facilitator health check result\n */\nexport interface HealthCheckResult {\n healthy: boolean;\n latencyMs?: number;\n error?: string;\n}\n\n/**\n * Facilitator fee information (for selection strategies)\n */\nexport interface FacilitatorFee {\n perTx: number;\n currency: string;\n freeQuota?: number;\n}\n\n/**\n * Facilitator configuration\n */\nexport interface FacilitatorConfig {\n /** Facilitator endpoint URL */\n endpoint?: string;\n /** API key (if required) */\n apiKey?: string;\n /** API secret (if required) */\n apiSecret?: string;\n /** Additional config specific to facilitator */\n [key: string]: unknown;\n}\n\n/**\n * Facilitator Interface\n * \n * All facilitators must implement this interface.\n */\nexport interface Facilitator {\n /** Unique identifier for this facilitator */\n readonly name: string;\n \n /** Human-readable display name */\n readonly displayName: string;\n \n /** Supported networks (e.g., [\"eip155:8453\", \"eip155:84532\"]) */\n readonly supportedNetworks: string[];\n \n /**\n * Check if facilitator is available and responsive\n */\n healthCheck(): Promise<HealthCheckResult>;\n \n /**\n * Verify a payment signature without executing it\n * \n * @param paymentPayload - The x402 payment payload from client\n * @param requirements - The payment requirements from server\n */\n verify(\n paymentPayload: X402PaymentPayload,\n requirements: X402PaymentRequirements\n ): Promise<VerifyResult>;\n \n /**\n * Settle a payment on-chain\n * \n * @param paymentPayload - The x402 payment payload from client\n * @param requirements - The payment requirements from server\n */\n settle(\n paymentPayload: X402PaymentPayload,\n requirements: X402PaymentRequirements\n ): Promise<SettleResult>;\n \n /**\n * Get current fee information (optional, for selection strategies)\n */\n getFee?(): Promise<FacilitatorFee>;\n \n /**\n * Check if this facilitator supports a given network\n */\n supportsNetwork(network: string): boolean;\n}\n\n/**\n * Base class with common functionality\n */\nexport abstract class BaseFacilitator implements Facilitator {\n abstract readonly name: string;\n abstract readonly displayName: string;\n abstract readonly supportedNetworks: string[];\n \n abstract healthCheck(): Promise<HealthCheckResult>;\n abstract verify(\n paymentPayload: X402PaymentPayload,\n requirements: X402PaymentRequirements\n ): Promise<VerifyResult>;\n abstract settle(\n paymentPayload: X402PaymentPayload,\n requirements: X402PaymentRequirements\n ): Promise<SettleResult>;\n \n supportsNetwork(network: string): boolean {\n return this.supportedNetworks.includes(network);\n }\n}\n","/**\n * CDP Facilitator\n * \n * Coinbase Developer Platform x402 facilitator implementation.\n * Auto-detects mainnet vs testnet from chain ID in request.\n * \n * Supported networks:\n * - Base mainnet (eip155:8453)\n * - Polygon mainnet (eip155:137)\n * - Base Sepolia testnet (eip155:84532)\n * \n * @see https://docs.cdp.coinbase.com/x402/core-concepts/facilitator\n */\n\nimport { readFileSync, existsSync } from 'fs';\nimport * as path from 'path';\nimport {\n BaseFacilitator,\n X402PaymentPayload,\n X402PaymentRequirements,\n VerifyResult,\n SettleResult,\n HealthCheckResult,\n FacilitatorFee,\n FacilitatorConfig,\n} from './interface.js';\n\n// x402 protocol version\nconst X402_VERSION = 2;\n\n// CDP Facilitator URL (handles both mainnet and testnet)\nconst CDP_URL = 'https://api.cdp.coinbase.com/platform/v2/x402';\n\n// Testnet chain IDs (for logging/info only - CDP auto-detects from network field)\nconst TESTNET_CHAIN_IDS = [84532]; // Base Sepolia\n\nexport interface CDPFacilitatorConfig extends FacilitatorConfig {\n /** CDP API Key ID (required) */\n apiKeyId?: string;\n /** CDP API Key Secret (required) */\n apiKeySecret?: string;\n}\n\n/**\n * Load environment from .env files\n */\nfunction loadEnvFile(): void {\n const envPaths = [\n path.join(process.cwd(), '.env'),\n path.join(process.env.HOME || '', '.moltspay', '.env'),\n ];\n \n for (const envPath of envPaths) {\n if (existsSync(envPath)) {\n try {\n const content = readFileSync(envPath, 'utf-8');\n for (const line of content.split('\\n')) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('#')) continue;\n const eqIndex = trimmed.indexOf('=');\n if (eqIndex === -1) continue;\n const key = trimmed.slice(0, eqIndex).trim();\n let value = trimmed.slice(eqIndex + 1).trim();\n if ((value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))) {\n value = value.slice(1, -1);\n }\n if (!process.env[key]) {\n process.env[key] = value;\n }\n }\n break;\n } catch {\n // Ignore errors\n }\n }\n }\n}\n\n/**\n * CDP (Coinbase Developer Platform) Facilitator\n * \n * Handles payment verification and settlement via Coinbase's x402 facilitator.\n */\nexport class CDPFacilitator extends BaseFacilitator {\n readonly name = 'cdp';\n readonly displayName = 'Coinbase CDP';\n readonly supportedNetworks: string[];\n \n private endpoint: string;\n private apiKeyId?: string;\n private apiKeySecret?: string;\n \n constructor(config: CDPFacilitatorConfig = {}) {\n super();\n \n // Load env files for credentials\n loadEnvFile();\n \n // Get credentials (required for CDP)\n this.apiKeyId = config.apiKeyId || process.env.CDP_API_KEY_ID;\n this.apiKeySecret = config.apiKeySecret || process.env.CDP_API_KEY_SECRET;\n \n // Single endpoint handles both mainnet and testnet (auto-detected from chain ID in request)\n this.endpoint = CDP_URL;\n \n // All supported networks - CDP handles both mainnet and testnet\n this.supportedNetworks = [\n 'eip155:8453', // Base mainnet\n 'eip155:137', // Polygon mainnet\n 'eip155:84532', // Base Sepolia (testnet)\n ];\n \n // Warn if missing credentials\n if (!this.apiKeyId || !this.apiKeySecret) {\n console.warn('[CDPFacilitator] WARNING: Missing CDP credentials!');\n console.warn('[CDPFacilitator] Set CDP_API_KEY_ID and CDP_API_KEY_SECRET in ~/.moltspay/.env');\n }\n }\n \n /**\n * Get auth headers for CDP API requests\n */\n private async getAuthHeaders(\n method: string,\n urlPath: string,\n body?: unknown\n ): Promise<Record<string, string>> {\n if (!this.apiKeyId || !this.apiKeySecret) {\n throw new Error('CDP credentials required. Set CDP_API_KEY_ID and CDP_API_KEY_SECRET');\n }\n \n try {\n const { getAuthHeaders } = await import('@coinbase/cdp-sdk/auth');\n \n return await getAuthHeaders({\n apiKeyId: this.apiKeyId,\n apiKeySecret: this.apiKeySecret,\n requestMethod: method,\n requestHost: 'api.cdp.coinbase.com',\n requestPath: urlPath,\n requestBody: body,\n });\n } catch (err: any) {\n throw new Error(`Failed to generate CDP auth: ${err.message}`);\n }\n }\n \n /**\n * Health check - verify facilitator is reachable\n */\n async healthCheck(): Promise<HealthCheckResult> {\n const start = Date.now();\n \n try {\n // For testnet, just check if x402.org responds\n // For mainnet, we could hit a health endpoint or just check DNS\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 5000);\n \n const response = await fetch(this.endpoint.replace('/x402', ''), {\n method: 'HEAD',\n signal: controller.signal,\n }).catch(() => null);\n \n clearTimeout(timeout);\n \n const latencyMs = Date.now() - start;\n \n return {\n healthy: response !== null,\n latencyMs,\n };\n } catch (err: any) {\n return {\n healthy: false,\n error: err.message,\n latencyMs: Date.now() - start,\n };\n }\n }\n \n /**\n * Verify payment signature with facilitator\n */\n async verify(\n paymentPayload: X402PaymentPayload,\n requirements: X402PaymentRequirements\n ): Promise<VerifyResult> {\n try {\n const requestBody = {\n x402Version: X402_VERSION,\n paymentPayload,\n paymentRequirements: requirements,\n };\n \n console.log('[CDP Verify] Payload:', JSON.stringify(paymentPayload, null, 2));\n \n const authHeaders = await this.getAuthHeaders(\n 'POST',\n '/platform/v2/x402/verify',\n requestBody\n );\n \n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...authHeaders,\n };\n \n const response = await fetch(`${this.endpoint}/verify`, {\n method: 'POST',\n headers,\n body: JSON.stringify(requestBody),\n });\n \n const result = await response.json() as any;\n console.log('[CDP Verify] Response:', response.status, JSON.stringify(result));\n \n if (!response.ok || !result.isValid) {\n return {\n valid: false,\n error: result.invalidReason || result.error || 'Verification failed',\n details: result,\n };\n }\n \n return { valid: true, details: result };\n } catch (err: any) {\n return {\n valid: false,\n error: `Facilitator error: ${err.message}`,\n };\n }\n }\n \n /**\n * Settle payment on-chain via facilitator\n */\n async settle(\n paymentPayload: X402PaymentPayload,\n requirements: X402PaymentRequirements\n ): Promise<SettleResult> {\n try {\n const requestBody = {\n x402Version: X402_VERSION,\n paymentPayload,\n paymentRequirements: requirements,\n };\n \n const authHeaders = await this.getAuthHeaders(\n 'POST',\n '/platform/v2/x402/settle',\n requestBody\n );\n \n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...authHeaders,\n };\n \n const response = await fetch(`${this.endpoint}/settle`, {\n method: 'POST',\n headers,\n body: JSON.stringify(requestBody),\n });\n \n const result = await response.json() as any;\n \n if (!response.ok || !result.success) {\n return {\n success: false,\n error: result.error || result.errorReason || 'Settlement failed',\n };\n }\n \n return {\n success: true,\n transaction: result.transaction,\n status: result.status || 'settled',\n };\n } catch (err: any) {\n return {\n success: false,\n error: `Settlement error: ${err.message}`,\n };\n }\n }\n \n /**\n * Get CDP fee information\n */\n async getFee(): Promise<FacilitatorFee> {\n // CDP pricing: 1000 free/month, then $0.001/tx\n return {\n perTx: 0.001,\n currency: 'USD',\n freeQuota: 1000,\n };\n }\n \n /**\n * Check if a chain ID is testnet\n */\n static isTestnet(chainId: number): boolean {\n return TESTNET_CHAIN_IDS.includes(chainId);\n }\n \n /**\n * Get configuration summary (for logging)\n */\n getConfigSummary(): string {\n const hasCredentials = !!(this.apiKeyId && this.apiKeySecret);\n const networks = this.supportedNetworks.join(', ');\n return `CDP Facilitator (networks: ${networks}, credentials: ${hasCredentials ? 'yes' : 'no'})`;\n }\n}\n","/**\n * Blockchain Configuration\n */\n\nimport type { ChainConfig, ChainName, TokenSymbol } from '../types/index.js';\n\nexport const CHAINS: Record<ChainName, ChainConfig> = {\n // ============ Mainnet ============\n base: {\n name: 'Base',\n chainId: 8453,\n rpc: 'https://mainnet.base.org',\n tokens: {\n USDC: {\n address: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\n decimals: 6,\n symbol: 'USDC',\n eip712Name: 'USD Coin', // EIP-712 domain name\n },\n USDT: {\n address: '0xfde4C96c8593536E31F229EA8f37b2ADa2699bb2',\n decimals: 6,\n symbol: 'USDT',\n eip712Name: 'Tether USD',\n },\n },\n usdc: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', // deprecated, for backward compat\n explorer: 'https://basescan.org/address/',\n explorerTx: 'https://basescan.org/tx/',\n avgBlockTime: 2,\n },\n polygon: {\n name: 'Polygon',\n chainId: 137,\n rpc: 'https://polygon-bor-rpc.publicnode.com',\n tokens: {\n USDC: {\n address: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',\n decimals: 6,\n symbol: 'USDC',\n eip712Name: 'USD Coin',\n },\n USDT: {\n address: '0xc2132D05D31c914a87C6611C10748AEb04B58e8F',\n decimals: 6,\n symbol: 'USDT',\n eip712Name: '(PoS) Tether USD', // Polygon uses this name\n },\n },\n usdc: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',\n explorer: 'https://polygonscan.com/address/',\n explorerTx: 'https://polygonscan.com/tx/',\n avgBlockTime: 2,\n },\n // ============ Testnet ============\n base_sepolia: {\n name: 'Base Sepolia',\n chainId: 84532,\n rpc: 'https://sepolia.base.org',\n tokens: {\n USDC: {\n address: '0x036CbD53842c5426634e7929541eC2318f3dCF7e',\n decimals: 6,\n symbol: 'USDC',\n eip712Name: 'USDC', // Testnet USDC uses 'USDC' not 'USD Coin'\n },\n USDT: {\n address: '0x036CbD53842c5426634e7929541eC2318f3dCF7e', // Same as USDC on testnet (no official USDT)\n decimals: 6,\n symbol: 'USDT',\n eip712Name: 'USDC', // Uses same contract as USDC\n },\n },\n usdc: '0x036CbD53842c5426634e7929541eC2318f3dCF7e',\n explorer: 'https://sepolia.basescan.org/address/',\n explorerTx: 'https://sepolia.basescan.org/tx/',\n avgBlockTime: 2,\n },\n // ============ Tempo Testnet (Moderato) ============\n tempo_moderato: {\n name: 'Tempo Moderato',\n chainId: 42431,\n rpc: 'https://rpc.moderato.tempo.xyz',\n tokens: {\n // TIP-20 stablecoins on Tempo testnet (from mppx SDK)\n // Note: Tempo uses USD as native gas token, not ETH\n USDC: {\n address: '0x20c0000000000000000000000000000000000000', // pathUSD - primary testnet stablecoin\n decimals: 6,\n symbol: 'USDC',\n eip712Name: 'pathUSD',\n },\n USDT: {\n address: '0x20c0000000000000000000000000000000000001', // alphaUSD\n decimals: 6,\n symbol: 'USDT',\n eip712Name: 'alphaUSD',\n },\n },\n usdc: '0x20c0000000000000000000000000000000000000',\n explorer: 'https://explore.testnet.tempo.xyz/address/',\n explorerTx: 'https://explore.testnet.tempo.xyz/tx/',\n avgBlockTime: 0.5, // ~500ms finality\n },\n};\n\n/**\n * Get token address for a chain\n */\nexport function getTokenAddress(chainName: ChainName, token: TokenSymbol): string {\n const chain = CHAINS[chainName];\n if (!chain) {\n throw new Error(`Unsupported chain: ${chainName}`);\n }\n const tokenConfig = chain.tokens[token];\n if (!tokenConfig) {\n throw new Error(`Token ${token} not supported on ${chainName}`);\n }\n return tokenConfig.address;\n}\n\n/**\n * Get token config for a chain\n */\nexport function getTokenConfig(chainName: ChainName, token: TokenSymbol) {\n const chain = CHAINS[chainName];\n if (!chain) {\n throw new Error(`Unsupported chain: ${chainName}`);\n }\n return chain.tokens[token];\n}\n\n/**\n * Get chain configuration\n */\nexport function getChain(name: ChainName): ChainConfig {\n const config = CHAINS[name];\n if (!config) {\n throw new Error(`Unsupported chain: ${name}. Supported: ${Object.keys(CHAINS).join(', ')}`);\n }\n return config;\n}\n\n/**\n * List all supported chains\n */\nexport function listChains(): ChainName[] {\n return Object.keys(CHAINS) as ChainName[];\n}\n\n/**\n * Get chain config by chainId\n */\nexport function getChainById(chainId: number): ChainConfig | undefined {\n return Object.values(CHAINS).find(c => c.chainId === chainId);\n}\n\n/**\n * ERC20 ABI (minimal, only required methods)\n */\nexport const ERC20_ABI = [\n 'function balanceOf(address owner) view returns (uint256)',\n 'function transfer(address to, uint256 amount) returns (bool)',\n 'function approve(address spender, uint256 amount) returns (bool)',\n 'function allowance(address owner, address spender) view returns (uint256)',\n 'function decimals() view returns (uint8)',\n 'function symbol() view returns (string)',\n 'function name() view returns (string)',\n 'function nonces(address owner) view returns (uint256)',\n 'function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s)',\n 'event Transfer(address indexed from, address indexed to, uint256 value)',\n 'event Approval(address indexed owner, address indexed spender, uint256 value)',\n];\n\nexport type { ChainConfig, ChainName, TokenSymbol };\n","/**\n * Tempo Testnet Facilitator\n * \n * Verifies payments on Tempo Moderato testnet by checking transaction receipts.\n * Unlike CDP facilitator, this directly verifies on-chain without a third-party service.\n */\n\nimport {\n BaseFacilitator,\n X402PaymentPayload,\n X402PaymentRequirements,\n VerifyResult,\n SettleResult,\n HealthCheckResult,\n} from './interface.js';\nimport { CHAINS } from '../chains/index.js';\n\n// TIP-20 Transfer event signature\nconst TRANSFER_EVENT_TOPIC = '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef';\n\ninterface TempoPaymentPayload {\n txHash: string;\n chainId: number;\n}\n\n/**\n * Tempo Testnet Facilitator\n * \n * Verifies TIP-20 token transfers on Tempo Moderato (chainId 42431).\n */\nexport class TempoFacilitator extends BaseFacilitator {\n readonly name = 'tempo';\n readonly displayName = 'Tempo Testnet';\n readonly supportedNetworks = ['eip155:42431']; // Tempo Moderato\n\n private rpcUrl: string;\n\n constructor() {\n super();\n this.rpcUrl = CHAINS.tempo_moderato.rpc;\n }\n\n async healthCheck(): Promise<HealthCheckResult> {\n const start = Date.now();\n try {\n const response = await fetch(this.rpcUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n jsonrpc: '2.0',\n method: 'eth_chainId',\n params: [],\n id: 1,\n }),\n });\n \n const data = await response.json() as { result: string };\n const chainId = parseInt(data.result, 16);\n \n if (chainId !== 42431) {\n return { healthy: false, error: `Wrong chainId: ${chainId}` };\n }\n \n return { healthy: true, latencyMs: Date.now() - start };\n } catch (error) {\n return { healthy: false, error: String(error) };\n }\n }\n\n async verify(\n paymentPayload: X402PaymentPayload,\n requirements: X402PaymentRequirements\n ): Promise<VerifyResult> {\n try {\n // Extract Tempo-specific payload\n const tempoPayload = paymentPayload.payload as TempoPaymentPayload;\n \n if (!tempoPayload?.txHash) {\n return { valid: false, error: 'Missing txHash in payment payload' };\n }\n\n // Get transaction receipt\n const receipt = await this.getTransactionReceipt(tempoPayload.txHash);\n \n if (!receipt) {\n return { valid: false, error: 'Transaction not found' };\n }\n\n if (receipt.status !== '0x1') {\n return { valid: false, error: 'Transaction failed' };\n }\n\n // Find Transfer event\n const transferLog = receipt.logs.find((log: any) => \n log.topics[0] === TRANSFER_EVENT_TOPIC\n );\n\n if (!transferLog) {\n return { valid: false, error: 'No Transfer event found' };\n }\n\n // Verify recipient (topic[2] is 'to' address, padded to 32 bytes)\n const toAddress = '0x' + transferLog.topics[2].slice(26).toLowerCase();\n const expectedTo = requirements.payTo.toLowerCase();\n \n if (toAddress !== expectedTo) {\n return { \n valid: false, \n error: `Wrong recipient: ${toAddress}, expected ${expectedTo}` \n };\n }\n\n // Verify amount (data field contains the amount)\n const amount = BigInt(transferLog.data);\n const expectedAmount = BigInt(requirements.amount);\n \n if (amount < expectedAmount) {\n return { \n valid: false, \n error: `Insufficient amount: ${amount}, expected ${expectedAmount}` \n };\n }\n\n // Verify token address\n const tokenAddress = transferLog.address.toLowerCase();\n const expectedToken = requirements.asset.toLowerCase();\n \n if (tokenAddress !== expectedToken) {\n return { \n valid: false, \n error: `Wrong token: ${tokenAddress}, expected ${expectedToken}` \n };\n }\n\n return { \n valid: true, \n details: {\n txHash: tempoPayload.txHash,\n from: '0x' + transferLog.topics[1].slice(26),\n to: toAddress,\n amount: amount.toString(),\n token: tokenAddress,\n }\n };\n } catch (error) {\n return { valid: false, error: `Verification failed: ${error}` };\n }\n }\n\n async settle(\n paymentPayload: X402PaymentPayload,\n requirements: X402PaymentRequirements\n ): Promise<SettleResult> {\n // For Tempo, the client already executed the transaction\n // We just verify and report success\n const verifyResult = await this.verify(paymentPayload, requirements);\n \n if (!verifyResult.valid) {\n return { success: false, error: verifyResult.error };\n }\n\n const tempoPayload = paymentPayload.payload as TempoPaymentPayload;\n \n return { \n success: true, \n transaction: tempoPayload.txHash,\n status: 'settled'\n };\n }\n\n private async getTransactionReceipt(txHash: string): Promise<any> {\n const response = await fetch(this.rpcUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n jsonrpc: '2.0',\n method: 'eth_getTransactionReceipt',\n params: [txHash],\n id: 1,\n }),\n });\n\n const data = await response.json() as { result: any };\n return data.result;\n }\n}\n","/**\n * Facilitator Registry\n * \n * Central registry for all available facilitators.\n * Supports selection strategies for failover, load balancing, etc.\n */\n\nimport {\n Facilitator,\n FacilitatorConfig,\n X402PaymentPayload,\n X402PaymentRequirements,\n VerifyResult,\n SettleResult,\n HealthCheckResult,\n} from './interface.js';\nimport { CDPFacilitator, CDPFacilitatorConfig } from './cdp.js';\nimport { TempoFacilitator } from './tempo.js';\n\n/**\n * Selection strategy for choosing facilitators\n */\nexport type SelectionStrategy = \n | 'failover' // Use primary, switch to fallback on failure\n | 'cheapest' // Use facilitator with lowest fees\n | 'fastest' // Use first responder\n | 'random' // Random selection (load balancing)\n | 'roundrobin'; // Rotate through facilitators\n\n/**\n * Facilitator selection configuration\n */\nexport interface FacilitatorSelection {\n /** Primary facilitator to use */\n primary: string;\n /** Fallback facilitators (in order of preference) */\n fallback?: string[];\n /** Selection strategy */\n strategy?: SelectionStrategy;\n /** Per-facilitator config overrides */\n config?: Record<string, FacilitatorConfig>;\n}\n\n/**\n * Factory function type for creating facilitators\n */\ntype FacilitatorFactory = (config?: FacilitatorConfig) => Facilitator;\n\n/**\n * Facilitator Registry\n * \n * Manages available facilitators and provides selection logic.\n */\nexport class FacilitatorRegistry {\n private factories: Map<string, FacilitatorFactory> = new Map();\n private instances: Map<string, Facilitator> = new Map();\n private selection: FacilitatorSelection;\n private roundRobinIndex = 0;\n \n constructor(selection?: FacilitatorSelection) {\n // Register built-in facilitators\n this.registerFactory('cdp', (config) => new CDPFacilitator(config as CDPFacilitatorConfig));\n this.registerFactory('tempo', () => new TempoFacilitator());\n \n // Default selection\n this.selection = selection || { primary: 'cdp', fallback: ['tempo'], strategy: 'failover' };\n }\n \n /**\n * Register a new facilitator factory\n */\n registerFactory(name: string, factory: FacilitatorFactory): void {\n this.factories.set(name, factory);\n }\n \n /**\n * Get or create a facilitator instance\n */\n get(name: string, config?: FacilitatorConfig): Facilitator {\n // Check cache first\n if (this.instances.has(name)) {\n return this.instances.get(name)!;\n }\n \n // Look up factory\n const factory = this.factories.get(name);\n if (!factory) {\n throw new Error(`Unknown facilitator: ${name}. Available: ${Array.from(this.factories.keys()).join(', ')}`);\n }\n \n // Merge config from selection\n const mergedConfig = {\n ...this.selection.config?.[name],\n ...config,\n };\n \n // Create and cache instance\n const instance = factory(mergedConfig);\n this.instances.set(name, instance);\n return instance;\n }\n \n /**\n * Get all configured facilitator names\n */\n getConfiguredNames(): string[] {\n const names = [this.selection.primary];\n if (this.selection.fallback) {\n names.push(...this.selection.fallback);\n }\n return names;\n }\n \n /**\n * Get list of facilitators based on selection strategy\n */\n private async getOrderedFacilitators(network: string): Promise<Facilitator[]> {\n const names = this.getConfiguredNames();\n const facilitators: Facilitator[] = [];\n \n for (const name of names) {\n try {\n const f = this.get(name);\n if (f.supportsNetwork(network)) {\n facilitators.push(f);\n }\n } catch (err) {\n console.warn(`[Registry] Failed to get facilitator ${name}:`, err);\n }\n }\n \n if (facilitators.length === 0) {\n throw new Error(`No facilitators available for network: ${network}`);\n }\n \n // Apply strategy\n switch (this.selection.strategy) {\n case 'random':\n return this.shuffle(facilitators);\n \n case 'roundrobin':\n this.roundRobinIndex = (this.roundRobinIndex + 1) % facilitators.length;\n return [\n ...facilitators.slice(this.roundRobinIndex),\n ...facilitators.slice(0, this.roundRobinIndex),\n ];\n \n case 'cheapest':\n return this.sortByCheapest(facilitators);\n \n case 'fastest':\n return this.sortByFastest(facilitators);\n \n case 'failover':\n default:\n return facilitators;\n }\n }\n \n private shuffle<T>(array: T[]): T[] {\n const result = [...array];\n for (let i = result.length - 1; i > 0; i--) {\n const j = Math.floor(Math.random() * (i + 1));\n [result[i], result[j]] = [result[j], result[i]];\n }\n return result;\n }\n \n private async sortByCheapest(facilitators: Facilitator[]): Promise<Facilitator[]> {\n const withFees = await Promise.all(\n facilitators.map(async (f) => {\n try {\n const fee = await f.getFee?.();\n return { facilitator: f, perTx: fee?.perTx ?? Infinity };\n } catch {\n return { facilitator: f, perTx: Infinity };\n }\n })\n );\n withFees.sort((a, b) => a.perTx - b.perTx);\n return withFees.map(w => w.facilitator);\n }\n \n private async sortByFastest(facilitators: Facilitator[]): Promise<Facilitator[]> {\n const withLatency = await Promise.all(\n facilitators.map(async (f) => {\n try {\n const health = await f.healthCheck();\n return { facilitator: f, latency: health.latencyMs ?? Infinity };\n } catch {\n return { facilitator: f, latency: Infinity };\n }\n })\n );\n withLatency.sort((a, b) => a.latency - b.latency);\n return withLatency.map(w => w.facilitator);\n }\n \n /**\n * Verify payment using configured facilitators\n */\n async verify(\n paymentPayload: X402PaymentPayload,\n requirements: X402PaymentRequirements\n ): Promise<VerifyResult & { facilitator: string }> {\n const network = paymentPayload.accepted?.network || paymentPayload.network || requirements.network;\n const facilitators = await this.getOrderedFacilitators(network);\n \n let lastError: string | undefined;\n \n for (const f of facilitators) {\n try {\n console.log(`[Registry] Trying ${f.name} for verify...`);\n const result = await f.verify(paymentPayload, requirements);\n \n if (result.valid) {\n console.log(`[Registry] ${f.name} verify succeeded`);\n return { ...result, facilitator: f.name };\n }\n \n lastError = result.error;\n console.log(`[Registry] ${f.name} verify failed: ${result.error}`);\n \n // For failover strategy, only try next if it's a network/server error\n if (this.selection.strategy === 'failover' && !this.isTransientError(result.error)) {\n // Permanent error (e.g., invalid signature) - don't try others\n break;\n }\n } catch (err: any) {\n lastError = err.message;\n console.error(`[Registry] ${f.name} error:`, err.message);\n }\n }\n \n return {\n valid: false,\n error: lastError || 'All facilitators failed',\n facilitator: 'none',\n };\n }\n \n /**\n * Settle payment using configured facilitators\n */\n async settle(\n paymentPayload: X402PaymentPayload,\n requirements: X402PaymentRequirements\n ): Promise<SettleResult & { facilitator: string }> {\n const network = paymentPayload.accepted?.network || paymentPayload.network || requirements.network;\n const facilitators = await this.getOrderedFacilitators(network);\n \n let lastError: string | undefined;\n \n for (const f of facilitators) {\n try {\n console.log(`[Registry] Trying ${f.name} for settle...`);\n const result = await f.settle(paymentPayload, requirements);\n \n if (result.success) {\n console.log(`[Registry] ${f.name} settle succeeded: ${result.transaction}`);\n return { ...result, facilitator: f.name };\n }\n \n lastError = result.error;\n console.log(`[Registry] ${f.name} settle failed: ${result.error}`);\n } catch (err: any) {\n lastError = err.message;\n console.error(`[Registry] ${f.name} error:`, err.message);\n }\n }\n \n return {\n success: false,\n error: lastError || 'All facilitators failed',\n facilitator: 'none',\n };\n }\n \n /**\n * Check health of all configured facilitators\n */\n async healthCheckAll(): Promise<Record<string, HealthCheckResult>> {\n const results: Record<string, HealthCheckResult> = {};\n \n for (const name of this.getConfiguredNames()) {\n try {\n const f = this.get(name);\n results[name] = await f.healthCheck();\n } catch (err: any) {\n results[name] = { healthy: false, error: err.message };\n }\n }\n \n return results;\n }\n \n /**\n * Check if an error is transient (network/server issue) vs permanent (bad request)\n */\n private isTransientError(error?: string): boolean {\n if (!error) return true;\n const transientPatterns = [\n /timeout/i,\n /network/i,\n /connection/i,\n /ECONNREFUSED/i,\n /ETIMEDOUT/i,\n /503/,\n /502/,\n /500/,\n ];\n return transientPatterns.some(p => p.test(error));\n }\n \n /**\n * Update selection configuration\n */\n setSelection(selection: FacilitatorSelection): void {\n this.selection = selection;\n // Clear cached instances to pick up new config\n this.instances.clear();\n }\n \n /**\n * Get current selection configuration\n */\n getSelection(): FacilitatorSelection {\n return { ...this.selection };\n }\n}\n\n// Default registry instance\nlet defaultRegistry: FacilitatorRegistry | null = null;\n\n/**\n * Get the default facilitator registry\n */\nexport function getDefaultRegistry(): FacilitatorRegistry {\n if (!defaultRegistry) {\n defaultRegistry = new FacilitatorRegistry();\n }\n return defaultRegistry;\n}\n\n/**\n * Create a new registry with custom selection\n */\nexport function createRegistry(selection?: FacilitatorSelection): FacilitatorRegistry {\n return new FacilitatorRegistry(selection);\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/facilitators/interface.ts","../../src/facilitators/cdp.ts","../../src/chains/index.ts","../../src/facilitators/tempo.ts","../../src/facilitators/bnb.ts","../../src/facilitators/solana.ts","../../src/chains/solana.ts","../../src/facilitators/registry.ts"],"sourcesContent":["/**\n * Facilitator Interface\n * \n * A facilitator is a service that handles x402 payment verification and settlement.\n * This abstraction allows MoltsPay to support multiple facilitators.\n * \n * @see https://www.x402.org/ecosystem?category=facilitators\n */\n\n/**\n * x402 Payment Payload (from client)\n */\nexport interface X402PaymentPayload {\n x402Version: number;\n scheme?: string;\n network?: string;\n accepted?: {\n scheme: string;\n network: string;\n asset: string;\n amount: string;\n payTo: string;\n maxTimeoutSeconds: number;\n extra?: Record<string, unknown>;\n };\n payload: unknown;\n}\n\n/**\n * x402 Payment Requirements (server specifies what it accepts)\n */\nexport interface X402PaymentRequirements {\n scheme: string;\n network: string;\n asset: string;\n amount: string;\n payTo: string;\n maxTimeoutSeconds: number;\n extra?: Record<string, unknown>;\n}\n\n/**\n * Result of payment verification\n */\nexport interface VerifyResult {\n valid: boolean;\n error?: string;\n details?: Record<string, unknown>;\n}\n\n/**\n * Result of payment settlement\n */\nexport interface SettleResult {\n success: boolean;\n transaction?: string;\n error?: string;\n status?: string;\n}\n\n/**\n * Facilitator health check result\n */\nexport interface HealthCheckResult {\n healthy: boolean;\n latencyMs?: number;\n error?: string;\n}\n\n/**\n * Facilitator fee information (for selection strategies)\n */\nexport interface FacilitatorFee {\n perTx: number;\n currency: string;\n freeQuota?: number;\n}\n\n/**\n * Facilitator configuration\n */\nexport interface FacilitatorConfig {\n /** Facilitator endpoint URL */\n endpoint?: string;\n /** API key (if required) */\n apiKey?: string;\n /** API secret (if required) */\n apiSecret?: string;\n /** Additional config specific to facilitator */\n [key: string]: unknown;\n}\n\n/**\n * Facilitator Interface\n * \n * All facilitators must implement this interface.\n */\nexport interface Facilitator {\n /** Unique identifier for this facilitator */\n readonly name: string;\n \n /** Human-readable display name */\n readonly displayName: string;\n \n /** Supported networks (e.g., [\"eip155:8453\", \"eip155:84532\"]) */\n readonly supportedNetworks: string[];\n \n /**\n * Check if facilitator is available and responsive\n */\n healthCheck(): Promise<HealthCheckResult>;\n \n /**\n * Verify a payment signature without executing it\n * \n * @param paymentPayload - The x402 payment payload from client\n * @param requirements - The payment requirements from server\n */\n verify(\n paymentPayload: X402PaymentPayload,\n requirements: X402PaymentRequirements\n ): Promise<VerifyResult>;\n \n /**\n * Settle a payment on-chain\n * \n * @param paymentPayload - The x402 payment payload from client\n * @param requirements - The payment requirements from server\n */\n settle(\n paymentPayload: X402PaymentPayload,\n requirements: X402PaymentRequirements\n ): Promise<SettleResult>;\n \n /**\n * Get current fee information (optional, for selection strategies)\n */\n getFee?(): Promise<FacilitatorFee>;\n \n /**\n * Check if this facilitator supports a given network\n */\n supportsNetwork(network: string): boolean;\n}\n\n/**\n * Base class with common functionality\n */\nexport abstract class BaseFacilitator implements Facilitator {\n abstract readonly name: string;\n abstract readonly displayName: string;\n abstract readonly supportedNetworks: string[];\n \n abstract healthCheck(): Promise<HealthCheckResult>;\n abstract verify(\n paymentPayload: X402PaymentPayload,\n requirements: X402PaymentRequirements\n ): Promise<VerifyResult>;\n abstract settle(\n paymentPayload: X402PaymentPayload,\n requirements: X402PaymentRequirements\n ): Promise<SettleResult>;\n \n supportsNetwork(network: string): boolean {\n return this.supportedNetworks.includes(network);\n }\n}\n","/**\n * CDP Facilitator\n * \n * Coinbase Developer Platform x402 facilitator implementation.\n * Auto-detects mainnet vs testnet from chain ID in request.\n * \n * Supported networks:\n * - Base mainnet (eip155:8453)\n * - Polygon mainnet (eip155:137)\n * - Base Sepolia testnet (eip155:84532)\n * \n * @see https://docs.cdp.coinbase.com/x402/core-concepts/facilitator\n */\n\nimport { readFileSync, existsSync } from 'fs';\nimport * as path from 'path';\nimport {\n BaseFacilitator,\n X402PaymentPayload,\n X402PaymentRequirements,\n VerifyResult,\n SettleResult,\n HealthCheckResult,\n FacilitatorFee,\n FacilitatorConfig,\n} from './interface.js';\n\n// x402 protocol version\nconst X402_VERSION = 2;\n\n// CDP Facilitator URL (handles both mainnet and testnet)\nconst CDP_URL = 'https://api.cdp.coinbase.com/platform/v2/x402';\n\n// Testnet chain IDs (for logging/info only - CDP auto-detects from network field)\nconst TESTNET_CHAIN_IDS = [84532]; // Base Sepolia\n\nexport interface CDPFacilitatorConfig extends FacilitatorConfig {\n /** CDP API Key ID (required) */\n apiKeyId?: string;\n /** CDP API Key Secret (required) */\n apiKeySecret?: string;\n}\n\n/**\n * Load environment from .env files\n */\nfunction loadEnvFile(): void {\n const envPaths = [\n path.join(process.cwd(), '.env'),\n path.join(process.env.HOME || '', '.moltspay', '.env'),\n ];\n \n for (const envPath of envPaths) {\n if (existsSync(envPath)) {\n try {\n const content = readFileSync(envPath, 'utf-8');\n for (const line of content.split('\\n')) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('#')) continue;\n const eqIndex = trimmed.indexOf('=');\n if (eqIndex === -1) continue;\n const key = trimmed.slice(0, eqIndex).trim();\n let value = trimmed.slice(eqIndex + 1).trim();\n if ((value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))) {\n value = value.slice(1, -1);\n }\n if (!process.env[key]) {\n process.env[key] = value;\n }\n }\n break;\n } catch {\n // Ignore errors\n }\n }\n }\n}\n\n/**\n * CDP (Coinbase Developer Platform) Facilitator\n * \n * Handles payment verification and settlement via Coinbase's x402 facilitator.\n */\nexport class CDPFacilitator extends BaseFacilitator {\n readonly name = 'cdp';\n readonly displayName = 'Coinbase CDP';\n readonly supportedNetworks: string[];\n \n private endpoint: string;\n private apiKeyId?: string;\n private apiKeySecret?: string;\n \n constructor(config: CDPFacilitatorConfig = {}) {\n super();\n \n // Load env files for credentials\n loadEnvFile();\n \n // Get credentials (required for CDP)\n this.apiKeyId = config.apiKeyId || process.env.CDP_API_KEY_ID;\n this.apiKeySecret = config.apiKeySecret || process.env.CDP_API_KEY_SECRET;\n \n // Single endpoint handles both mainnet and testnet (auto-detected from chain ID in request)\n this.endpoint = CDP_URL;\n \n // All supported networks - CDP handles both mainnet and testnet\n this.supportedNetworks = [\n 'eip155:8453', // Base mainnet\n 'eip155:137', // Polygon mainnet\n 'eip155:84532', // Base Sepolia (testnet)\n ];\n \n // Warn if missing credentials\n if (!this.apiKeyId || !this.apiKeySecret) {\n console.warn('[CDPFacilitator] WARNING: Missing CDP credentials!');\n console.warn('[CDPFacilitator] Set CDP_API_KEY_ID and CDP_API_KEY_SECRET in ~/.moltspay/.env');\n }\n }\n \n /**\n * Get auth headers for CDP API requests\n */\n private async getAuthHeaders(\n method: string,\n urlPath: string,\n body?: unknown\n ): Promise<Record<string, string>> {\n if (!this.apiKeyId || !this.apiKeySecret) {\n throw new Error('CDP credentials required. Set CDP_API_KEY_ID and CDP_API_KEY_SECRET');\n }\n \n try {\n const { getAuthHeaders } = await import('@coinbase/cdp-sdk/auth');\n \n return await getAuthHeaders({\n apiKeyId: this.apiKeyId,\n apiKeySecret: this.apiKeySecret,\n requestMethod: method,\n requestHost: 'api.cdp.coinbase.com',\n requestPath: urlPath,\n requestBody: body,\n });\n } catch (err: any) {\n throw new Error(`Failed to generate CDP auth: ${err.message}`);\n }\n }\n \n /**\n * Health check - verify facilitator is reachable\n */\n async healthCheck(): Promise<HealthCheckResult> {\n const start = Date.now();\n \n try {\n // For testnet, just check if x402.org responds\n // For mainnet, we could hit a health endpoint or just check DNS\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 5000);\n \n const response = await fetch(this.endpoint.replace('/x402', ''), {\n method: 'HEAD',\n signal: controller.signal,\n }).catch(() => null);\n \n clearTimeout(timeout);\n \n const latencyMs = Date.now() - start;\n \n return {\n healthy: response !== null,\n latencyMs,\n };\n } catch (err: any) {\n return {\n healthy: false,\n error: err.message,\n latencyMs: Date.now() - start,\n };\n }\n }\n \n /**\n * Verify payment signature with facilitator\n */\n async verify(\n paymentPayload: X402PaymentPayload,\n requirements: X402PaymentRequirements\n ): Promise<VerifyResult> {\n try {\n const requestBody = {\n x402Version: X402_VERSION,\n paymentPayload,\n paymentRequirements: requirements,\n };\n \n console.log('[CDP Verify] Payload:', JSON.stringify(paymentPayload, null, 2));\n \n const authHeaders = await this.getAuthHeaders(\n 'POST',\n '/platform/v2/x402/verify',\n requestBody\n );\n \n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...authHeaders,\n };\n \n const response = await fetch(`${this.endpoint}/verify`, {\n method: 'POST',\n headers,\n body: JSON.stringify(requestBody),\n });\n \n const result = await response.json() as any;\n console.log('[CDP Verify] Response:', response.status, JSON.stringify(result));\n \n if (!response.ok || !result.isValid) {\n return {\n valid: false,\n error: result.invalidReason || result.error || 'Verification failed',\n details: result,\n };\n }\n \n return { valid: true, details: result };\n } catch (err: any) {\n return {\n valid: false,\n error: `Facilitator error: ${err.message}`,\n };\n }\n }\n \n /**\n * Settle payment on-chain via facilitator\n */\n async settle(\n paymentPayload: X402PaymentPayload,\n requirements: X402PaymentRequirements\n ): Promise<SettleResult> {\n try {\n const requestBody = {\n x402Version: X402_VERSION,\n paymentPayload,\n paymentRequirements: requirements,\n };\n \n const authHeaders = await this.getAuthHeaders(\n 'POST',\n '/platform/v2/x402/settle',\n requestBody\n );\n \n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...authHeaders,\n };\n \n const response = await fetch(`${this.endpoint}/settle`, {\n method: 'POST',\n headers,\n body: JSON.stringify(requestBody),\n });\n \n const result = await response.json() as any;\n \n if (!response.ok || !result.success) {\n return {\n success: false,\n error: result.error || result.errorReason || 'Settlement failed',\n };\n }\n \n return {\n success: true,\n transaction: result.transaction,\n status: result.status || 'settled',\n };\n } catch (err: any) {\n return {\n success: false,\n error: `Settlement error: ${err.message}`,\n };\n }\n }\n \n /**\n * Get CDP fee information\n */\n async getFee(): Promise<FacilitatorFee> {\n // CDP pricing: 1000 free/month, then $0.001/tx\n return {\n perTx: 0.001,\n currency: 'USD',\n freeQuota: 1000,\n };\n }\n \n /**\n * Check if a chain ID is testnet\n */\n static isTestnet(chainId: number): boolean {\n return TESTNET_CHAIN_IDS.includes(chainId);\n }\n \n /**\n * Get configuration summary (for logging)\n */\n getConfigSummary(): string {\n const hasCredentials = !!(this.apiKeyId && this.apiKeySecret);\n const networks = this.supportedNetworks.join(', ');\n return `CDP Facilitator (networks: ${networks}, credentials: ${hasCredentials ? 'yes' : 'no'})`;\n }\n}\n","/**\n * Blockchain Configuration\n */\n\nimport type { ChainConfig, ChainName, EvmChainName, TokenSymbol } from '../types/index.js';\n\nexport const CHAINS: Record<EvmChainName, ChainConfig> = {\n // ============ Mainnet ============\n base: {\n name: 'Base',\n chainId: 8453,\n rpc: 'https://mainnet.base.org',\n tokens: {\n USDC: {\n address: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\n decimals: 6,\n symbol: 'USDC',\n eip712Name: 'USD Coin', // EIP-712 domain name\n },\n USDT: {\n address: '0xfde4C96c8593536E31F229EA8f37b2ADa2699bb2',\n decimals: 6,\n symbol: 'USDT',\n eip712Name: 'Tether USD',\n },\n },\n usdc: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', // deprecated, for backward compat\n explorer: 'https://basescan.org/address/',\n explorerTx: 'https://basescan.org/tx/',\n avgBlockTime: 2,\n },\n polygon: {\n name: 'Polygon',\n chainId: 137,\n rpc: 'https://polygon-bor-rpc.publicnode.com',\n tokens: {\n USDC: {\n address: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',\n decimals: 6,\n symbol: 'USDC',\n eip712Name: 'USD Coin',\n },\n USDT: {\n address: '0xc2132D05D31c914a87C6611C10748AEb04B58e8F',\n decimals: 6,\n symbol: 'USDT',\n eip712Name: '(PoS) Tether USD', // Polygon uses this name\n },\n },\n usdc: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',\n explorer: 'https://polygonscan.com/address/',\n explorerTx: 'https://polygonscan.com/tx/',\n avgBlockTime: 2,\n },\n // ============ Testnet ============\n base_sepolia: {\n name: 'Base Sepolia',\n chainId: 84532,\n rpc: 'https://sepolia.base.org',\n tokens: {\n USDC: {\n address: '0x036CbD53842c5426634e7929541eC2318f3dCF7e',\n decimals: 6,\n symbol: 'USDC',\n eip712Name: 'USDC', // Testnet USDC uses 'USDC' not 'USD Coin'\n },\n USDT: {\n address: '0x036CbD53842c5426634e7929541eC2318f3dCF7e', // Same as USDC on testnet (no official USDT)\n decimals: 6,\n symbol: 'USDT',\n eip712Name: 'USDC', // Uses same contract as USDC\n },\n },\n usdc: '0x036CbD53842c5426634e7929541eC2318f3dCF7e',\n explorer: 'https://sepolia.basescan.org/address/',\n explorerTx: 'https://sepolia.basescan.org/tx/',\n avgBlockTime: 2,\n },\n // ============ Tempo Testnet (Moderato) ============\n tempo_moderato: {\n name: 'Tempo Moderato',\n chainId: 42431,\n rpc: 'https://rpc.moderato.tempo.xyz',\n tokens: {\n // TIP-20 stablecoins on Tempo testnet (from mppx SDK)\n // Note: Tempo uses USD as native gas token, not ETH\n USDC: {\n address: '0x20c0000000000000000000000000000000000000', // pathUSD - primary testnet stablecoin\n decimals: 6,\n symbol: 'USDC',\n eip712Name: 'pathUSD',\n },\n USDT: {\n address: '0x20c0000000000000000000000000000000000001', // alphaUSD\n decimals: 6,\n symbol: 'USDT',\n eip712Name: 'alphaUSD',\n },\n },\n usdc: '0x20c0000000000000000000000000000000000000',\n explorer: 'https://explore.testnet.tempo.xyz/address/',\n explorerTx: 'https://explore.testnet.tempo.xyz/tx/',\n avgBlockTime: 0.5, // ~500ms finality\n },\n // ============ BNB Chain Testnet ============\n bnb_testnet: {\n name: 'BNB Testnet',\n chainId: 97,\n rpc: 'https://data-seed-prebsc-1-s1.binance.org:8545',\n tokens: {\n // Note: BNB uses 18 decimals for stablecoins (unlike Base/Polygon which use 6)\n // Using official Binance-Peg testnet tokens\n USDC: {\n address: '0x64544969ed7EBf5f083679233325356EbE738930', // Testnet USDC\n decimals: 18,\n symbol: 'USDC',\n eip712Name: 'USD Coin',\n },\n USDT: {\n address: '0x337610d27c682E347C9cD60BD4b3b107C9d34dDd', // Testnet USDT\n decimals: 18,\n symbol: 'USDT',\n eip712Name: 'Tether USD',\n },\n },\n usdc: '0x64544969ed7EBf5f083679233325356EbE738930',\n explorer: 'https://testnet.bscscan.com/address/',\n explorerTx: 'https://testnet.bscscan.com/tx/',\n avgBlockTime: 3,\n // BNB-specific: requires approval for pay-for-success flow\n requiresApproval: true,\n },\n // ============ BNB Chain Mainnet ============\n bnb: {\n name: 'BNB Smart Chain',\n chainId: 56,\n rpc: 'https://bsc-dataseed.binance.org',\n tokens: {\n // Note: BNB uses 18 decimals for stablecoins\n USDC: {\n address: '0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d',\n decimals: 18,\n symbol: 'USDC',\n eip712Name: 'USD Coin',\n },\n USDT: {\n address: '0x55d398326f99059fF775485246999027B3197955',\n decimals: 18,\n symbol: 'USDT',\n eip712Name: 'Tether USD',\n },\n },\n usdc: '0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d',\n explorer: 'https://bscscan.com/address/',\n explorerTx: 'https://bscscan.com/tx/',\n avgBlockTime: 3,\n // BNB-specific: requires approval for pay-for-success flow\n requiresApproval: true,\n },\n};\n\n/**\n * Get token address for a chain\n */\nexport function getTokenAddress(chainName: EvmChainName, token: TokenSymbol): string {\n const chain = CHAINS[chainName];\n if (!chain) {\n throw new Error(`Unsupported chain: ${chainName}`);\n }\n const tokenConfig = chain.tokens[token];\n if (!tokenConfig) {\n throw new Error(`Token ${token} not supported on ${chainName}`);\n }\n return tokenConfig.address;\n}\n\n/**\n * Get token config for a chain\n */\nexport function getTokenConfig(chainName: EvmChainName, token: TokenSymbol) {\n const chain = CHAINS[chainName];\n if (!chain) {\n throw new Error(`Unsupported chain: ${chainName}`);\n }\n return chain.tokens[token];\n}\n\n/**\n * Get chain configuration\n */\nexport function getChain(name: EvmChainName): ChainConfig {\n const config = CHAINS[name];\n if (!config) {\n throw new Error(`Unsupported chain: ${name}. Supported: ${Object.keys(CHAINS).join(', ')}`);\n }\n return config;\n}\n\n/**\n * List all supported EVM chains\n */\nexport function listChains(): EvmChainName[] {\n return Object.keys(CHAINS) as EvmChainName[];\n}\n\n/**\n * Get chain config by chainId\n */\nexport function getChainById(chainId: number): ChainConfig | undefined {\n return Object.values(CHAINS).find(c => c.chainId === chainId);\n}\n\n/**\n * ERC20 ABI (minimal, only required methods)\n */\nexport const ERC20_ABI = [\n 'function balanceOf(address owner) view returns (uint256)',\n 'function transfer(address to, uint256 amount) returns (bool)',\n 'function approve(address spender, uint256 amount) returns (bool)',\n 'function allowance(address owner, address spender) view returns (uint256)',\n 'function decimals() view returns (uint8)',\n 'function symbol() view returns (string)',\n 'function name() view returns (string)',\n 'function nonces(address owner) view returns (uint256)',\n 'function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s)',\n 'event Transfer(address indexed from, address indexed to, uint256 value)',\n 'event Approval(address indexed owner, address indexed spender, uint256 value)',\n];\n\nexport type { ChainConfig, ChainName, EvmChainName, TokenSymbol };\n","/**\n * Tempo Testnet Facilitator\n * \n * Verifies payments on Tempo Moderato testnet by checking transaction receipts.\n * Unlike CDP facilitator, this directly verifies on-chain without a third-party service.\n */\n\nimport {\n BaseFacilitator,\n X402PaymentPayload,\n X402PaymentRequirements,\n VerifyResult,\n SettleResult,\n HealthCheckResult,\n} from './interface.js';\nimport { CHAINS } from '../chains/index.js';\n\n// TIP-20 Transfer event signature\nconst TRANSFER_EVENT_TOPIC = '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef';\n\ninterface TempoPaymentPayload {\n txHash: string;\n chainId: number;\n}\n\n/**\n * Tempo Testnet Facilitator\n * \n * Verifies TIP-20 token transfers on Tempo Moderato (chainId 42431).\n */\nexport class TempoFacilitator extends BaseFacilitator {\n readonly name = 'tempo';\n readonly displayName = 'Tempo Testnet';\n readonly supportedNetworks = ['eip155:42431']; // Tempo Moderato\n\n private rpcUrl: string;\n\n constructor() {\n super();\n this.rpcUrl = CHAINS.tempo_moderato.rpc;\n }\n\n async healthCheck(): Promise<HealthCheckResult> {\n const start = Date.now();\n try {\n const response = await fetch(this.rpcUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n jsonrpc: '2.0',\n method: 'eth_chainId',\n params: [],\n id: 1,\n }),\n });\n \n const data = await response.json() as { result: string };\n const chainId = parseInt(data.result, 16);\n \n if (chainId !== 42431) {\n return { healthy: false, error: `Wrong chainId: ${chainId}` };\n }\n \n return { healthy: true, latencyMs: Date.now() - start };\n } catch (error) {\n return { healthy: false, error: String(error) };\n }\n }\n\n async verify(\n paymentPayload: X402PaymentPayload,\n requirements: X402PaymentRequirements\n ): Promise<VerifyResult> {\n try {\n // Extract Tempo-specific payload\n const tempoPayload = paymentPayload.payload as TempoPaymentPayload;\n \n if (!tempoPayload?.txHash) {\n return { valid: false, error: 'Missing txHash in payment payload' };\n }\n\n // Get transaction receipt\n const receipt = await this.getTransactionReceipt(tempoPayload.txHash);\n \n if (!receipt) {\n return { valid: false, error: 'Transaction not found' };\n }\n\n if (receipt.status !== '0x1') {\n return { valid: false, error: 'Transaction failed' };\n }\n\n // Find Transfer event\n const transferLog = receipt.logs.find((log: any) => \n log.topics[0] === TRANSFER_EVENT_TOPIC\n );\n\n if (!transferLog) {\n return { valid: false, error: 'No Transfer event found' };\n }\n\n // Verify recipient (topic[2] is 'to' address, padded to 32 bytes)\n const toAddress = '0x' + transferLog.topics[2].slice(26).toLowerCase();\n const expectedTo = requirements.payTo.toLowerCase();\n \n if (toAddress !== expectedTo) {\n return { \n valid: false, \n error: `Wrong recipient: ${toAddress}, expected ${expectedTo}` \n };\n }\n\n // Verify amount (data field contains the amount)\n const amount = BigInt(transferLog.data);\n const expectedAmount = BigInt(requirements.amount);\n \n if (amount < expectedAmount) {\n return { \n valid: false, \n error: `Insufficient amount: ${amount}, expected ${expectedAmount}` \n };\n }\n\n // Verify token address\n const tokenAddress = transferLog.address.toLowerCase();\n const expectedToken = requirements.asset.toLowerCase();\n \n if (tokenAddress !== expectedToken) {\n return { \n valid: false, \n error: `Wrong token: ${tokenAddress}, expected ${expectedToken}` \n };\n }\n\n return { \n valid: true, \n details: {\n txHash: tempoPayload.txHash,\n from: '0x' + transferLog.topics[1].slice(26),\n to: toAddress,\n amount: amount.toString(),\n token: tokenAddress,\n }\n };\n } catch (error) {\n return { valid: false, error: `Verification failed: ${error}` };\n }\n }\n\n async settle(\n paymentPayload: X402PaymentPayload,\n requirements: X402PaymentRequirements\n ): Promise<SettleResult> {\n // For Tempo, the client already executed the transaction\n // We just verify and report success\n const verifyResult = await this.verify(paymentPayload, requirements);\n \n if (!verifyResult.valid) {\n return { success: false, error: verifyResult.error };\n }\n\n const tempoPayload = paymentPayload.payload as TempoPaymentPayload;\n \n return { \n success: true, \n transaction: tempoPayload.txHash,\n status: 'settled'\n };\n }\n\n private async getTransactionReceipt(txHash: string): Promise<any> {\n const response = await fetch(this.rpcUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n jsonrpc: '2.0',\n method: 'eth_getTransactionReceipt',\n params: [txHash],\n id: 1,\n }),\n });\n\n const data = await response.json() as { result: any };\n return data.result;\n }\n}\n","/**\n * BNB Chain Facilitator\n * \n * Handles pay-for-success payments on BNB Smart Chain.\n * \n * Flow:\n * 1. Client pre-approves server wallet (one-time, via `moltspay init`)\n * 2. Client signs EIP-712 intent (no gas, just signature)\n * 3. Server verifies intent signature\n * 4. Server executes service\n * 5. Success → Server calls transferFrom (server pays gas)\n * 6. Failure → No transfer, client keeps money\n * \n * Key difference from Tempo:\n * - Tempo: Client pays first → service might fail → money lost\n * - BNB: Service runs first → success = payment (pay-for-success)\n */\n\nimport {\n BaseFacilitator,\n X402PaymentPayload,\n X402PaymentRequirements,\n VerifyResult,\n SettleResult,\n HealthCheckResult,\n} from './interface.js';\nimport { CHAINS, ChainConfig } from '../chains/index.js';\nimport { privateKeyToAccount } from 'viem/accounts';\n\n// ERC20 Transfer event signature\nconst TRANSFER_EVENT_TOPIC = '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef';\n\n// EIP-712 Domain\nconst EIP712_DOMAIN = {\n name: 'MoltsPay',\n version: '1',\n};\n\n// EIP-712 Types for Payment Intent\nconst INTENT_TYPES = {\n PaymentIntent: [\n { name: 'from', type: 'address' },\n { name: 'to', type: 'address' },\n { name: 'amount', type: 'uint256' },\n { name: 'token', type: 'address' },\n { name: 'service', type: 'string' },\n { name: 'nonce', type: 'uint256' },\n { name: 'deadline', type: 'uint256' },\n ],\n};\n\n// ERC20 ABI (minimal)\nconst ERC20_ABI = {\n transfer: 'function transfer(address to, uint256 amount) returns (bool)',\n transferFrom: 'function transferFrom(address from, address to, uint256 amount) returns (bool)',\n allowance: 'function allowance(address owner, address spender) view returns (uint256)',\n balanceOf: 'function balanceOf(address account) view returns (uint256)',\n approve: 'function approve(address spender, uint256 amount) returns (bool)',\n};\n\n/**\n * BNB Payment Intent (signed by client)\n */\nexport interface BNBPaymentIntent {\n from: string;\n to: string;\n amount: string;\n token: string;\n service: string;\n nonce: number;\n deadline: number;\n signature: string;\n}\n\n/**\n * BNB Payment Payload (from client in x402 request)\n */\ninterface BNBPaymentPayload {\n intent: BNBPaymentIntent;\n chainId: number;\n}\n\n/**\n * BNB Chain Facilitator\n * \n * Handles pay-for-success payments on BNB mainnet (chainId 56) and testnet (chainId 97).\n * Server wallet executes transferFrom after successful service delivery.\n */\nexport class BNBFacilitator extends BaseFacilitator {\n readonly name = 'bnb';\n readonly displayName = 'BNB Smart Chain';\n readonly supportedNetworks = ['eip155:56', 'eip155:97']; // Mainnet + Testnet\n\n private serverPrivateKey: string;\n private spenderAddress: string | null = null;\n private chainConfigs: { [key: number]: { rpc: string; chain: ChainConfig } };\n\n constructor(serverPrivateKey?: string) {\n super();\n this.serverPrivateKey = serverPrivateKey || process.env.BNB_SERVER_PRIVATE_KEY || '';\n \n // Pre-compute spender address synchronously using viem\n if (this.serverPrivateKey) {\n const key = this.serverPrivateKey.startsWith('0x') \n ? this.serverPrivateKey as `0x${string}`\n : `0x${this.serverPrivateKey}` as `0x${string}`;\n const account = privateKeyToAccount(key);\n this.spenderAddress = account.address;\n }\n \n this.chainConfigs = {\n 56: { rpc: CHAINS.bnb.rpc, chain: CHAINS.bnb },\n 97: { rpc: CHAINS.bnb_testnet.rpc, chain: CHAINS.bnb_testnet },\n };\n }\n\n async healthCheck(): Promise<HealthCheckResult> {\n const start = Date.now();\n try {\n // Check mainnet\n const response = await fetch(this.chainConfigs[56].rpc, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n jsonrpc: '2.0',\n method: 'eth_chainId',\n params: [],\n id: 1,\n }),\n });\n \n const data = await response.json() as { result: string };\n const chainId = parseInt(data.result, 16);\n \n if (chainId !== 56) {\n return { healthy: false, error: `Wrong chainId: ${chainId}` };\n }\n \n return { healthy: true, latencyMs: Date.now() - start };\n } catch (error) {\n return { healthy: false, error: String(error) };\n }\n }\n\n /**\n * Verify a payment intent signature (before service execution)\n * \n * This verifies:\n * 1. Signature is valid for the intent\n * 2. Client has approved server wallet\n * 3. Client has sufficient balance\n * 4. Intent hasn't expired\n */\n async verify(\n paymentPayload: X402PaymentPayload,\n requirements: X402PaymentRequirements\n ): Promise<VerifyResult> {\n try {\n const bnbPayload = paymentPayload.payload as BNBPaymentPayload;\n \n if (!bnbPayload?.intent) {\n return { valid: false, error: 'Missing intent in payment payload' };\n }\n\n const { intent, chainId } = bnbPayload;\n const config = this.chainConfigs[chainId];\n \n if (!config) {\n return { valid: false, error: `Unsupported chainId: ${chainId}` };\n }\n\n // Check deadline\n if (intent.deadline < Date.now()) {\n return { valid: false, error: 'Intent expired' };\n }\n\n // Verify signature\n const recoveredAddress = await this.recoverIntentSigner(intent, chainId);\n if (recoveredAddress.toLowerCase() !== intent.from.toLowerCase()) {\n return { valid: false, error: 'Invalid signature' };\n }\n\n // Verify recipient matches\n if (intent.to.toLowerCase() !== requirements.payTo.toLowerCase()) {\n return { valid: false, error: `Wrong recipient: ${intent.to}` };\n }\n\n // Verify amount matches\n if (BigInt(intent.amount) < BigInt(requirements.amount)) {\n return { valid: false, error: `Insufficient amount: ${intent.amount}` };\n }\n\n // Verify token matches\n if (intent.token.toLowerCase() !== requirements.asset.toLowerCase()) {\n return { valid: false, error: `Wrong token: ${intent.token}` };\n }\n\n // Check allowance\n const serverAddress = await this.getServerAddress();\n const allowance = await this.getAllowance(intent.from, serverAddress, intent.token, config.rpc);\n \n if (BigInt(allowance) < BigInt(intent.amount)) {\n return { valid: false, error: 'Insufficient allowance. Run: npx moltspay init --chain bnb' };\n }\n\n // Check balance\n const balance = await this.getBalance(intent.from, intent.token, config.rpc);\n if (BigInt(balance) < BigInt(intent.amount)) {\n return { valid: false, error: 'Insufficient balance' };\n }\n\n return { \n valid: true, \n details: {\n from: intent.from,\n to: intent.to,\n amount: intent.amount,\n token: intent.token,\n service: intent.service,\n nonce: intent.nonce,\n deadline: intent.deadline,\n }\n };\n } catch (error) {\n return { valid: false, error: `Verification failed: ${error}` };\n }\n }\n\n /**\n * Settle a payment by executing transferFrom\n * \n * This is called AFTER the service has been successfully delivered.\n * Server pays gas, transfers tokens from client to provider.\n */\n async settle(\n paymentPayload: X402PaymentPayload,\n requirements: X402PaymentRequirements\n ): Promise<SettleResult> {\n if (!this.serverPrivateKey) {\n return { success: false, error: 'Server wallet not configured (BNB_SERVER_PRIVATE_KEY)' };\n }\n\n try {\n // First verify the intent\n const verifyResult = await this.verify(paymentPayload, requirements);\n if (!verifyResult.valid) {\n return { success: false, error: verifyResult.error };\n }\n\n const bnbPayload = paymentPayload.payload as BNBPaymentPayload;\n const { intent, chainId } = bnbPayload;\n const config = this.chainConfigs[chainId];\n\n // Execute transferFrom\n const txHash = await this.executeTransferFrom(\n intent.from,\n intent.to,\n intent.amount,\n intent.token,\n config.rpc\n );\n\n return { \n success: true, \n transaction: txHash,\n status: 'settled'\n };\n } catch (error) {\n return { success: false, error: `Settlement failed: ${error}` };\n }\n }\n\n /**\n * Check if client has approved the server wallet\n */\n async checkApproval(\n clientAddress: string, \n token: string, \n chainId: number\n ): Promise<{ approved: boolean; allowance: string }> {\n const config = this.chainConfigs[chainId];\n if (!config) {\n throw new Error(`Unsupported chainId: ${chainId}`);\n }\n\n const serverAddress = await this.getServerAddress();\n const allowance = await this.getAllowance(clientAddress, serverAddress, token, config.rpc);\n \n // Consider approved if allowance > 1000 USDC (with 18 decimals)\n const minAllowance = BigInt('1000000000000000000000'); // 1000 tokens\n \n return {\n approved: BigInt(allowance) >= minAllowance,\n allowance,\n };\n }\n\n /**\n * Verify a completed transaction (for checking past payments)\n */\n async verifyTransaction(\n txHash: string, \n expected: { to: string; amount: string; token: string },\n chainId: number\n ): Promise<VerifyResult> {\n const config = this.chainConfigs[chainId];\n if (!config) {\n return { valid: false, error: `Unsupported chainId: ${chainId}` };\n }\n\n try {\n const receipt = await this.getTransactionReceipt(txHash, config.rpc);\n \n if (!receipt) {\n return { valid: false, error: 'Transaction not found' };\n }\n\n if (receipt.status !== '0x1') {\n return { valid: false, error: 'Transaction failed' };\n }\n\n // Find Transfer event\n const transferLog = receipt.logs.find((log: any) => \n log.topics[0] === TRANSFER_EVENT_TOPIC &&\n log.address.toLowerCase() === expected.token.toLowerCase()\n );\n\n if (!transferLog) {\n return { valid: false, error: 'No Transfer event found' };\n }\n\n // Verify recipient\n const toAddress = '0x' + transferLog.topics[2].slice(26).toLowerCase();\n if (toAddress !== expected.to.toLowerCase()) {\n return { valid: false, error: `Wrong recipient: ${toAddress}` };\n }\n\n // Verify amount\n const amount = BigInt(transferLog.data);\n if (amount < BigInt(expected.amount)) {\n return { valid: false, error: `Insufficient amount: ${amount}` };\n }\n\n return { \n valid: true, \n details: {\n txHash,\n from: '0x' + transferLog.topics[1].slice(26),\n to: toAddress,\n amount: amount.toString(),\n token: transferLog.address,\n }\n };\n } catch (error) {\n return { valid: false, error: `Verification failed: ${error}` };\n }\n }\n\n // ==================== Private Methods ====================\n\n /**\n * Get the server's spender address (public, for 402 responses)\n * Returns cached value computed at construction time.\n */\n getSpenderAddress(): string | null {\n return this.spenderAddress;\n }\n\n private async getServerAddress(): Promise<string> {\n // Derive address from private key using ethers\n const { ethers } = await import('ethers');\n const wallet = new ethers.Wallet(this.serverPrivateKey);\n return wallet.address;\n }\n\n private async recoverIntentSigner(intent: BNBPaymentIntent, chainId: number): Promise<string> {\n // Use ethers for EIP-712 signature recovery\n const { ethers } = await import('ethers');\n \n const domain = {\n ...EIP712_DOMAIN,\n chainId,\n };\n\n const message = {\n from: intent.from,\n to: intent.to,\n amount: intent.amount,\n token: intent.token,\n service: intent.service,\n nonce: intent.nonce,\n deadline: intent.deadline,\n };\n\n const recoveredAddress = ethers.verifyTypedData(\n domain,\n INTENT_TYPES,\n message,\n intent.signature\n );\n\n return recoveredAddress;\n }\n\n private async getAllowance(owner: string, spender: string, token: string, rpcUrl: string): Promise<string> {\n // allowance(address,address) selector + params\n const selector = '0xdd62ed3e';\n const ownerPadded = owner.toLowerCase().replace('0x', '').padStart(64, '0');\n const spenderPadded = spender.toLowerCase().replace('0x', '').padStart(64, '0');\n const data = selector + ownerPadded + spenderPadded;\n\n const response = await fetch(rpcUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n jsonrpc: '2.0',\n method: 'eth_call',\n params: [{ to: token, data }, 'latest'],\n id: 1,\n }),\n });\n\n const result = await response.json() as { result: string };\n return result.result || '0x0';\n }\n\n private async getBalance(account: string, token: string, rpcUrl: string): Promise<string> {\n // balanceOf(address) selector + param\n const selector = '0x70a08231';\n const accountPadded = account.toLowerCase().replace('0x', '').padStart(64, '0');\n const data = selector + accountPadded;\n\n const response = await fetch(rpcUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n jsonrpc: '2.0',\n method: 'eth_call',\n params: [{ to: token, data }, 'latest'],\n id: 1,\n }),\n });\n\n const result = await response.json() as { result: string };\n return result.result || '0x0';\n }\n\n private async executeTransferFrom(\n from: string,\n to: string,\n amount: string,\n token: string,\n rpcUrl: string\n ): Promise<string> {\n const { ethers } = await import('ethers');\n \n const provider = new ethers.JsonRpcProvider(rpcUrl);\n const wallet = new ethers.Wallet(this.serverPrivateKey, provider);\n \n const tokenContract = new ethers.Contract(token, [\n 'function transferFrom(address from, address to, uint256 amount) returns (bool)',\n ], wallet);\n\n const tx = await tokenContract.transferFrom(from, to, amount);\n const receipt = await tx.wait();\n \n return receipt.hash;\n }\n\n private async getTransactionReceipt(txHash: string, rpcUrl: string): Promise<any> {\n const response = await fetch(rpcUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n jsonrpc: '2.0',\n method: 'eth_getTransactionReceipt',\n params: [txHash],\n id: 1,\n }),\n });\n\n const data = await response.json() as { result: any };\n return data.result;\n }\n}\n\n/**\n * Create EIP-712 typed data for signing a payment intent\n * \n * Used by clients to sign their payment intent.\n */\nexport function createIntentTypedData(\n intent: Omit<BNBPaymentIntent, 'signature'>,\n chainId: number\n) {\n return {\n domain: {\n ...EIP712_DOMAIN,\n chainId,\n },\n types: INTENT_TYPES,\n primaryType: 'PaymentIntent' as const,\n message: {\n from: intent.from,\n to: intent.to,\n amount: intent.amount,\n token: intent.token,\n service: intent.service,\n nonce: intent.nonce,\n deadline: intent.deadline,\n },\n };\n}\n","/**\n * Solana Facilitator\n * \n * Pay-for-success payment settlement for Solana SPL token transfers.\n * Unlike EVM chains, Solana doesn't have a third-party facilitator - \n * we verify and settle directly on-chain.\n * \n * Flow:\n * 1. Client signs a SPL token transfer authorization\n * 2. Server receives the signed transaction\n * 3. Server verifies the signature and amount\n * 4. Server submits the transaction to settle payment\n */\n\nimport { \n Connection, \n PublicKey, \n Transaction,\n VersionedTransaction,\n sendAndConfirmTransaction,\n Keypair,\n} from '@solana/web3.js';\nimport {\n getAssociatedTokenAddress,\n createTransferCheckedInstruction,\n getAccount,\n createAssociatedTokenAccountInstruction,\n TOKEN_PROGRAM_ID,\n} from '@solana/spl-token';\nimport { \n BaseFacilitator, \n type X402PaymentPayload, \n type X402PaymentRequirements,\n type VerifyResult,\n type SettleResult,\n type HealthCheckResult,\n} from './interface.js';\nimport { SOLANA_CHAINS, type SolanaChainName } from '../chains/solana.js';\n\n/**\n * Solana payment payload structure\n */\nexport interface SolanaPaymentPayload {\n /** Base58 encoded signed transaction */\n signedTransaction: string;\n /** Sender's public key (Base58) */\n sender: string;\n /** Chain: solana or solana_devnet */\n chain: SolanaChainName;\n}\n\n/**\n * Solana Facilitator configuration\n */\nexport interface SolanaFacilitatorConfig {\n /** Optional fee payer keypair for gasless transactions */\n feePayerKeypair?: Keypair;\n}\n\n/**\n * Solana Facilitator for pay-for-success payments\n * \n * Supports gasless mode: if feePayerKeypair is provided, server pays tx fees\n */\nexport class SolanaFacilitator extends BaseFacilitator {\n readonly name = 'solana';\n readonly displayName = 'Solana Direct';\n readonly supportedNetworks = ['solana:mainnet', 'solana:devnet'];\n\n private connections: Map<SolanaChainName, Connection> = new Map();\n private feePayerKeypair?: Keypair;\n\n constructor(config?: SolanaFacilitatorConfig) {\n super();\n this.feePayerKeypair = config?.feePayerKeypair;\n \n // Initialize connections\n for (const [chain, config] of Object.entries(SOLANA_CHAINS)) {\n this.connections.set(\n chain as SolanaChainName, \n new Connection(config.rpc, 'confirmed')\n );\n }\n \n if (this.feePayerKeypair) {\n console.log(`[SolanaFacilitator] Gasless mode enabled. Fee payer: ${this.feePayerKeypair.publicKey.toBase58()}`);\n }\n }\n \n /**\n * Get fee payer public key (for gasless transactions)\n */\n getFeePayerPubkey(): string | null {\n return this.feePayerKeypair?.publicKey.toBase58() || null;\n }\n\n private getConnection(chain: SolanaChainName): Connection {\n const conn = this.connections.get(chain);\n if (!conn) {\n throw new Error(`No connection for chain: ${chain}`);\n }\n return conn;\n }\n\n /**\n * Convert our chain name to network identifier\n */\n static chainToNetwork(chain: SolanaChainName): string {\n return chain === 'solana' ? 'solana:mainnet' : 'solana:devnet';\n }\n\n /**\n * Convert network identifier to chain name\n */\n static networkToChain(network: string): SolanaChainName | null {\n if (network === 'solana:mainnet') return 'solana';\n if (network === 'solana:devnet') return 'solana_devnet';\n return null;\n }\n\n async healthCheck(): Promise<HealthCheckResult> {\n const start = Date.now();\n try {\n // Check devnet connection\n const conn = this.getConnection('solana_devnet');\n await conn.getSlot();\n return {\n healthy: true,\n latencyMs: Date.now() - start,\n };\n } catch (error: any) {\n return {\n healthy: false,\n error: error.message,\n };\n }\n }\n\n /**\n * Verify a Solana payment\n * \n * Checks:\n * 1. Transaction is valid and properly signed\n * 2. Transfer instruction matches expected amount and recipient\n */\n async verify(\n paymentPayload: X402PaymentPayload,\n requirements: X402PaymentRequirements\n ): Promise<VerifyResult> {\n try {\n const solanaPayload = paymentPayload.payload as SolanaPaymentPayload;\n if (!solanaPayload || !solanaPayload.signedTransaction) {\n return { valid: false, error: 'Missing signed transaction' };\n }\n\n const chain = solanaPayload.chain || 'solana_devnet';\n const chainConfig = SOLANA_CHAINS[chain];\n if (!chainConfig) {\n return { valid: false, error: `Invalid chain: ${chain}` };\n }\n\n // Decode the transaction\n const txBuffer = Buffer.from(solanaPayload.signedTransaction, 'base64');\n let tx: Transaction | VersionedTransaction;\n \n try {\n // Try legacy transaction first\n tx = Transaction.from(txBuffer);\n } catch {\n // Try versioned transaction\n tx = VersionedTransaction.deserialize(txBuffer);\n }\n\n // Verify at least one signature exists (may be partial in gasless mode)\n if (tx instanceof Transaction) {\n // In gasless mode, fee payer signature is added by server\n // Client only signs for token transfer authority\n const hasAnySignature = tx.signatures.some(sig => \n sig.signature && !sig.signature.every(b => b === 0)\n );\n if (!hasAnySignature) {\n return { valid: false, error: 'Transaction not signed' };\n }\n }\n\n // Parse expected values from requirements\n const expectedAmount = BigInt(requirements.amount);\n const expectedRecipient = new PublicKey(requirements.payTo);\n\n // For now, we trust the transaction structure\n // Full verification happens at settlement time\n return {\n valid: true,\n details: {\n chain,\n sender: solanaPayload.sender,\n recipient: requirements.payTo,\n amount: requirements.amount,\n },\n };\n } catch (error: any) {\n return { valid: false, error: error.message };\n }\n }\n\n /**\n * Settle a Solana payment\n * \n * Submits the signed transaction to the network.\n * In gasless mode, adds fee payer signature before submitting.\n */\n async settle(\n paymentPayload: X402PaymentPayload,\n requirements: X402PaymentRequirements\n ): Promise<SettleResult> {\n try {\n const solanaPayload = paymentPayload.payload as SolanaPaymentPayload;\n if (!solanaPayload || !solanaPayload.signedTransaction) {\n return { success: false, error: 'Missing signed transaction' };\n }\n\n const chain = solanaPayload.chain || 'solana_devnet';\n const connection = this.getConnection(chain);\n\n // Decode the transaction\n const txBuffer = Buffer.from(solanaPayload.signedTransaction, 'base64');\n \n let txToSend: Buffer;\n \n try {\n // Try legacy transaction\n const tx = Transaction.from(txBuffer);\n \n // Check if we need to add fee payer signature (gasless mode)\n if (this.feePayerKeypair && tx.feePayer) {\n const feePayerPubkey = this.feePayerKeypair.publicKey.toBase58();\n const txFeePayer = tx.feePayer.toBase58();\n \n if (txFeePayer === feePayerPubkey) {\n // Gasless mode: add fee payer signature\n console.log(`[SolanaFacilitator] Gasless mode: adding fee payer signature`);\n tx.partialSign(this.feePayerKeypair);\n }\n }\n \n txToSend = tx.serialize();\n } catch (e: any) {\n // Fall back to versioned transaction (no gasless support for versioned yet)\n txToSend = txBuffer;\n }\n\n // Send the transaction\n const signature = await connection.sendRawTransaction(txToSend, {\n skipPreflight: false,\n preflightCommitment: 'confirmed',\n });\n\n // Wait for confirmation\n const confirmation = await connection.confirmTransaction(signature, 'confirmed');\n \n if (confirmation.value.err) {\n return {\n success: false,\n error: `Transaction failed: ${JSON.stringify(confirmation.value.err)}`,\n transaction: signature,\n };\n }\n\n return {\n success: true,\n transaction: signature,\n status: 'confirmed',\n };\n } catch (error: any) {\n return { success: false, error: error.message };\n }\n }\n\n supportsNetwork(network: string): boolean {\n return this.supportedNetworks.includes(network);\n }\n}\n\n/**\n * Create a Solana payment transaction for signing\n * \n * This is called by the client to create the transaction to sign.\n * \n * @param senderPubkey - The sender's public key (token owner)\n * @param recipientPubkey - The recipient's public key\n * @param amount - Amount in token base units\n * @param chain - Solana chain (solana or solana_devnet)\n * @param feePayerPubkey - Optional fee payer public key for gasless transactions\n */\nexport async function createSolanaPaymentTransaction(\n senderPubkey: PublicKey,\n recipientPubkey: PublicKey,\n amount: bigint,\n chain: SolanaChainName,\n feePayerPubkey?: PublicKey,\n): Promise<Transaction> {\n const chainConfig = SOLANA_CHAINS[chain];\n const connection = new Connection(chainConfig.rpc, 'confirmed');\n const mint = new PublicKey(chainConfig.tokens.USDC.mint);\n\n // Determine who pays fees (gasless mode uses server's fee payer)\n const actualFeePayer = feePayerPubkey || senderPubkey;\n\n // Get ATAs\n const senderATA = await getAssociatedTokenAddress(mint, senderPubkey);\n const recipientATA = await getAssociatedTokenAddress(mint, recipientPubkey);\n\n const transaction = new Transaction();\n\n // Check if recipient ATA exists\n try {\n await getAccount(connection, recipientATA);\n } catch {\n // Create ATA for recipient (fee payer pays rent in gasless mode)\n transaction.add(\n createAssociatedTokenAccountInstruction(\n actualFeePayer, // payer (fee payer in gasless mode)\n recipientATA, // ata to create\n recipientPubkey, // owner\n mint // mint\n )\n );\n }\n\n // Add transfer instruction\n transaction.add(\n createTransferCheckedInstruction(\n senderATA, // source\n mint, // mint\n recipientATA, // destination\n senderPubkey, // owner (sender still authorizes the transfer)\n amount, // amount\n chainConfig.tokens.USDC.decimals // decimals\n )\n );\n\n // Get recent blockhash\n const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash();\n transaction.recentBlockhash = blockhash;\n transaction.feePayer = actualFeePayer;\n\n return transaction;\n}\n\nexport default SolanaFacilitator;\n","/**\n * Solana Chain Configuration\n * \n * Solana is NOT an EVM chain - uses different:\n * - Key format: ed25519 (EdDSA) vs secp256k1 (ECDSA)\n * - Address format: Base58 vs 0x hex\n * - Token standard: SPL vs ERC-20\n */\n\nimport { Connection, PublicKey } from '@solana/web3.js';\n\nexport interface SolanaChainConfig {\n name: string;\n cluster: 'mainnet-beta' | 'devnet' | 'testnet';\n rpc: string;\n explorer: string;\n explorerTx: string;\n tokens: {\n USDC: {\n mint: string;\n decimals: number;\n };\n };\n}\n\nexport type SolanaChainName = 'solana' | 'solana_devnet';\n\nexport const SOLANA_CHAINS: Record<SolanaChainName, SolanaChainConfig> = {\n solana: {\n name: 'Solana Mainnet',\n cluster: 'mainnet-beta',\n rpc: 'https://api.mainnet-beta.solana.com',\n explorer: 'https://solscan.io/account/',\n explorerTx: 'https://solscan.io/tx/',\n tokens: {\n USDC: {\n mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', // Circle official USDC\n decimals: 6,\n },\n },\n },\n solana_devnet: {\n name: 'Solana Devnet',\n cluster: 'devnet',\n rpc: 'https://api.devnet.solana.com',\n explorer: 'https://solscan.io/account/',\n explorerTx: 'https://solscan.io/tx/',\n tokens: {\n USDC: {\n // Circle's devnet USDC (if not available, we'll deploy our own test token)\n mint: '4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU',\n decimals: 6,\n },\n },\n },\n};\n\n/**\n * Get Solana RPC connection\n */\nexport function getSolanaConnection(chain: SolanaChainName): Connection {\n const config = SOLANA_CHAINS[chain];\n return new Connection(config.rpc, 'confirmed');\n}\n\n/**\n * Get USDC mint public key for a Solana chain\n */\nexport function getUSDCMint(chain: SolanaChainName): PublicKey {\n return new PublicKey(SOLANA_CHAINS[chain].tokens.USDC.mint);\n}\n\n/**\n * Get Solana chain config\n */\nexport function getSolanaChain(name: SolanaChainName): SolanaChainConfig {\n const config = SOLANA_CHAINS[name];\n if (!config) {\n throw new Error(`Unsupported Solana chain: ${name}. Supported: ${Object.keys(SOLANA_CHAINS).join(', ')}`);\n }\n return config;\n}\n\n/**\n * Check if a chain name is a Solana chain\n */\nexport function isSolanaChain(chain: string): chain is SolanaChainName {\n return chain === 'solana' || chain === 'solana_devnet';\n}\n\n/**\n * Get explorer URL for a Solana address\n */\nexport function getSolanaExplorerUrl(chain: SolanaChainName, address: string): string {\n const config = SOLANA_CHAINS[chain];\n const clusterParam = chain === 'solana_devnet' ? '?cluster=devnet' : '';\n return `${config.explorer}${address}${clusterParam}`;\n}\n\n/**\n * Get explorer URL for a Solana transaction\n */\nexport function getSolanaTxExplorerUrl(chain: SolanaChainName, signature: string): string {\n const config = SOLANA_CHAINS[chain];\n const clusterParam = chain === 'solana_devnet' ? '?cluster=devnet' : '';\n return `${config.explorerTx}${signature}${clusterParam}`;\n}\n","/**\n * Facilitator Registry\n * \n * Central registry for all available facilitators.\n * Supports selection strategies for failover, load balancing, etc.\n */\n\nimport {\n Facilitator,\n FacilitatorConfig,\n X402PaymentPayload,\n X402PaymentRequirements,\n VerifyResult,\n SettleResult,\n HealthCheckResult,\n} from './interface.js';\nimport { CDPFacilitator, CDPFacilitatorConfig } from './cdp.js';\nimport { TempoFacilitator } from './tempo.js';\nimport { BNBFacilitator } from './bnb.js';\nimport { SolanaFacilitator, SolanaFacilitatorConfig } from './solana.js';\nimport { Keypair } from '@solana/web3.js';\nimport bs58 from 'bs58';\n\n/**\n * Selection strategy for choosing facilitators\n */\nexport type SelectionStrategy = \n | 'failover' // Use primary, switch to fallback on failure\n | 'cheapest' // Use facilitator with lowest fees\n | 'fastest' // Use first responder\n | 'random' // Random selection (load balancing)\n | 'roundrobin'; // Rotate through facilitators\n\n/**\n * Facilitator selection configuration\n */\nexport interface FacilitatorSelection {\n /** Primary facilitator to use */\n primary: string;\n /** Fallback facilitators (in order of preference) */\n fallback?: string[];\n /** Selection strategy */\n strategy?: SelectionStrategy;\n /** Per-facilitator config overrides */\n config?: Record<string, FacilitatorConfig>;\n}\n\n/**\n * Factory function type for creating facilitators\n */\ntype FacilitatorFactory = (config?: FacilitatorConfig) => Facilitator;\n\n/**\n * Facilitator Registry\n * \n * Manages available facilitators and provides selection logic.\n */\nexport class FacilitatorRegistry {\n private factories: Map<string, FacilitatorFactory> = new Map();\n private instances: Map<string, Facilitator> = new Map();\n private selection: FacilitatorSelection;\n private roundRobinIndex = 0;\n \n constructor(selection?: FacilitatorSelection) {\n // Register built-in facilitators\n this.registerFactory('cdp', (config) => new CDPFacilitator(config as CDPFacilitatorConfig));\n this.registerFactory('tempo', () => new TempoFacilitator());\n this.registerFactory('bnb', (config) => new BNBFacilitator(config?.serverPrivateKey as string));\n this.registerFactory('solana', (config) => {\n // Load fee payer keypair from config or env\n let feePayerKeypair: Keypair | undefined;\n const feePayerKey = (config as any)?.feePayerPrivateKey || process.env.SOLANA_FEE_PAYER_KEY;\n \n if (feePayerKey) {\n try {\n feePayerKeypair = Keypair.fromSecretKey(bs58.decode(feePayerKey));\n } catch (e: any) {\n console.warn(`[SolanaFacilitator] Invalid fee payer key: ${e.message}`);\n }\n }\n \n return new SolanaFacilitator({ feePayerKeypair } as SolanaFacilitatorConfig);\n });\n \n // Default selection\n this.selection = selection || { primary: 'cdp', fallback: ['tempo', 'bnb', 'solana'], strategy: 'failover' };\n }\n \n /**\n * Register a new facilitator factory\n */\n registerFactory(name: string, factory: FacilitatorFactory): void {\n this.factories.set(name, factory);\n }\n \n /**\n * Get or create a facilitator instance\n */\n get(name: string, config?: FacilitatorConfig): Facilitator {\n // Check cache first\n if (this.instances.has(name)) {\n return this.instances.get(name)!;\n }\n \n // Look up factory\n const factory = this.factories.get(name);\n if (!factory) {\n throw new Error(`Unknown facilitator: ${name}. Available: ${Array.from(this.factories.keys()).join(', ')}`);\n }\n \n // Merge config from selection\n const mergedConfig = {\n ...this.selection.config?.[name],\n ...config,\n };\n \n // Create and cache instance\n const instance = factory(mergedConfig);\n this.instances.set(name, instance);\n return instance;\n }\n \n /**\n * Get all configured facilitator names\n */\n getConfiguredNames(): string[] {\n const names = [this.selection.primary];\n if (this.selection.fallback) {\n names.push(...this.selection.fallback);\n }\n return names;\n }\n \n /**\n * Get list of facilitators based on selection strategy\n */\n private async getOrderedFacilitators(network: string): Promise<Facilitator[]> {\n const names = this.getConfiguredNames();\n const facilitators: Facilitator[] = [];\n \n for (const name of names) {\n try {\n const f = this.get(name);\n if (f.supportsNetwork(network)) {\n facilitators.push(f);\n }\n } catch (err) {\n console.warn(`[Registry] Failed to get facilitator ${name}:`, err);\n }\n }\n \n if (facilitators.length === 0) {\n throw new Error(`No facilitators available for network: ${network}`);\n }\n \n // Apply strategy\n switch (this.selection.strategy) {\n case 'random':\n return this.shuffle(facilitators);\n \n case 'roundrobin':\n this.roundRobinIndex = (this.roundRobinIndex + 1) % facilitators.length;\n return [\n ...facilitators.slice(this.roundRobinIndex),\n ...facilitators.slice(0, this.roundRobinIndex),\n ];\n \n case 'cheapest':\n return this.sortByCheapest(facilitators);\n \n case 'fastest':\n return this.sortByFastest(facilitators);\n \n case 'failover':\n default:\n return facilitators;\n }\n }\n \n private shuffle<T>(array: T[]): T[] {\n const result = [...array];\n for (let i = result.length - 1; i > 0; i--) {\n const j = Math.floor(Math.random() * (i + 1));\n [result[i], result[j]] = [result[j], result[i]];\n }\n return result;\n }\n \n private async sortByCheapest(facilitators: Facilitator[]): Promise<Facilitator[]> {\n const withFees = await Promise.all(\n facilitators.map(async (f) => {\n try {\n const fee = await f.getFee?.();\n return { facilitator: f, perTx: fee?.perTx ?? Infinity };\n } catch {\n return { facilitator: f, perTx: Infinity };\n }\n })\n );\n withFees.sort((a, b) => a.perTx - b.perTx);\n return withFees.map(w => w.facilitator);\n }\n \n private async sortByFastest(facilitators: Facilitator[]): Promise<Facilitator[]> {\n const withLatency = await Promise.all(\n facilitators.map(async (f) => {\n try {\n const health = await f.healthCheck();\n return { facilitator: f, latency: health.latencyMs ?? Infinity };\n } catch {\n return { facilitator: f, latency: Infinity };\n }\n })\n );\n withLatency.sort((a, b) => a.latency - b.latency);\n return withLatency.map(w => w.facilitator);\n }\n \n /**\n * Verify payment using configured facilitators\n */\n async verify(\n paymentPayload: X402PaymentPayload,\n requirements: X402PaymentRequirements\n ): Promise<VerifyResult & { facilitator: string }> {\n const network = paymentPayload.accepted?.network || paymentPayload.network || requirements.network;\n const facilitators = await this.getOrderedFacilitators(network);\n \n let lastError: string | undefined;\n \n for (const f of facilitators) {\n try {\n console.log(`[Registry] Trying ${f.name} for verify...`);\n const result = await f.verify(paymentPayload, requirements);\n \n if (result.valid) {\n console.log(`[Registry] ${f.name} verify succeeded`);\n return { ...result, facilitator: f.name };\n }\n \n lastError = result.error;\n console.log(`[Registry] ${f.name} verify failed: ${result.error}`);\n \n // For failover strategy, only try next if it's a network/server error\n if (this.selection.strategy === 'failover' && !this.isTransientError(result.error)) {\n // Permanent error (e.g., invalid signature) - don't try others\n break;\n }\n } catch (err: any) {\n lastError = err.message;\n console.error(`[Registry] ${f.name} error:`, err.message);\n }\n }\n \n return {\n valid: false,\n error: lastError || 'All facilitators failed',\n facilitator: 'none',\n };\n }\n \n /**\n * Settle payment using configured facilitators\n */\n async settle(\n paymentPayload: X402PaymentPayload,\n requirements: X402PaymentRequirements\n ): Promise<SettleResult & { facilitator: string }> {\n const network = paymentPayload.accepted?.network || paymentPayload.network || requirements.network;\n const facilitators = await this.getOrderedFacilitators(network);\n \n let lastError: string | undefined;\n \n for (const f of facilitators) {\n try {\n console.log(`[Registry] Trying ${f.name} for settle...`);\n const result = await f.settle(paymentPayload, requirements);\n \n if (result.success) {\n console.log(`[Registry] ${f.name} settle succeeded: ${result.transaction}`);\n return { ...result, facilitator: f.name };\n }\n \n lastError = result.error;\n console.log(`[Registry] ${f.name} settle failed: ${result.error}`);\n } catch (err: any) {\n lastError = err.message;\n console.error(`[Registry] ${f.name} error:`, err.message);\n }\n }\n \n return {\n success: false,\n error: lastError || 'All facilitators failed',\n facilitator: 'none',\n };\n }\n \n /**\n * Check health of all configured facilitators\n */\n async healthCheckAll(): Promise<Record<string, HealthCheckResult>> {\n const results: Record<string, HealthCheckResult> = {};\n \n for (const name of this.getConfiguredNames()) {\n try {\n const f = this.get(name);\n results[name] = await f.healthCheck();\n } catch (err: any) {\n results[name] = { healthy: false, error: err.message };\n }\n }\n \n return results;\n }\n \n /**\n * Check if an error is transient (network/server issue) vs permanent (bad request)\n */\n private isTransientError(error?: string): boolean {\n if (!error) return true;\n const transientPatterns = [\n /timeout/i,\n /network/i,\n /connection/i,\n /ECONNREFUSED/i,\n /ETIMEDOUT/i,\n /503/,\n /502/,\n /500/,\n ];\n return transientPatterns.some(p => p.test(error));\n }\n \n /**\n * Update selection configuration\n */\n setSelection(selection: FacilitatorSelection): void {\n this.selection = selection;\n // Clear cached instances to pick up new config\n this.instances.clear();\n }\n \n /**\n * Get current selection configuration\n */\n getSelection(): FacilitatorSelection {\n return { ...this.selection };\n }\n}\n\n// Default registry instance\nlet defaultRegistry: FacilitatorRegistry | null = null;\n\n/**\n * Get the default facilitator registry\n */\nexport function getDefaultRegistry(): FacilitatorRegistry {\n if (!defaultRegistry) {\n defaultRegistry = new FacilitatorRegistry();\n }\n return defaultRegistry;\n}\n\n/**\n * Create a new registry with custom selection\n */\nexport function createRegistry(selection?: FacilitatorSelection): FacilitatorRegistry {\n return new FacilitatorRegistry(selection);\n}\n"],"mappings":";AAoJO,IAAe,kBAAf,MAAsD;AAAA,EAe3D,gBAAgB,SAA0B;AACxC,WAAO,KAAK,kBAAkB,SAAS,OAAO;AAAA,EAChD;AACF;;;ACxJA,SAAS,cAAc,kBAAkB;AACzC,YAAY,UAAU;AAatB,IAAM,eAAe;AAGrB,IAAM,UAAU;AAGhB,IAAM,oBAAoB,CAAC,KAAK;AAYhC,SAAS,cAAoB;AAC3B,QAAM,WAAW;AAAA,IACV,UAAK,QAAQ,IAAI,GAAG,MAAM;AAAA,IAC1B,UAAK,QAAQ,IAAI,QAAQ,IAAI,aAAa,MAAM;AAAA,EACvD;AAEA,aAAW,WAAW,UAAU;AAC9B,QAAI,WAAW,OAAO,GAAG;AACvB,UAAI;AACF,cAAM,UAAU,aAAa,SAAS,OAAO;AAC7C,mBAAW,QAAQ,QAAQ,MAAM,IAAI,GAAG;AACtC,gBAAM,UAAU,KAAK,KAAK;AAC1B,cAAI,CAAC,WAAW,QAAQ,WAAW,GAAG,EAAG;AACzC,gBAAM,UAAU,QAAQ,QAAQ,GAAG;AACnC,cAAI,YAAY,GAAI;AACpB,gBAAM,MAAM,QAAQ,MAAM,GAAG,OAAO,EAAE,KAAK;AAC3C,cAAI,QAAQ,QAAQ,MAAM,UAAU,CAAC,EAAE,KAAK;AAC5C,cAAK,MAAM,WAAW,GAAG,KAAK,MAAM,SAAS,GAAG,KAC3C,MAAM,WAAW,GAAG,KAAK,MAAM,SAAS,GAAG,GAAI;AAClD,oBAAQ,MAAM,MAAM,GAAG,EAAE;AAAA,UAC3B;AACA,cAAI,CAAC,QAAQ,IAAI,GAAG,GAAG;AACrB,oBAAQ,IAAI,GAAG,IAAI;AAAA,UACrB;AAAA,QACF;AACA;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AACF;AAOO,IAAM,iBAAN,cAA6B,gBAAgB;AAAA,EACzC,OAAO;AAAA,EACP,cAAc;AAAA,EACd;AAAA,EAED;AAAA,EACA;AAAA,EACA;AAAA,EAER,YAAY,SAA+B,CAAC,GAAG;AAC7C,UAAM;AAGN,gBAAY;AAGZ,SAAK,WAAW,OAAO,YAAY,QAAQ,IAAI;AAC/C,SAAK,eAAe,OAAO,gBAAgB,QAAQ,IAAI;AAGvD,SAAK,WAAW;AAGhB,SAAK,oBAAoB;AAAA,MACvB;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IACF;AAGA,QAAI,CAAC,KAAK,YAAY,CAAC,KAAK,cAAc;AACxC,cAAQ,KAAK,oDAAoD;AACjE,cAAQ,KAAK,gFAAgF;AAAA,IAC/F;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,eACZ,QACA,SACA,MACiC;AACjC,QAAI,CAAC,KAAK,YAAY,CAAC,KAAK,cAAc;AACxC,YAAM,IAAI,MAAM,qEAAqE;AAAA,IACvF;AAEA,QAAI;AACF,YAAM,EAAE,eAAe,IAAI,MAAM,OAAO,wBAAwB;AAEhE,aAAO,MAAM,eAAe;AAAA,QAC1B,UAAU,KAAK;AAAA,QACf,cAAc,KAAK;AAAA,QACnB,eAAe;AAAA,QACf,aAAa;AAAA,QACb,aAAa;AAAA,QACb,aAAa;AAAA,MACf,CAAC;AAAA,IACH,SAAS,KAAU;AACjB,YAAM,IAAI,MAAM,gCAAgC,IAAI,OAAO,EAAE;AAAA,IAC/D;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cAA0C;AAC9C,UAAM,QAAQ,KAAK,IAAI;AAEvB,QAAI;AAGF,YAAM,aAAa,IAAI,gBAAgB;AACvC,YAAM,UAAU,WAAW,MAAM,WAAW,MAAM,GAAG,GAAI;AAEzD,YAAM,WAAW,MAAM,MAAM,KAAK,SAAS,QAAQ,SAAS,EAAE,GAAG;AAAA,QAC/D,QAAQ;AAAA,QACR,QAAQ,WAAW;AAAA,MACrB,CAAC,EAAE,MAAM,MAAM,IAAI;AAEnB,mBAAa,OAAO;AAEpB,YAAM,YAAY,KAAK,IAAI,IAAI;AAE/B,aAAO;AAAA,QACL,SAAS,aAAa;AAAA,QACtB;AAAA,MACF;AAAA,IACF,SAAS,KAAU;AACjB,aAAO;AAAA,QACL,SAAS;AAAA,QACT,OAAO,IAAI;AAAA,QACX,WAAW,KAAK,IAAI,IAAI;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OACJ,gBACA,cACuB;AACvB,QAAI;AACF,YAAM,cAAc;AAAA,QAClB,aAAa;AAAA,QACb;AAAA,QACA,qBAAqB;AAAA,MACvB;AAEA,cAAQ,IAAI,yBAAyB,KAAK,UAAU,gBAAgB,MAAM,CAAC,CAAC;AAE5E,YAAM,cAAc,MAAM,KAAK;AAAA,QAC7B;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAEA,YAAM,UAAkC;AAAA,QACtC,gBAAgB;AAAA,QAChB,GAAG;AAAA,MACL;AAEA,YAAM,WAAW,MAAM,MAAM,GAAG,KAAK,QAAQ,WAAW;AAAA,QACtD,QAAQ;AAAA,QACR;AAAA,QACA,MAAM,KAAK,UAAU,WAAW;AAAA,MAClC,CAAC;AAED,YAAM,SAAS,MAAM,SAAS,KAAK;AACnC,cAAQ,IAAI,0BAA0B,SAAS,QAAQ,KAAK,UAAU,MAAM,CAAC;AAE7E,UAAI,CAAC,SAAS,MAAM,CAAC,OAAO,SAAS;AACnC,eAAO;AAAA,UACL,OAAO;AAAA,UACP,OAAO,OAAO,iBAAiB,OAAO,SAAS;AAAA,UAC/C,SAAS;AAAA,QACX;AAAA,MACF;AAEA,aAAO,EAAE,OAAO,MAAM,SAAS,OAAO;AAAA,IACxC,SAAS,KAAU;AACjB,aAAO;AAAA,QACL,OAAO;AAAA,QACP,OAAO,sBAAsB,IAAI,OAAO;AAAA,MAC1C;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OACJ,gBACA,cACuB;AACvB,QAAI;AACF,YAAM,cAAc;AAAA,QAClB,aAAa;AAAA,QACb;AAAA,QACA,qBAAqB;AAAA,MACvB;AAEA,YAAM,cAAc,MAAM,KAAK;AAAA,QAC7B;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAEA,YAAM,UAAkC;AAAA,QACtC,gBAAgB;AAAA,QAChB,GAAG;AAAA,MACL;AAEA,YAAM,WAAW,MAAM,MAAM,GAAG,KAAK,QAAQ,WAAW;AAAA,QACtD,QAAQ;AAAA,QACR;AAAA,QACA,MAAM,KAAK,UAAU,WAAW;AAAA,MAClC,CAAC;AAED,YAAM,SAAS,MAAM,SAAS,KAAK;AAEnC,UAAI,CAAC,SAAS,MAAM,CAAC,OAAO,SAAS;AACnC,eAAO;AAAA,UACL,SAAS;AAAA,UACT,OAAO,OAAO,SAAS,OAAO,eAAe;AAAA,QAC/C;AAAA,MACF;AAEA,aAAO;AAAA,QACL,SAAS;AAAA,QACT,aAAa,OAAO;AAAA,QACpB,QAAQ,OAAO,UAAU;AAAA,MAC3B;AAAA,IACF,SAAS,KAAU;AACjB,aAAO;AAAA,QACL,SAAS;AAAA,QACT,OAAO,qBAAqB,IAAI,OAAO;AAAA,MACzC;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SAAkC;AAEtC,WAAO;AAAA,MACL,OAAO;AAAA,MACP,UAAU;AAAA,MACV,WAAW;AAAA,IACb;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,UAAU,SAA0B;AACzC,WAAO,kBAAkB,SAAS,OAAO;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA,EAKA,mBAA2B;AACzB,UAAM,iBAAiB,CAAC,EAAE,KAAK,YAAY,KAAK;AAChD,UAAM,WAAW,KAAK,kBAAkB,KAAK,IAAI;AACjD,WAAO,8BAA8B,QAAQ,kBAAkB,iBAAiB,QAAQ,IAAI;AAAA,EAC9F;AACF;;;ACrTO,IAAM,SAA4C;AAAA;AAAA,EAEvD,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,SAAS;AAAA,IACT,KAAK;AAAA,IACL,QAAQ;AAAA,MACN,MAAM;AAAA,QACJ,SAAS;AAAA,QACT,UAAU;AAAA,QACV,QAAQ;AAAA,QACR,YAAY;AAAA;AAAA,MACd;AAAA,MACA,MAAM;AAAA,QACJ,SAAS;AAAA,QACT,UAAU;AAAA,QACV,QAAQ;AAAA,QACR,YAAY;AAAA,MACd;AAAA,IACF;AAAA,IACA,MAAM;AAAA;AAAA,IACN,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,cAAc;AAAA,EAChB;AAAA,EACA,SAAS;AAAA,IACP,MAAM;AAAA,IACN,SAAS;AAAA,IACT,KAAK;AAAA,IACL,QAAQ;AAAA,MACN,MAAM;AAAA,QACJ,SAAS;AAAA,QACT,UAAU;AAAA,QACV,QAAQ;AAAA,QACR,YAAY;AAAA,MACd;AAAA,MACA,MAAM;AAAA,QACJ,SAAS;AAAA,QACT,UAAU;AAAA,QACV,QAAQ;AAAA,QACR,YAAY;AAAA;AAAA,MACd;AAAA,IACF;AAAA,IACA,MAAM;AAAA,IACN,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,cAAc;AAAA,EAChB;AAAA;AAAA,EAEA,cAAc;AAAA,IACZ,MAAM;AAAA,IACN,SAAS;AAAA,IACT,KAAK;AAAA,IACL,QAAQ;AAAA,MACN,MAAM;AAAA,QACJ,SAAS;AAAA,QACT,UAAU;AAAA,QACV,QAAQ;AAAA,QACR,YAAY;AAAA;AAAA,MACd;AAAA,MACA,MAAM;AAAA,QACJ,SAAS;AAAA;AAAA,QACT,UAAU;AAAA,QACV,QAAQ;AAAA,QACR,YAAY;AAAA;AAAA,MACd;AAAA,IACF;AAAA,IACA,MAAM;AAAA,IACN,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,cAAc;AAAA,EAChB;AAAA;AAAA,EAEA,gBAAgB;AAAA,IACd,MAAM;AAAA,IACN,SAAS;AAAA,IACT,KAAK;AAAA,IACL,QAAQ;AAAA;AAAA;AAAA,MAGN,MAAM;AAAA,QACJ,SAAS;AAAA;AAAA,QACT,UAAU;AAAA,QACV,QAAQ;AAAA,QACR,YAAY;AAAA,MACd;AAAA,MACA,MAAM;AAAA,QACJ,SAAS;AAAA;AAAA,QACT,UAAU;AAAA,QACV,QAAQ;AAAA,QACR,YAAY;AAAA,MACd;AAAA,IACF;AAAA,IACA,MAAM;AAAA,IACN,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,cAAc;AAAA;AAAA,EAChB;AAAA;AAAA,EAEA,aAAa;AAAA,IACX,MAAM;AAAA,IACN,SAAS;AAAA,IACT,KAAK;AAAA,IACL,QAAQ;AAAA;AAAA;AAAA,MAGN,MAAM;AAAA,QACJ,SAAS;AAAA;AAAA,QACT,UAAU;AAAA,QACV,QAAQ;AAAA,QACR,YAAY;AAAA,MACd;AAAA,MACA,MAAM;AAAA,QACJ,SAAS;AAAA;AAAA,QACT,UAAU;AAAA,QACV,QAAQ;AAAA,QACR,YAAY;AAAA,MACd;AAAA,IACF;AAAA,IACA,MAAM;AAAA,IACN,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,cAAc;AAAA;AAAA,IAEd,kBAAkB;AAAA,EACpB;AAAA;AAAA,EAEA,KAAK;AAAA,IACH,MAAM;AAAA,IACN,SAAS;AAAA,IACT,KAAK;AAAA,IACL,QAAQ;AAAA;AAAA,MAEN,MAAM;AAAA,QACJ,SAAS;AAAA,QACT,UAAU;AAAA,QACV,QAAQ;AAAA,QACR,YAAY;AAAA,MACd;AAAA,MACA,MAAM;AAAA,QACJ,SAAS;AAAA,QACT,UAAU;AAAA,QACV,QAAQ;AAAA,QACR,YAAY;AAAA,MACd;AAAA,IACF;AAAA,IACA,MAAM;AAAA,IACN,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,cAAc;AAAA;AAAA,IAEd,kBAAkB;AAAA,EACpB;AACF;;;AC7IA,IAAM,uBAAuB;AAYtB,IAAM,mBAAN,cAA+B,gBAAgB;AAAA,EAC3C,OAAO;AAAA,EACP,cAAc;AAAA,EACd,oBAAoB,CAAC,cAAc;AAAA;AAAA,EAEpC;AAAA,EAER,cAAc;AACZ,UAAM;AACN,SAAK,SAAS,OAAO,eAAe;AAAA,EACtC;AAAA,EAEA,MAAM,cAA0C;AAC9C,UAAM,QAAQ,KAAK,IAAI;AACvB,QAAI;AACF,YAAM,WAAW,MAAM,MAAM,KAAK,QAAQ;AAAA,QACxC,QAAQ;AAAA,QACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,QAC9C,MAAM,KAAK,UAAU;AAAA,UACnB,SAAS;AAAA,UACT,QAAQ;AAAA,UACR,QAAQ,CAAC;AAAA,UACT,IAAI;AAAA,QACN,CAAC;AAAA,MACH,CAAC;AAED,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,UAAU,SAAS,KAAK,QAAQ,EAAE;AAExC,UAAI,YAAY,OAAO;AACrB,eAAO,EAAE,SAAS,OAAO,OAAO,kBAAkB,OAAO,GAAG;AAAA,MAC9D;AAEA,aAAO,EAAE,SAAS,MAAM,WAAW,KAAK,IAAI,IAAI,MAAM;AAAA,IACxD,SAAS,OAAO;AACd,aAAO,EAAE,SAAS,OAAO,OAAO,OAAO,KAAK,EAAE;AAAA,IAChD;AAAA,EACF;AAAA,EAEA,MAAM,OACJ,gBACA,cACuB;AACvB,QAAI;AAEF,YAAM,eAAe,eAAe;AAEpC,UAAI,CAAC,cAAc,QAAQ;AACzB,eAAO,EAAE,OAAO,OAAO,OAAO,oCAAoC;AAAA,MACpE;AAGA,YAAM,UAAU,MAAM,KAAK,sBAAsB,aAAa,MAAM;AAEpE,UAAI,CAAC,SAAS;AACZ,eAAO,EAAE,OAAO,OAAO,OAAO,wBAAwB;AAAA,MACxD;AAEA,UAAI,QAAQ,WAAW,OAAO;AAC5B,eAAO,EAAE,OAAO,OAAO,OAAO,qBAAqB;AAAA,MACrD;AAGA,YAAM,cAAc,QAAQ,KAAK;AAAA,QAAK,CAAC,QACrC,IAAI,OAAO,CAAC,MAAM;AAAA,MACpB;AAEA,UAAI,CAAC,aAAa;AAChB,eAAO,EAAE,OAAO,OAAO,OAAO,0BAA0B;AAAA,MAC1D;AAGA,YAAM,YAAY,OAAO,YAAY,OAAO,CAAC,EAAE,MAAM,EAAE,EAAE,YAAY;AACrE,YAAM,aAAa,aAAa,MAAM,YAAY;AAElD,UAAI,cAAc,YAAY;AAC5B,eAAO;AAAA,UACL,OAAO;AAAA,UACP,OAAO,oBAAoB,SAAS,cAAc,UAAU;AAAA,QAC9D;AAAA,MACF;AAGA,YAAM,SAAS,OAAO,YAAY,IAAI;AACtC,YAAM,iBAAiB,OAAO,aAAa,MAAM;AAEjD,UAAI,SAAS,gBAAgB;AAC3B,eAAO;AAAA,UACL,OAAO;AAAA,UACP,OAAO,wBAAwB,MAAM,cAAc,cAAc;AAAA,QACnE;AAAA,MACF;AAGA,YAAM,eAAe,YAAY,QAAQ,YAAY;AACrD,YAAM,gBAAgB,aAAa,MAAM,YAAY;AAErD,UAAI,iBAAiB,eAAe;AAClC,eAAO;AAAA,UACL,OAAO;AAAA,UACP,OAAO,gBAAgB,YAAY,cAAc,aAAa;AAAA,QAChE;AAAA,MACF;AAEA,aAAO;AAAA,QACL,OAAO;AAAA,QACP,SAAS;AAAA,UACP,QAAQ,aAAa;AAAA,UACrB,MAAM,OAAO,YAAY,OAAO,CAAC,EAAE,MAAM,EAAE;AAAA,UAC3C,IAAI;AAAA,UACJ,QAAQ,OAAO,SAAS;AAAA,UACxB,OAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,aAAO,EAAE,OAAO,OAAO,OAAO,wBAAwB,KAAK,GAAG;AAAA,IAChE;AAAA,EACF;AAAA,EAEA,MAAM,OACJ,gBACA,cACuB;AAGvB,UAAM,eAAe,MAAM,KAAK,OAAO,gBAAgB,YAAY;AAEnE,QAAI,CAAC,aAAa,OAAO;AACvB,aAAO,EAAE,SAAS,OAAO,OAAO,aAAa,MAAM;AAAA,IACrD;AAEA,UAAM,eAAe,eAAe;AAEpC,WAAO;AAAA,MACL,SAAS;AAAA,MACT,aAAa,aAAa;AAAA,MAC1B,QAAQ;AAAA,IACV;AAAA,EACF;AAAA,EAEA,MAAc,sBAAsB,QAA8B;AAChE,UAAM,WAAW,MAAM,MAAM,KAAK,QAAQ;AAAA,MACxC,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAC9C,MAAM,KAAK,UAAU;AAAA,QACnB,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,QAAQ,CAAC,MAAM;AAAA,QACf,IAAI;AAAA,MACN,CAAC;AAAA,IACH,CAAC;AAED,UAAM,OAAO,MAAM,SAAS,KAAK;AACjC,WAAO,KAAK;AAAA,EACd;AACF;;;AC9JA,SAAS,2BAA2B;AAGpC,IAAMA,wBAAuB;AAG7B,IAAM,gBAAgB;AAAA,EACpB,MAAM;AAAA,EACN,SAAS;AACX;AAGA,IAAM,eAAe;AAAA,EACnB,eAAe;AAAA,IACb,EAAE,MAAM,QAAQ,MAAM,UAAU;AAAA,IAChC,EAAE,MAAM,MAAM,MAAM,UAAU;AAAA,IAC9B,EAAE,MAAM,UAAU,MAAM,UAAU;AAAA,IAClC,EAAE,MAAM,SAAS,MAAM,UAAU;AAAA,IACjC,EAAE,MAAM,WAAW,MAAM,SAAS;AAAA,IAClC,EAAE,MAAM,SAAS,MAAM,UAAU;AAAA,IACjC,EAAE,MAAM,YAAY,MAAM,UAAU;AAAA,EACtC;AACF;AAuCO,IAAM,iBAAN,cAA6B,gBAAgB;AAAA,EACzC,OAAO;AAAA,EACP,cAAc;AAAA,EACd,oBAAoB,CAAC,aAAa,WAAW;AAAA;AAAA,EAE9C;AAAA,EACA,iBAAgC;AAAA,EAChC;AAAA,EAER,YAAY,kBAA2B;AACrC,UAAM;AACN,SAAK,mBAAmB,oBAAoB,QAAQ,IAAI,0BAA0B;AAGlF,QAAI,KAAK,kBAAkB;AACzB,YAAM,MAAM,KAAK,iBAAiB,WAAW,IAAI,IAC7C,KAAK,mBACL,KAAK,KAAK,gBAAgB;AAC9B,YAAM,UAAU,oBAAoB,GAAG;AACvC,WAAK,iBAAiB,QAAQ;AAAA,IAChC;AAEA,SAAK,eAAe;AAAA,MAClB,IAAI,EAAE,KAAK,OAAO,IAAI,KAAK,OAAO,OAAO,IAAI;AAAA,MAC7C,IAAI,EAAE,KAAK,OAAO,YAAY,KAAK,OAAO,OAAO,YAAY;AAAA,IAC/D;AAAA,EACF;AAAA,EAEA,MAAM,cAA0C;AAC9C,UAAM,QAAQ,KAAK,IAAI;AACvB,QAAI;AAEF,YAAM,WAAW,MAAM,MAAM,KAAK,aAAa,EAAE,EAAE,KAAK;AAAA,QACtD,QAAQ;AAAA,QACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,QAC9C,MAAM,KAAK,UAAU;AAAA,UACnB,SAAS;AAAA,UACT,QAAQ;AAAA,UACR,QAAQ,CAAC;AAAA,UACT,IAAI;AAAA,QACN,CAAC;AAAA,MACH,CAAC;AAED,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,UAAU,SAAS,KAAK,QAAQ,EAAE;AAExC,UAAI,YAAY,IAAI;AAClB,eAAO,EAAE,SAAS,OAAO,OAAO,kBAAkB,OAAO,GAAG;AAAA,MAC9D;AAEA,aAAO,EAAE,SAAS,MAAM,WAAW,KAAK,IAAI,IAAI,MAAM;AAAA,IACxD,SAAS,OAAO;AACd,aAAO,EAAE,SAAS,OAAO,OAAO,OAAO,KAAK,EAAE;AAAA,IAChD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,OACJ,gBACA,cACuB;AACvB,QAAI;AACF,YAAM,aAAa,eAAe;AAElC,UAAI,CAAC,YAAY,QAAQ;AACvB,eAAO,EAAE,OAAO,OAAO,OAAO,oCAAoC;AAAA,MACpE;AAEA,YAAM,EAAE,QAAQ,QAAQ,IAAI;AAC5B,YAAM,SAAS,KAAK,aAAa,OAAO;AAExC,UAAI,CAAC,QAAQ;AACX,eAAO,EAAE,OAAO,OAAO,OAAO,wBAAwB,OAAO,GAAG;AAAA,MAClE;AAGA,UAAI,OAAO,WAAW,KAAK,IAAI,GAAG;AAChC,eAAO,EAAE,OAAO,OAAO,OAAO,iBAAiB;AAAA,MACjD;AAGA,YAAM,mBAAmB,MAAM,KAAK,oBAAoB,QAAQ,OAAO;AACvE,UAAI,iBAAiB,YAAY,MAAM,OAAO,KAAK,YAAY,GAAG;AAChE,eAAO,EAAE,OAAO,OAAO,OAAO,oBAAoB;AAAA,MACpD;AAGA,UAAI,OAAO,GAAG,YAAY,MAAM,aAAa,MAAM,YAAY,GAAG;AAChE,eAAO,EAAE,OAAO,OAAO,OAAO,oBAAoB,OAAO,EAAE,GAAG;AAAA,MAChE;AAGA,UAAI,OAAO,OAAO,MAAM,IAAI,OAAO,aAAa,MAAM,GAAG;AACvD,eAAO,EAAE,OAAO,OAAO,OAAO,wBAAwB,OAAO,MAAM,GAAG;AAAA,MACxE;AAGA,UAAI,OAAO,MAAM,YAAY,MAAM,aAAa,MAAM,YAAY,GAAG;AACnE,eAAO,EAAE,OAAO,OAAO,OAAO,gBAAgB,OAAO,KAAK,GAAG;AAAA,MAC/D;AAGA,YAAM,gBAAgB,MAAM,KAAK,iBAAiB;AAClD,YAAM,YAAY,MAAM,KAAK,aAAa,OAAO,MAAM,eAAe,OAAO,OAAO,OAAO,GAAG;AAE9F,UAAI,OAAO,SAAS,IAAI,OAAO,OAAO,MAAM,GAAG;AAC7C,eAAO,EAAE,OAAO,OAAO,OAAO,6DAA6D;AAAA,MAC7F;AAGA,YAAM,UAAU,MAAM,KAAK,WAAW,OAAO,MAAM,OAAO,OAAO,OAAO,GAAG;AAC3E,UAAI,OAAO,OAAO,IAAI,OAAO,OAAO,MAAM,GAAG;AAC3C,eAAO,EAAE,OAAO,OAAO,OAAO,uBAAuB;AAAA,MACvD;AAEA,aAAO;AAAA,QACL,OAAO;AAAA,QACP,SAAS;AAAA,UACP,MAAM,OAAO;AAAA,UACb,IAAI,OAAO;AAAA,UACX,QAAQ,OAAO;AAAA,UACf,OAAO,OAAO;AAAA,UACd,SAAS,OAAO;AAAA,UAChB,OAAO,OAAO;AAAA,UACd,UAAU,OAAO;AAAA,QACnB;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,aAAO,EAAE,OAAO,OAAO,OAAO,wBAAwB,KAAK,GAAG;AAAA,IAChE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,OACJ,gBACA,cACuB;AACvB,QAAI,CAAC,KAAK,kBAAkB;AAC1B,aAAO,EAAE,SAAS,OAAO,OAAO,wDAAwD;AAAA,IAC1F;AAEA,QAAI;AAEF,YAAM,eAAe,MAAM,KAAK,OAAO,gBAAgB,YAAY;AACnE,UAAI,CAAC,aAAa,OAAO;AACvB,eAAO,EAAE,SAAS,OAAO,OAAO,aAAa,MAAM;AAAA,MACrD;AAEA,YAAM,aAAa,eAAe;AAClC,YAAM,EAAE,QAAQ,QAAQ,IAAI;AAC5B,YAAM,SAAS,KAAK,aAAa,OAAO;AAGxC,YAAM,SAAS,MAAM,KAAK;AAAA,QACxB,OAAO;AAAA,QACP,OAAO;AAAA,QACP,OAAO;AAAA,QACP,OAAO;AAAA,QACP,OAAO;AAAA,MACT;AAEA,aAAO;AAAA,QACL,SAAS;AAAA,QACT,aAAa;AAAA,QACb,QAAQ;AAAA,MACV;AAAA,IACF,SAAS,OAAO;AACd,aAAO,EAAE,SAAS,OAAO,OAAO,sBAAsB,KAAK,GAAG;AAAA,IAChE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cACJ,eACA,OACA,SACmD;AACnD,UAAM,SAAS,KAAK,aAAa,OAAO;AACxC,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI,MAAM,wBAAwB,OAAO,EAAE;AAAA,IACnD;AAEA,UAAM,gBAAgB,MAAM,KAAK,iBAAiB;AAClD,UAAM,YAAY,MAAM,KAAK,aAAa,eAAe,eAAe,OAAO,OAAO,GAAG;AAGzF,UAAM,eAAe,OAAO,wBAAwB;AAEpD,WAAO;AAAA,MACL,UAAU,OAAO,SAAS,KAAK;AAAA,MAC/B;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,kBACJ,QACA,UACA,SACuB;AACvB,UAAM,SAAS,KAAK,aAAa,OAAO;AACxC,QAAI,CAAC,QAAQ;AACX,aAAO,EAAE,OAAO,OAAO,OAAO,wBAAwB,OAAO,GAAG;AAAA,IAClE;AAEA,QAAI;AACF,YAAM,UAAU,MAAM,KAAK,sBAAsB,QAAQ,OAAO,GAAG;AAEnE,UAAI,CAAC,SAAS;AACZ,eAAO,EAAE,OAAO,OAAO,OAAO,wBAAwB;AAAA,MACxD;AAEA,UAAI,QAAQ,WAAW,OAAO;AAC5B,eAAO,EAAE,OAAO,OAAO,OAAO,qBAAqB;AAAA,MACrD;AAGA,YAAM,cAAc,QAAQ,KAAK;AAAA,QAAK,CAAC,QACrC,IAAI,OAAO,CAAC,MAAMC,yBAClB,IAAI,QAAQ,YAAY,MAAM,SAAS,MAAM,YAAY;AAAA,MAC3D;AAEA,UAAI,CAAC,aAAa;AAChB,eAAO,EAAE,OAAO,OAAO,OAAO,0BAA0B;AAAA,MAC1D;AAGA,YAAM,YAAY,OAAO,YAAY,OAAO,CAAC,EAAE,MAAM,EAAE,EAAE,YAAY;AACrE,UAAI,cAAc,SAAS,GAAG,YAAY,GAAG;AAC3C,eAAO,EAAE,OAAO,OAAO,OAAO,oBAAoB,SAAS,GAAG;AAAA,MAChE;AAGA,YAAM,SAAS,OAAO,YAAY,IAAI;AACtC,UAAI,SAAS,OAAO,SAAS,MAAM,GAAG;AACpC,eAAO,EAAE,OAAO,OAAO,OAAO,wBAAwB,MAAM,GAAG;AAAA,MACjE;AAEA,aAAO;AAAA,QACL,OAAO;AAAA,QACP,SAAS;AAAA,UACP;AAAA,UACA,MAAM,OAAO,YAAY,OAAO,CAAC,EAAE,MAAM,EAAE;AAAA,UAC3C,IAAI;AAAA,UACJ,QAAQ,OAAO,SAAS;AAAA,UACxB,OAAO,YAAY;AAAA,QACrB;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,aAAO,EAAE,OAAO,OAAO,OAAO,wBAAwB,KAAK,GAAG;AAAA,IAChE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,oBAAmC;AACjC,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAc,mBAAoC;AAEhD,UAAM,EAAE,OAAO,IAAI,MAAM,OAAO,QAAQ;AACxC,UAAM,SAAS,IAAI,OAAO,OAAO,KAAK,gBAAgB;AACtD,WAAO,OAAO;AAAA,EAChB;AAAA,EAEA,MAAc,oBAAoB,QAA0B,SAAkC;AAE5F,UAAM,EAAE,OAAO,IAAI,MAAM,OAAO,QAAQ;AAExC,UAAM,SAAS;AAAA,MACb,GAAG;AAAA,MACH;AAAA,IACF;AAEA,UAAM,UAAU;AAAA,MACd,MAAM,OAAO;AAAA,MACb,IAAI,OAAO;AAAA,MACX,QAAQ,OAAO;AAAA,MACf,OAAO,OAAO;AAAA,MACd,SAAS,OAAO;AAAA,MAChB,OAAO,OAAO;AAAA,MACd,UAAU,OAAO;AAAA,IACnB;AAEA,UAAM,mBAAmB,OAAO;AAAA,MAC9B;AAAA,MACA;AAAA,MACA;AAAA,MACA,OAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,aAAa,OAAe,SAAiB,OAAe,QAAiC;AAEzG,UAAM,WAAW;AACjB,UAAM,cAAc,MAAM,YAAY,EAAE,QAAQ,MAAM,EAAE,EAAE,SAAS,IAAI,GAAG;AAC1E,UAAM,gBAAgB,QAAQ,YAAY,EAAE,QAAQ,MAAM,EAAE,EAAE,SAAS,IAAI,GAAG;AAC9E,UAAM,OAAO,WAAW,cAAc;AAEtC,UAAM,WAAW,MAAM,MAAM,QAAQ;AAAA,MACnC,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAC9C,MAAM,KAAK,UAAU;AAAA,QACnB,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,QAAQ,CAAC,EAAE,IAAI,OAAO,KAAK,GAAG,QAAQ;AAAA,QACtC,IAAI;AAAA,MACN,CAAC;AAAA,IACH,CAAC;AAED,UAAM,SAAS,MAAM,SAAS,KAAK;AACnC,WAAO,OAAO,UAAU;AAAA,EAC1B;AAAA,EAEA,MAAc,WAAW,SAAiB,OAAe,QAAiC;AAExF,UAAM,WAAW;AACjB,UAAM,gBAAgB,QAAQ,YAAY,EAAE,QAAQ,MAAM,EAAE,EAAE,SAAS,IAAI,GAAG;AAC9E,UAAM,OAAO,WAAW;AAExB,UAAM,WAAW,MAAM,MAAM,QAAQ;AAAA,MACnC,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAC9C,MAAM,KAAK,UAAU;AAAA,QACnB,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,QAAQ,CAAC,EAAE,IAAI,OAAO,KAAK,GAAG,QAAQ;AAAA,QACtC,IAAI;AAAA,MACN,CAAC;AAAA,IACH,CAAC;AAED,UAAM,SAAS,MAAM,SAAS,KAAK;AACnC,WAAO,OAAO,UAAU;AAAA,EAC1B;AAAA,EAEA,MAAc,oBACZ,MACA,IACA,QACA,OACA,QACiB;AACjB,UAAM,EAAE,OAAO,IAAI,MAAM,OAAO,QAAQ;AAExC,UAAM,WAAW,IAAI,OAAO,gBAAgB,MAAM;AAClD,UAAM,SAAS,IAAI,OAAO,OAAO,KAAK,kBAAkB,QAAQ;AAEhE,UAAM,gBAAgB,IAAI,OAAO,SAAS,OAAO;AAAA,MAC/C;AAAA,IACF,GAAG,MAAM;AAET,UAAM,KAAK,MAAM,cAAc,aAAa,MAAM,IAAI,MAAM;AAC5D,UAAM,UAAU,MAAM,GAAG,KAAK;AAE9B,WAAO,QAAQ;AAAA,EACjB;AAAA,EAEA,MAAc,sBAAsB,QAAgB,QAA8B;AAChF,UAAM,WAAW,MAAM,MAAM,QAAQ;AAAA,MACnC,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAC9C,MAAM,KAAK,UAAU;AAAA,QACnB,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,QAAQ,CAAC,MAAM;AAAA,QACf,IAAI;AAAA,MACN,CAAC;AAAA,IACH,CAAC;AAED,UAAM,OAAO,MAAM,SAAS,KAAK;AACjC,WAAO,KAAK;AAAA,EACd;AACF;AAOO,SAAS,sBACd,QACA,SACA;AACA,SAAO;AAAA,IACL,QAAQ;AAAA,MACN,GAAG;AAAA,MACH;AAAA,IACF;AAAA,IACA,OAAO;AAAA,IACP,aAAa;AAAA,IACb,SAAS;AAAA,MACP,MAAM,OAAO;AAAA,MACb,IAAI,OAAO;AAAA,MACX,QAAQ,OAAO;AAAA,MACf,OAAO,OAAO;AAAA,MACd,SAAS,OAAO;AAAA,MAChB,OAAO,OAAO;AAAA,MACd,UAAU,OAAO;AAAA,IACnB;AAAA,EACF;AACF;;;AClfA;AAAA,EACE,cAAAC;AAAA,EACA,aAAAC;AAAA,EACA;AAAA,EACA;AAAA,OAGK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEK;;;ACnBP,SAAS,YAAY,iBAAiB;AAkB/B,IAAM,gBAA4D;AAAA,EACvE,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,IACT,KAAK;AAAA,IACL,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,QAAQ;AAAA,MACN,MAAM;AAAA,QACJ,MAAM;AAAA;AAAA,QACN,UAAU;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AAAA,EACA,eAAe;AAAA,IACb,MAAM;AAAA,IACN,SAAS;AAAA,IACT,KAAK;AAAA,IACL,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,QAAQ;AAAA,MACN,MAAM;AAAA;AAAA,QAEJ,MAAM;AAAA,QACN,UAAU;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AACF;;;ADSO,IAAM,oBAAN,cAAgC,gBAAgB;AAAA,EAC5C,OAAO;AAAA,EACP,cAAc;AAAA,EACd,oBAAoB,CAAC,kBAAkB,eAAe;AAAA,EAEvD,cAAgD,oBAAI,IAAI;AAAA,EACxD;AAAA,EAER,YAAY,QAAkC;AAC5C,UAAM;AACN,SAAK,kBAAkB,QAAQ;AAG/B,eAAW,CAAC,OAAOC,OAAM,KAAK,OAAO,QAAQ,aAAa,GAAG;AAC3D,WAAK,YAAY;AAAA,QACf;AAAA,QACA,IAAIC,YAAWD,QAAO,KAAK,WAAW;AAAA,MACxC;AAAA,IACF;AAEA,QAAI,KAAK,iBAAiB;AACxB,cAAQ,IAAI,wDAAwD,KAAK,gBAAgB,UAAU,SAAS,CAAC,EAAE;AAAA,IACjH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,oBAAmC;AACjC,WAAO,KAAK,iBAAiB,UAAU,SAAS,KAAK;AAAA,EACvD;AAAA,EAEQ,cAAc,OAAoC;AACxD,UAAM,OAAO,KAAK,YAAY,IAAI,KAAK;AACvC,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,MAAM,4BAA4B,KAAK,EAAE;AAAA,IACrD;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,eAAe,OAAgC;AACpD,WAAO,UAAU,WAAW,mBAAmB;AAAA,EACjD;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,eAAe,SAAyC;AAC7D,QAAI,YAAY,iBAAkB,QAAO;AACzC,QAAI,YAAY,gBAAiB,QAAO;AACxC,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,cAA0C;AAC9C,UAAM,QAAQ,KAAK,IAAI;AACvB,QAAI;AAEF,YAAM,OAAO,KAAK,cAAc,eAAe;AAC/C,YAAM,KAAK,QAAQ;AACnB,aAAO;AAAA,QACL,SAAS;AAAA,QACT,WAAW,KAAK,IAAI,IAAI;AAAA,MAC1B;AAAA,IACF,SAAS,OAAY;AACnB,aAAO;AAAA,QACL,SAAS;AAAA,QACT,OAAO,MAAM;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,OACJ,gBACA,cACuB;AACvB,QAAI;AACF,YAAM,gBAAgB,eAAe;AACrC,UAAI,CAAC,iBAAiB,CAAC,cAAc,mBAAmB;AACtD,eAAO,EAAE,OAAO,OAAO,OAAO,6BAA6B;AAAA,MAC7D;AAEA,YAAM,QAAQ,cAAc,SAAS;AACrC,YAAM,cAAc,cAAc,KAAK;AACvC,UAAI,CAAC,aAAa;AAChB,eAAO,EAAE,OAAO,OAAO,OAAO,kBAAkB,KAAK,GAAG;AAAA,MAC1D;AAGA,YAAM,WAAW,OAAO,KAAK,cAAc,mBAAmB,QAAQ;AACtE,UAAI;AAEJ,UAAI;AAEF,aAAK,YAAY,KAAK,QAAQ;AAAA,MAChC,QAAQ;AAEN,aAAK,qBAAqB,YAAY,QAAQ;AAAA,MAChD;AAGA,UAAI,cAAc,aAAa;AAG7B,cAAM,kBAAkB,GAAG,WAAW;AAAA,UAAK,SACzC,IAAI,aAAa,CAAC,IAAI,UAAU,MAAM,OAAK,MAAM,CAAC;AAAA,QACpD;AACA,YAAI,CAAC,iBAAiB;AACpB,iBAAO,EAAE,OAAO,OAAO,OAAO,yBAAyB;AAAA,QACzD;AAAA,MACF;AAGA,YAAM,iBAAiB,OAAO,aAAa,MAAM;AACjD,YAAM,oBAAoB,IAAIE,WAAU,aAAa,KAAK;AAI1D,aAAO;AAAA,QACL,OAAO;AAAA,QACP,SAAS;AAAA,UACP;AAAA,UACA,QAAQ,cAAc;AAAA,UACtB,WAAW,aAAa;AAAA,UACxB,QAAQ,aAAa;AAAA,QACvB;AAAA,MACF;AAAA,IACF,SAAS,OAAY;AACnB,aAAO,EAAE,OAAO,OAAO,OAAO,MAAM,QAAQ;AAAA,IAC9C;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,OACJ,gBACA,cACuB;AACvB,QAAI;AACF,YAAM,gBAAgB,eAAe;AACrC,UAAI,CAAC,iBAAiB,CAAC,cAAc,mBAAmB;AACtD,eAAO,EAAE,SAAS,OAAO,OAAO,6BAA6B;AAAA,MAC/D;AAEA,YAAM,QAAQ,cAAc,SAAS;AACrC,YAAM,aAAa,KAAK,cAAc,KAAK;AAG3C,YAAM,WAAW,OAAO,KAAK,cAAc,mBAAmB,QAAQ;AAEtE,UAAI;AAEJ,UAAI;AAEF,cAAM,KAAK,YAAY,KAAK,QAAQ;AAGpC,YAAI,KAAK,mBAAmB,GAAG,UAAU;AACvC,gBAAM,iBAAiB,KAAK,gBAAgB,UAAU,SAAS;AAC/D,gBAAM,aAAa,GAAG,SAAS,SAAS;AAExC,cAAI,eAAe,gBAAgB;AAEjC,oBAAQ,IAAI,8DAA8D;AAC1E,eAAG,YAAY,KAAK,eAAe;AAAA,UACrC;AAAA,QACF;AAEA,mBAAW,GAAG,UAAU;AAAA,MAC1B,SAAS,GAAQ;AAEf,mBAAW;AAAA,MACb;AAGA,YAAM,YAAY,MAAM,WAAW,mBAAmB,UAAU;AAAA,QAC9D,eAAe;AAAA,QACf,qBAAqB;AAAA,MACvB,CAAC;AAGD,YAAM,eAAe,MAAM,WAAW,mBAAmB,WAAW,WAAW;AAE/E,UAAI,aAAa,MAAM,KAAK;AAC1B,eAAO;AAAA,UACL,SAAS;AAAA,UACT,OAAO,uBAAuB,KAAK,UAAU,aAAa,MAAM,GAAG,CAAC;AAAA,UACpE,aAAa;AAAA,QACf;AAAA,MACF;AAEA,aAAO;AAAA,QACL,SAAS;AAAA,QACT,aAAa;AAAA,QACb,QAAQ;AAAA,MACV;AAAA,IACF,SAAS,OAAY;AACnB,aAAO,EAAE,SAAS,OAAO,OAAO,MAAM,QAAQ;AAAA,IAChD;AAAA,EACF;AAAA,EAEA,gBAAgB,SAA0B;AACxC,WAAO,KAAK,kBAAkB,SAAS,OAAO;AAAA,EAChD;AACF;AAaA,eAAsB,+BACpB,cACA,iBACA,QACA,OACA,gBACsB;AACtB,QAAM,cAAc,cAAc,KAAK;AACvC,QAAM,aAAa,IAAID,YAAW,YAAY,KAAK,WAAW;AAC9D,QAAM,OAAO,IAAIC,WAAU,YAAY,OAAO,KAAK,IAAI;AAGvD,QAAM,iBAAiB,kBAAkB;AAGzC,QAAM,YAAY,MAAM,0BAA0B,MAAM,YAAY;AACpE,QAAM,eAAe,MAAM,0BAA0B,MAAM,eAAe;AAE1E,QAAM,cAAc,IAAI,YAAY;AAGpC,MAAI;AACF,UAAM,WAAW,YAAY,YAAY;AAAA,EAC3C,QAAQ;AAEN,gBAAY;AAAA,MACV;AAAA,QACE;AAAA;AAAA,QACA;AAAA;AAAA,QACA;AAAA;AAAA,QACA;AAAA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,cAAY;AAAA,IACV;AAAA,MACE;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA,YAAY,OAAO,KAAK;AAAA;AAAA,IAC1B;AAAA,EACF;AAGA,QAAM,EAAE,WAAW,qBAAqB,IAAI,MAAM,WAAW,mBAAmB;AAChF,cAAY,kBAAkB;AAC9B,cAAY,WAAW;AAEvB,SAAO;AACT;;;AEvUA,SAAS,WAAAC,gBAAe;AACxB,OAAO,UAAU;AAoCV,IAAM,sBAAN,MAA0B;AAAA,EACvB,YAA6C,oBAAI,IAAI;AAAA,EACrD,YAAsC,oBAAI,IAAI;AAAA,EAC9C;AAAA,EACA,kBAAkB;AAAA,EAE1B,YAAY,WAAkC;AAE5C,SAAK,gBAAgB,OAAO,CAAC,WAAW,IAAI,eAAe,MAA8B,CAAC;AAC1F,SAAK,gBAAgB,SAAS,MAAM,IAAI,iBAAiB,CAAC;AAC1D,SAAK,gBAAgB,OAAO,CAAC,WAAW,IAAI,eAAe,QAAQ,gBAA0B,CAAC;AAC9F,SAAK,gBAAgB,UAAU,CAAC,WAAW;AAEzC,UAAI;AACJ,YAAM,cAAe,QAAgB,sBAAsB,QAAQ,IAAI;AAEvE,UAAI,aAAa;AACf,YAAI;AACF,4BAAkBA,SAAQ,cAAc,KAAK,OAAO,WAAW,CAAC;AAAA,QAClE,SAAS,GAAQ;AACf,kBAAQ,KAAK,8CAA8C,EAAE,OAAO,EAAE;AAAA,QACxE;AAAA,MACF;AAEA,aAAO,IAAI,kBAAkB,EAAE,gBAAgB,CAA4B;AAAA,IAC7E,CAAC;AAGD,SAAK,YAAY,aAAa,EAAE,SAAS,OAAO,UAAU,CAAC,SAAS,OAAO,QAAQ,GAAG,UAAU,WAAW;AAAA,EAC7G;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAgB,MAAc,SAAmC;AAC/D,SAAK,UAAU,IAAI,MAAM,OAAO;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,MAAc,QAAyC;AAEzD,QAAI,KAAK,UAAU,IAAI,IAAI,GAAG;AAC5B,aAAO,KAAK,UAAU,IAAI,IAAI;AAAA,IAChC;AAGA,UAAM,UAAU,KAAK,UAAU,IAAI,IAAI;AACvC,QAAI,CAAC,SAAS;AACZ,YAAM,IAAI,MAAM,wBAAwB,IAAI,gBAAgB,MAAM,KAAK,KAAK,UAAU,KAAK,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE;AAAA,IAC5G;AAGA,UAAM,eAAe;AAAA,MACnB,GAAG,KAAK,UAAU,SAAS,IAAI;AAAA,MAC/B,GAAG;AAAA,IACL;AAGA,UAAM,WAAW,QAAQ,YAAY;AACrC,SAAK,UAAU,IAAI,MAAM,QAAQ;AACjC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,qBAA+B;AAC7B,UAAM,QAAQ,CAAC,KAAK,UAAU,OAAO;AACrC,QAAI,KAAK,UAAU,UAAU;AAC3B,YAAM,KAAK,GAAG,KAAK,UAAU,QAAQ;AAAA,IACvC;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,uBAAuB,SAAyC;AAC5E,UAAM,QAAQ,KAAK,mBAAmB;AACtC,UAAM,eAA8B,CAAC;AAErC,eAAW,QAAQ,OAAO;AACxB,UAAI;AACF,cAAM,IAAI,KAAK,IAAI,IAAI;AACvB,YAAI,EAAE,gBAAgB,OAAO,GAAG;AAC9B,uBAAa,KAAK,CAAC;AAAA,QACrB;AAAA,MACF,SAAS,KAAK;AACZ,gBAAQ,KAAK,wCAAwC,IAAI,KAAK,GAAG;AAAA,MACnE;AAAA,IACF;AAEA,QAAI,aAAa,WAAW,GAAG;AAC7B,YAAM,IAAI,MAAM,0CAA0C,OAAO,EAAE;AAAA,IACrE;AAGA,YAAQ,KAAK,UAAU,UAAU;AAAA,MAC/B,KAAK;AACH,eAAO,KAAK,QAAQ,YAAY;AAAA,MAElC,KAAK;AACH,aAAK,mBAAmB,KAAK,kBAAkB,KAAK,aAAa;AACjE,eAAO;AAAA,UACL,GAAG,aAAa,MAAM,KAAK,eAAe;AAAA,UAC1C,GAAG,aAAa,MAAM,GAAG,KAAK,eAAe;AAAA,QAC/C;AAAA,MAEF,KAAK;AACH,eAAO,KAAK,eAAe,YAAY;AAAA,MAEzC,KAAK;AACH,eAAO,KAAK,cAAc,YAAY;AAAA,MAExC,KAAK;AAAA,MACL;AACE,eAAO;AAAA,IACX;AAAA,EACF;AAAA,EAEQ,QAAW,OAAiB;AAClC,UAAM,SAAS,CAAC,GAAG,KAAK;AACxB,aAAS,IAAI,OAAO,SAAS,GAAG,IAAI,GAAG,KAAK;AAC1C,YAAM,IAAI,KAAK,MAAM,KAAK,OAAO,KAAK,IAAI,EAAE;AAC5C,OAAC,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC;AAAA,IAChD;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,eAAe,cAAqD;AAChF,UAAM,WAAW,MAAM,QAAQ;AAAA,MAC7B,aAAa,IAAI,OAAO,MAAM;AAC5B,YAAI;AACF,gBAAM,MAAM,MAAM,EAAE,SAAS;AAC7B,iBAAO,EAAE,aAAa,GAAG,OAAO,KAAK,SAAS,SAAS;AAAA,QACzD,QAAQ;AACN,iBAAO,EAAE,aAAa,GAAG,OAAO,SAAS;AAAA,QAC3C;AAAA,MACF,CAAC;AAAA,IACH;AACA,aAAS,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK;AACzC,WAAO,SAAS,IAAI,OAAK,EAAE,WAAW;AAAA,EACxC;AAAA,EAEA,MAAc,cAAc,cAAqD;AAC/E,UAAM,cAAc,MAAM,QAAQ;AAAA,MAChC,aAAa,IAAI,OAAO,MAAM;AAC5B,YAAI;AACF,gBAAM,SAAS,MAAM,EAAE,YAAY;AACnC,iBAAO,EAAE,aAAa,GAAG,SAAS,OAAO,aAAa,SAAS;AAAA,QACjE,QAAQ;AACN,iBAAO,EAAE,aAAa,GAAG,SAAS,SAAS;AAAA,QAC7C;AAAA,MACF,CAAC;AAAA,IACH;AACA,gBAAY,KAAK,CAAC,GAAG,MAAM,EAAE,UAAU,EAAE,OAAO;AAChD,WAAO,YAAY,IAAI,OAAK,EAAE,WAAW;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OACJ,gBACA,cACiD;AACjD,UAAM,UAAU,eAAe,UAAU,WAAW,eAAe,WAAW,aAAa;AAC3F,UAAM,eAAe,MAAM,KAAK,uBAAuB,OAAO;AAE9D,QAAI;AAEJ,eAAW,KAAK,cAAc;AAC5B,UAAI;AACF,gBAAQ,IAAI,qBAAqB,EAAE,IAAI,gBAAgB;AACvD,cAAM,SAAS,MAAM,EAAE,OAAO,gBAAgB,YAAY;AAE1D,YAAI,OAAO,OAAO;AAChB,kBAAQ,IAAI,cAAc,EAAE,IAAI,mBAAmB;AACnD,iBAAO,EAAE,GAAG,QAAQ,aAAa,EAAE,KAAK;AAAA,QAC1C;AAEA,oBAAY,OAAO;AACnB,gBAAQ,IAAI,cAAc,EAAE,IAAI,mBAAmB,OAAO,KAAK,EAAE;AAGjE,YAAI,KAAK,UAAU,aAAa,cAAc,CAAC,KAAK,iBAAiB,OAAO,KAAK,GAAG;AAElF;AAAA,QACF;AAAA,MACF,SAAS,KAAU;AACjB,oBAAY,IAAI;AAChB,gBAAQ,MAAM,cAAc,EAAE,IAAI,WAAW,IAAI,OAAO;AAAA,MAC1D;AAAA,IACF;AAEA,WAAO;AAAA,MACL,OAAO;AAAA,MACP,OAAO,aAAa;AAAA,MACpB,aAAa;AAAA,IACf;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OACJ,gBACA,cACiD;AACjD,UAAM,UAAU,eAAe,UAAU,WAAW,eAAe,WAAW,aAAa;AAC3F,UAAM,eAAe,MAAM,KAAK,uBAAuB,OAAO;AAE9D,QAAI;AAEJ,eAAW,KAAK,cAAc;AAC5B,UAAI;AACF,gBAAQ,IAAI,qBAAqB,EAAE,IAAI,gBAAgB;AACvD,cAAM,SAAS,MAAM,EAAE,OAAO,gBAAgB,YAAY;AAE1D,YAAI,OAAO,SAAS;AAClB,kBAAQ,IAAI,cAAc,EAAE,IAAI,sBAAsB,OAAO,WAAW,EAAE;AAC1E,iBAAO,EAAE,GAAG,QAAQ,aAAa,EAAE,KAAK;AAAA,QAC1C;AAEA,oBAAY,OAAO;AACnB,gBAAQ,IAAI,cAAc,EAAE,IAAI,mBAAmB,OAAO,KAAK,EAAE;AAAA,MACnE,SAAS,KAAU;AACjB,oBAAY,IAAI;AAChB,gBAAQ,MAAM,cAAc,EAAE,IAAI,WAAW,IAAI,OAAO;AAAA,MAC1D;AAAA,IACF;AAEA,WAAO;AAAA,MACL,SAAS;AAAA,MACT,OAAO,aAAa;AAAA,MACpB,aAAa;AAAA,IACf;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,iBAA6D;AACjE,UAAM,UAA6C,CAAC;AAEpD,eAAW,QAAQ,KAAK,mBAAmB,GAAG;AAC5C,UAAI;AACF,cAAM,IAAI,KAAK,IAAI,IAAI;AACvB,gBAAQ,IAAI,IAAI,MAAM,EAAE,YAAY;AAAA,MACtC,SAAS,KAAU;AACjB,gBAAQ,IAAI,IAAI,EAAE,SAAS,OAAO,OAAO,IAAI,QAAQ;AAAA,MACvD;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,iBAAiB,OAAyB;AAChD,QAAI,CAAC,MAAO,QAAO;AACnB,UAAM,oBAAoB;AAAA,MACxB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,WAAO,kBAAkB,KAAK,OAAK,EAAE,KAAK,KAAK,CAAC;AAAA,EAClD;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa,WAAuC;AAClD,SAAK,YAAY;AAEjB,SAAK,UAAU,MAAM;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA,EAKA,eAAqC;AACnC,WAAO,EAAE,GAAG,KAAK,UAAU;AAAA,EAC7B;AACF;AAGA,IAAI,kBAA8C;AAK3C,SAAS,qBAA0C;AACxD,MAAI,CAAC,iBAAiB;AACpB,sBAAkB,IAAI,oBAAoB;AAAA,EAC5C;AACA,SAAO;AACT;AAKO,SAAS,eAAe,WAAuD;AACpF,SAAO,IAAI,oBAAoB,SAAS;AAC1C;","names":["TRANSFER_EVENT_TOPIC","TRANSFER_EVENT_TOPIC","Connection","PublicKey","config","Connection","PublicKey","Keypair"]}
|
|
@@ -18,8 +18,12 @@ interface ChainConfig {
|
|
|
18
18
|
explorer: string;
|
|
19
19
|
explorerTx: string;
|
|
20
20
|
avgBlockTime: number;
|
|
21
|
+
/** If true, requires one-time approval for pay-for-success flow (e.g., BNB) */
|
|
22
|
+
requiresApproval?: boolean;
|
|
21
23
|
}
|
|
22
|
-
type
|
|
24
|
+
type EvmChainName = 'base' | 'polygon' | 'base_sepolia' | 'tempo_moderato' | 'bnb' | 'bnb_testnet';
|
|
25
|
+
type SolanaChainName = 'solana' | 'solana_devnet';
|
|
26
|
+
type ChainName = EvmChainName | SolanaChainName;
|
|
23
27
|
interface WalletBalance {
|
|
24
28
|
address: string;
|
|
25
29
|
eth: string;
|
|
@@ -40,4 +44,4 @@ interface TransferResult {
|
|
|
40
44
|
error?: string;
|
|
41
45
|
}
|
|
42
46
|
|
|
43
|
-
export type {
|
|
47
|
+
export type { ChainConfig as C, EvmChainName as E, TokenSymbol as T, WalletBalance as W, TokenConfig as a, ChainName as b, TransferResult as c };
|
|
@@ -18,8 +18,12 @@ interface ChainConfig {
|
|
|
18
18
|
explorer: string;
|
|
19
19
|
explorerTx: string;
|
|
20
20
|
avgBlockTime: number;
|
|
21
|
+
/** If true, requires one-time approval for pay-for-success flow (e.g., BNB) */
|
|
22
|
+
requiresApproval?: boolean;
|
|
21
23
|
}
|
|
22
|
-
type
|
|
24
|
+
type EvmChainName = 'base' | 'polygon' | 'base_sepolia' | 'tempo_moderato' | 'bnb' | 'bnb_testnet';
|
|
25
|
+
type SolanaChainName = 'solana' | 'solana_devnet';
|
|
26
|
+
type ChainName = EvmChainName | SolanaChainName;
|
|
23
27
|
interface WalletBalance {
|
|
24
28
|
address: string;
|
|
25
29
|
eth: string;
|
|
@@ -40,4 +44,4 @@ interface TransferResult {
|
|
|
40
44
|
error?: string;
|
|
41
45
|
}
|
|
42
46
|
|
|
43
|
-
export type {
|
|
47
|
+
export type { ChainConfig as C, EvmChainName as E, TokenSymbol as T, WalletBalance as W, TokenConfig as a, ChainName as b, TransferResult as c };
|
package/dist/index.d.mts
CHANGED
|
@@ -6,4 +6,5 @@ export { VerifyPaymentParams, VerifyPaymentResult, getTransactionStatus, verifyP
|
|
|
6
6
|
export { CDPWallet, getCDPWalletAddress, initCDPWallet, isCDPAvailable, loadCDPWallet } from './cdp/index.mjs';
|
|
7
7
|
export { B as BaseFacilitator, F as Facilitator, a as FacilitatorConfig, b as FacilitatorFee, c as FacilitatorRegistry, d as FacilitatorSelection, H as HealthCheckResult, S as SelectionStrategy, e as SettleResult, V as VerifyResult, X as X402PaymentPayload, f as X402PaymentRequirements, g as createRegistry, h as getDefaultRegistry } from './registry-OsEO2dOu.mjs';
|
|
8
8
|
export { C as CDPFacilitator, a as CDPFacilitatorConfig } from './cdp-p_eHuQpb.mjs';
|
|
9
|
-
import '
|
|
9
|
+
import 'ethers';
|
|
10
|
+
import './index-D_2FkLwV.mjs';
|
package/dist/index.d.ts
CHANGED
|
@@ -6,4 +6,5 @@ export { VerifyPaymentParams, VerifyPaymentResult, getTransactionStatus, verifyP
|
|
|
6
6
|
export { CDPWallet, getCDPWalletAddress, initCDPWallet, isCDPAvailable, loadCDPWallet } from './cdp/index.js';
|
|
7
7
|
export { B as BaseFacilitator, F as Facilitator, a as FacilitatorConfig, b as FacilitatorFee, c as FacilitatorRegistry, d as FacilitatorSelection, H as HealthCheckResult, S as SelectionStrategy, e as SettleResult, V as VerifyResult, X as X402PaymentPayload, f as X402PaymentRequirements, g as createRegistry, h as getDefaultRegistry } from './registry-OsEO2dOu.js';
|
|
8
8
|
export { C as CDPFacilitator, a as CDPFacilitatorConfig } from './cdp-DeohBe1o.js';
|
|
9
|
-
import '
|
|
9
|
+
import 'ethers';
|
|
10
|
+
import './index-D_2FkLwV.js';
|