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.
Files changed (57) hide show
  1. package/README.md +221 -38
  2. package/dist/cdp/index.d.mts +4 -4
  3. package/dist/cdp/index.d.ts +4 -4
  4. package/dist/cdp/index.js +57 -0
  5. package/dist/cdp/index.js.map +1 -1
  6. package/dist/cdp/index.mjs +57 -0
  7. package/dist/cdp/index.mjs.map +1 -1
  8. package/dist/chains/index.d.mts +9 -8
  9. package/dist/chains/index.d.ts +9 -8
  10. package/dist/chains/index.js +57 -0
  11. package/dist/chains/index.js.map +1 -1
  12. package/dist/chains/index.mjs +57 -0
  13. package/dist/chains/index.mjs.map +1 -1
  14. package/dist/cli/index.js +1975 -273
  15. package/dist/cli/index.js.map +1 -1
  16. package/dist/cli/index.mjs +1977 -265
  17. package/dist/cli/index.mjs.map +1 -1
  18. package/dist/client/index.d.mts +36 -3
  19. package/dist/client/index.d.ts +36 -3
  20. package/dist/client/index.js +540 -32
  21. package/dist/client/index.js.map +1 -1
  22. package/dist/client/index.mjs +548 -30
  23. package/dist/client/index.mjs.map +1 -1
  24. package/dist/facilitators/index.d.mts +220 -1
  25. package/dist/facilitators/index.d.ts +220 -1
  26. package/dist/facilitators/index.js +664 -1
  27. package/dist/facilitators/index.js.map +1 -1
  28. package/dist/facilitators/index.mjs +670 -1
  29. package/dist/facilitators/index.mjs.map +1 -1
  30. package/dist/{index-On9ZaGDW.d.mts → index-D_2FkLwV.d.mts} +6 -2
  31. package/dist/{index-On9ZaGDW.d.ts → index-D_2FkLwV.d.ts} +6 -2
  32. package/dist/index.d.mts +2 -1
  33. package/dist/index.d.ts +2 -1
  34. package/dist/index.js +1413 -146
  35. package/dist/index.js.map +1 -1
  36. package/dist/index.mjs +1421 -144
  37. package/dist/index.mjs.map +1 -1
  38. package/dist/server/index.d.mts +13 -3
  39. package/dist/server/index.d.ts +13 -3
  40. package/dist/server/index.js +905 -52
  41. package/dist/server/index.js.map +1 -1
  42. package/dist/server/index.mjs +915 -52
  43. package/dist/server/index.mjs.map +1 -1
  44. package/dist/verify/index.d.mts +1 -1
  45. package/dist/verify/index.d.ts +1 -1
  46. package/dist/verify/index.js +57 -0
  47. package/dist/verify/index.js.map +1 -1
  48. package/dist/verify/index.mjs +57 -0
  49. package/dist/verify/index.mjs.map +1 -1
  50. package/dist/wallet/index.d.mts +3 -3
  51. package/dist/wallet/index.d.ts +3 -3
  52. package/dist/wallet/index.js +57 -0
  53. package/dist/wallet/index.js.map +1 -1
  54. package/dist/wallet/index.mjs +57 -0
  55. package/dist/wallet/index.mjs.map +1 -1
  56. package/package.json +4 -1
  57. package/schemas/moltspay.services.schema.json +27 -132
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/server/index.ts","../src/facilitators/interface.ts","../src/facilitators/cdp.ts","../src/chains/index.ts","../src/facilitators/tempo.ts","../src/facilitators/registry.ts","../src/client/index.ts","../src/wallet/Wallet.ts","../src/wallet/createWallet.ts","../src/verify/index.ts","../src/cdp/index.ts"],"sourcesContent":["/**\n * MoltsPay - Payment infrastructure for AI Agents\n * \n * Server (for agents selling services):\n * import { MoltsPayServer } from 'moltspay';\n * const server = new MoltsPayServer('./moltspay.services.json');\n * server.skill('my-service', async (params) => { ... });\n * server.listen(3000);\n * \n * Client (for agents buying services):\n * import { MoltsPayClient } from 'moltspay';\n * const client = new MoltsPayClient();\n * const result = await client.pay('http://provider:3000', 'my-service', { ... });\n * \n * @packageDocumentation\n */\n\n// Server - for selling services\nexport { MoltsPayServer } from './server/index.js';\nexport type {\n ServicesManifest,\n ServiceConfig,\n ProviderConfig,\n SkillFunction,\n RegisteredSkill,\n Charge,\n ChargeStatus,\n PaymentRequest,\n MoltsPayServerOptions,\n} from './server/types.js';\n\n// Client - for buying services\nexport { MoltsPayClient } from './client/index.js';\nexport type {\n ClientConfig,\n WalletData,\n PaymentRequired,\n ServiceInfo,\n ProviderInfo,\n ServicesResponse,\n VerifyResponse,\n MoltsPayClientOptions,\n} from './client/types.js';\n\n// Chain configuration\nexport { CHAINS, getChain, listChains, getChainById, ERC20_ABI } from './chains/index.js';\n\n// Wallet utilities\nexport {\n createWallet,\n loadWallet,\n getWalletAddress,\n walletExists,\n} from './wallet/index.js';\n\n// Payment verification\nexport {\n verifyPayment,\n getTransactionStatus,\n waitForTransaction,\n type VerifyPaymentParams,\n type VerifyPaymentResult,\n} from './verify/index.js';\n\n// CDP Wallet (optional)\nexport {\n initCDPWallet,\n loadCDPWallet,\n getCDPWalletAddress,\n isCDPAvailable,\n CDPWallet,\n} from './cdp/index.js';\n\n// Facilitators (v0.9.0+)\nexport {\n Facilitator,\n BaseFacilitator,\n FacilitatorRegistry,\n CDPFacilitator,\n getDefaultRegistry,\n createRegistry,\n} from './facilitators/index.js';\nexport type {\n FacilitatorConfig,\n FacilitatorSelection,\n SelectionStrategy,\n X402PaymentPayload,\n X402PaymentRequirements,\n VerifyResult,\n SettleResult,\n HealthCheckResult,\n FacilitatorFee,\n CDPFacilitatorConfig,\n} from './facilitators/index.js';\n","/**\n * MoltsPay Server - Payment infrastructure for AI Agents\n * \n * Now uses pluggable Facilitator abstraction for payment verification/settlement.\n * \n * Environment variables (from ~/.moltspay/.env or process.env):\n * USE_MAINNET=true - Use Base mainnet (requires CDP keys)\n * CDP_API_KEY_ID=xxx - Coinbase Developer Platform API key ID\n * CDP_API_KEY_SECRET=xxx - CDP API key secret\n * \n * Usage:\n * const server = new MoltsPayServer('./moltspay.services.json');\n * server.skill('text-to-video', async (params) => { ... });\n * server.listen(3000);\n */\n\nimport { readFileSync, existsSync } from 'fs';\nimport { createServer, IncomingMessage, ServerResponse } from 'http';\nimport * as path from 'path';\nimport {\n FacilitatorRegistry,\n FacilitatorSelection,\n X402PaymentPayload,\n X402PaymentRequirements,\n} from '../facilitators/index.js';\nimport {\n ServicesManifest,\n ServiceConfig,\n SkillFunction,\n RegisteredSkill,\n MoltsPayServerOptions,\n} from './types.js';\n\nexport * from './types.js';\n\n// x402 constants\nconst X402_VERSION = 2;\nconst PAYMENT_REQUIRED_HEADER = 'x-payment-required';\nconst PAYMENT_HEADER = 'x-payment';\nconst PAYMENT_RESPONSE_HEADER = 'x-payment-response';\n\n// MPP (Machine Payments Protocol) constants\nconst MPP_AUTH_HEADER = 'authorization';\nconst MPP_WWW_AUTH_HEADER = 'www-authenticate';\nconst MPP_RECEIPT_HEADER = 'payment-receipt';\n\n// Token contract addresses by network\nconst TOKEN_ADDRESSES: Record<string, Record<string, string>> = {\n 'eip155:8453': {\n USDC: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\n USDT: '0xfde4C96c8593536E31F229EA8f37b2ADa2699bb2',\n },\n 'eip155:84532': {\n USDC: '0x036CbD53842c5426634e7929541eC2318f3dCF7e',\n USDT: '0x036CbD53842c5426634e7929541eC2318f3dCF7e', // Same as USDC on testnet\n },\n 'eip155:137': {\n USDC: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',\n USDT: '0xc2132D05D31c914a87C6611C10748AEb04B58e8F',\n },\n 'eip155:42431': {\n // Tempo Moderato testnet - TIP-20 stablecoins\n USDC: '0x20c0000000000000000000000000000000000000', // pathUSD\n USDT: '0x20c0000000000000000000000000000000000001', // alphaUSD\n },\n};\n\n// Chain name to network ID mapping\nconst CHAIN_TO_NETWORK: Record<string, string> = {\n 'base': 'eip155:8453',\n 'base_sepolia': 'eip155:84532',\n 'polygon': 'eip155:137',\n 'tempo_moderato': 'eip155:42431',\n};\n\n// EIP-712 domain info for tokens (per network)\n// Different networks may have different domain names for the same token\nconst TOKEN_DOMAINS: Record<string, Record<string, { name: string; version: string }>> = {\n // Base mainnet\n 'eip155:8453': {\n USDC: { name: 'USD Coin', version: '2' },\n USDT: { name: 'Tether USD', version: '2' },\n },\n // Base Sepolia testnet - USDC uses 'USDC' not 'USD Coin'\n 'eip155:84532': {\n USDC: { name: 'USDC', version: '2' },\n USDT: { name: 'USDC', version: '2' }, // Same contract as USDC on testnet\n },\n // Polygon mainnet\n 'eip155:137': {\n USDC: { name: 'USD Coin', version: '2' },\n USDT: { name: '(PoS) Tether USD', version: '2' },\n },\n // Tempo Moderato testnet - TIP-20 stablecoins\n 'eip155:42431': {\n USDC: { name: 'pathUSD', version: '1' },\n USDT: { name: 'alphaUSD', version: '1' },\n },\n};\n\n// Helper to get token domain for a network\nfunction getTokenDomain(network: string, token: string): { name: string; version: string } {\n const networkDomains = TOKEN_DOMAINS[network] || TOKEN_DOMAINS['eip155:8453']; // fallback to base mainnet\n return networkDomains[token] || { name: 'USD Coin', version: '2' };\n}\n\n// Helper to get accepted currencies with backward compatibility\nfunction getAcceptedCurrencies(config: ServiceConfig): string[] {\n return config.acceptedCurrencies ?? [config.currency];\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 console.log(`[MoltsPay] Loaded config from ${envPath}`);\n break;\n } catch {\n // Ignore errors\n }\n }\n }\n}\n\n/**\n * Extended server options with facilitator config\n */\nexport interface MoltsPayServerOptionsExtended extends MoltsPayServerOptions {\n /** Facilitator selection configuration */\n facilitators?: FacilitatorSelection;\n}\n\nexport class MoltsPayServer {\n private manifest: ServicesManifest;\n private skills: Map<string, RegisteredSkill> = new Map();\n private options: MoltsPayServerOptionsExtended;\n private registry: FacilitatorRegistry;\n private networkId: string;\n private useMainnet: boolean;\n\n constructor(servicesPath: string, options: MoltsPayServerOptionsExtended = {}) {\n // Load env files FIRST (before reading USE_MAINNET)\n loadEnvFile();\n \n // Load services manifest\n const content = readFileSync(servicesPath, 'utf-8');\n this.manifest = JSON.parse(content) as ServicesManifest;\n \n this.options = {\n port: options.port || 3000,\n host: options.host || '0.0.0.0',\n ...options,\n };\n\n // Determine default network from env (fallback only)\n // NOTE: Chain is auto-detected from client payment header (payment.network)\n // USE_MAINNET is only used as fallback when payment header omits network\n // Recommended: configure \"chains\" array in manifest instead\n this.useMainnet = process.env.USE_MAINNET?.toLowerCase() === 'true';\n this.networkId = this.useMainnet ? 'eip155:8453' : 'eip155:84532';\n\n // Create facilitator registry with config (env vars take precedence)\n // Always include 'tempo' in fallback for Tempo testnet support\n const defaultFallback = ['tempo'];\n const envFallback = process.env.FACILITATOR_FALLBACK?.split(',').filter(Boolean);\n const facilitatorConfig: FacilitatorSelection = options.facilitators || {\n primary: process.env.FACILITATOR_PRIMARY || 'cdp',\n fallback: envFallback || defaultFallback,\n strategy: (process.env.FACILITATOR_STRATEGY as any) || 'failover',\n config: {\n cdp: { useMainnet: this.useMainnet },\n },\n };\n this.registry = new FacilitatorRegistry(facilitatorConfig);\n\n // Get primary facilitator for logging\n const primaryFacilitator = this.registry.get(facilitatorConfig.primary);\n \n console.log(`[MoltsPay] Loaded ${this.manifest.services.length} services from ${servicesPath}`);\n console.log(`[MoltsPay] Provider: ${this.manifest.provider.name}`);\n console.log(`[MoltsPay] Receive wallet: ${this.manifest.provider.wallet}`);\n \n // Log configured chains\n const chains = this.manifest.provider.chains;\n if (chains && chains.length > 0) {\n const chainNames = chains.map(c => c.chain || c.network).join(', ');\n console.log(`[MoltsPay] Chains: ${chainNames} (multi-chain enabled)`);\n } else {\n const networkName = this.useMainnet ? 'Base mainnet' : 'Base Sepolia (testnet)';\n console.log(`[MoltsPay] Network: ${this.networkId} (${networkName})`);\n }\n \n console.log(`[MoltsPay] Facilitator: ${primaryFacilitator.displayName} (${facilitatorConfig.strategy || 'failover'})`);\n console.log(`[MoltsPay] Protocol: x402 (gasless for both client AND server)`);\n }\n\n /**\n * Register a skill handler for a service\n */\n skill(serviceId: string, handler: SkillFunction): this {\n const config = this.manifest.services.find(s => s.id === serviceId);\n if (!config) {\n throw new Error(`Service '${serviceId}' not found in manifest`);\n }\n this.skills.set(serviceId, { id: serviceId, config, handler });\n return this;\n }\n\n /**\n * Get all configured chains for this provider\n * Returns array of { network, wallet, tokens } for each chain\n */\n private getProviderChains(): Array<{ network: string; wallet: string; tokens: string[] }> {\n const provider = this.manifest.provider;\n \n // If chains array is defined, use it\n // Supports both string array [\"base\", \"polygon\"] and object array [{chain, wallet, tokens}]\n if (provider.chains && provider.chains.length > 0) {\n return provider.chains.map(c => {\n const chainName = typeof c === 'string' ? c : c.chain;\n return {\n network: CHAIN_TO_NETWORK[chainName] || 'eip155:8453',\n wallet: (typeof c === 'object' ? c.wallet : null) || provider.wallet,\n tokens: (typeof c === 'object' ? c.tokens : null) || ['USDC'],\n };\n });\n }\n \n // Fallback to single chain (backward compat)\n const chain = provider.chain || 'base';\n const network = CHAIN_TO_NETWORK[chain] || this.networkId;\n return [{\n network,\n wallet: provider.wallet,\n tokens: ['USDC'],\n }];\n }\n\n /**\n * Get wallet address for a specific network\n */\n private getWalletForNetwork(network: string): string {\n const chains = this.getProviderChains();\n const chain = chains.find(c => c.network === network);\n return chain?.wallet || this.manifest.provider.wallet;\n }\n\n /**\n * Check if a network is accepted by this provider\n */\n private isNetworkAccepted(network: string): boolean {\n const chains = this.getProviderChains();\n return chains.some(c => c.network === network);\n }\n\n /**\n * Start HTTP server\n */\n listen(port?: number): void {\n const p = port || this.options.port || 3000;\n const host = this.options.host || '0.0.0.0';\n\n const server = createServer((req, res) => this.handleRequest(req, res));\n server.listen(p, host, () => {\n console.log(`[MoltsPay] Server listening on http://${host}:${p}`);\n console.log(`[MoltsPay] Endpoints:`);\n console.log(` GET /services - List available services`);\n console.log(` POST /execute - Execute service (x402 payment)`);\n console.log(` POST /proxy - Proxy payment for external services`);\n console.log(` GET /health - Health check (incl. facilitators)`);\n });\n }\n\n /**\n * Handle incoming request\n */\n private async handleRequest(req: IncomingMessage, res: ServerResponse): Promise<void> {\n // CORS\n res.setHeader('Access-Control-Allow-Origin', '*');\n res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');\n res.setHeader('Access-Control-Allow-Headers', 'Content-Type, X-Payment, Authorization');\n res.setHeader('Access-Control-Expose-Headers', 'X-Payment-Required, X-Payment-Response, WWW-Authenticate, Payment-Receipt');\n\n if (req.method === 'OPTIONS') {\n res.writeHead(204);\n res.end();\n return;\n }\n\n try {\n const url = new URL(req.url || '/', `http://${req.headers.host}`);\n \n if (url.pathname === '/services' && req.method === 'GET') {\n return this.handleGetServices(res);\n }\n\n // Standard discovery endpoint\n if (url.pathname === '/.well-known/agent-services.json' && req.method === 'GET') {\n return this.handleAgentServicesDiscovery(res);\n }\n\n if (url.pathname === '/health' && req.method === 'GET') {\n return await this.handleHealthCheck(res);\n }\n\n if (url.pathname === '/execute' && req.method === 'POST') {\n const body = await this.readBody(req);\n const paymentHeader = req.headers[PAYMENT_HEADER] as string | undefined;\n return await this.handleExecute(body, paymentHeader, res);\n }\n\n if (url.pathname === '/proxy' && req.method === 'POST') {\n // Check IP whitelist\n const clientIP = (req.headers['x-real-ip'] as string) || \n (req.headers['x-forwarded-for'] as string)?.split(',')[0]?.trim() ||\n req.socket.remoteAddress || '';\n if (!this.isProxyAllowed(clientIP)) {\n return this.sendJson(res, 403, { error: 'Forbidden: IP not allowed' });\n }\n const body = await this.readBody(req);\n const paymentHeader = req.headers[PAYMENT_HEADER] as string | undefined;\n return await this.handleProxy(body, paymentHeader, res);\n }\n\n // MPP Protocol: Handle service-specific endpoints like /text-to-video, /ping\n // Check if URL matches a registered service ID\n const servicePath = url.pathname.replace(/^\\//, ''); // Remove leading slash\n const skill = this.skills.get(servicePath);\n if (skill && (req.method === 'POST' || req.method === 'GET')) {\n const body = req.method === 'POST' ? await this.readBody(req) : {};\n const authHeader = req.headers[MPP_AUTH_HEADER] as string | undefined;\n const x402Header = req.headers[PAYMENT_HEADER] as string | undefined;\n return await this.handleMPPRequest(skill, body, authHeader, x402Header, res);\n }\n\n // Not found\n this.sendJson(res, 404, { error: 'Not found' });\n } catch (err: any) {\n console.error('[MoltsPay] Error:', err);\n this.sendJson(res, 500, { error: err.message || 'Internal error' });\n }\n }\n\n /**\n * GET /.well-known/agent-services.json - Standard discovery endpoint\n */\n private handleAgentServicesDiscovery(res: ServerResponse): void {\n const services = this.manifest.services.map(s => ({\n id: s.id,\n name: s.name,\n description: s.description,\n price: s.price,\n currency: s.currency,\n acceptedCurrencies: getAcceptedCurrencies(s),\n input: s.input,\n output: s.output,\n available: this.skills.has(s.id),\n }));\n\n this.sendJson(res, 200, {\n version: '1.0',\n provider: {\n name: this.manifest.provider.name,\n description: this.manifest.provider.description,\n wallet: this.manifest.provider.wallet,\n chain: this.manifest.provider.chain || 'base',\n },\n services,\n endpoints: {\n services: '/services',\n execute: '/execute',\n health: '/health',\n },\n payment: {\n protocol: 'x402',\n version: X402_VERSION,\n network: this.networkId,\n schemes: ['exact'],\n mainnet: this.useMainnet,\n },\n });\n }\n\n /**\n * GET /services - List available services\n */\n private handleGetServices(res: ServerResponse): void {\n const services = this.manifest.services.map(s => ({\n id: s.id,\n name: s.name,\n description: s.description,\n price: s.price,\n currency: s.currency,\n acceptedCurrencies: getAcceptedCurrencies(s),\n input: s.input,\n output: s.output,\n available: this.skills.has(s.id),\n }));\n\n const selection = this.registry.getSelection();\n \n this.sendJson(res, 200, {\n provider: this.manifest.provider,\n services,\n x402: {\n version: X402_VERSION,\n network: this.networkId,\n schemes: ['exact'],\n facilitators: {\n primary: selection.primary,\n fallback: selection.fallback,\n strategy: selection.strategy,\n },\n mainnet: this.useMainnet,\n },\n });\n }\n\n /**\n * GET /health - Health check endpoint\n */\n private async handleHealthCheck(res: ServerResponse): Promise<void> {\n const facilitatorHealth = await this.registry.healthCheckAll();\n \n const allHealthy = Object.values(facilitatorHealth).every(h => h.healthy);\n \n this.sendJson(res, allHealthy ? 200 : 503, {\n status: allHealthy ? 'healthy' : 'degraded',\n network: this.networkId,\n facilitators: facilitatorHealth,\n services: this.manifest.services.length,\n registered: this.skills.size,\n });\n }\n\n /**\n * POST /execute - Execute service with x402 payment\n */\n private async handleExecute(\n body: any,\n paymentHeader: string | undefined,\n res: ServerResponse\n ): Promise<void> {\n const { service, params } = body;\n\n if (!service) {\n return this.sendJson(res, 400, { error: 'Missing service' });\n }\n\n const skill = this.skills.get(service);\n if (!skill) {\n return this.sendJson(res, 404, { error: `Service '${service}' not found or not registered` });\n }\n\n // Validate required params\n for (const [key, field] of Object.entries(skill.config.input)) {\n if (field.required && (!params || params[key] === undefined)) {\n return this.sendJson(res, 400, { error: `Missing required param: ${key}` });\n }\n }\n\n // If no payment header, return 402 with payment requirements\n if (!paymentHeader) {\n return this.sendPaymentRequired(skill.config, res);\n }\n\n // Parse payment payload\n let payment: X402PaymentPayload;\n try {\n const decoded = Buffer.from(paymentHeader, 'base64').toString('utf-8');\n payment = JSON.parse(decoded);\n } catch {\n return this.sendJson(res, 400, { error: 'Invalid X-Payment header' });\n }\n\n // Validate basic payment fields\n const validation = this.validatePayment(payment, skill.config);\n if (!validation.valid) {\n return this.sendJson(res, 402, { error: validation.error });\n }\n\n // Detect which token is being used\n const paymentToken = this.detectPaymentToken(payment);\n if (paymentToken && !this.isTokenAccepted(skill.config, paymentToken)) {\n const accepted = getAcceptedCurrencies(skill.config);\n return this.sendJson(res, 402, { \n error: `Token ${paymentToken} not accepted. Accepted: ${accepted.join(', ')}` \n });\n }\n\n // Auto-detect chain from payment header (key insight: client specifies chain via --chain flag)\n // payment.network contains \"eip155:8453\" (base) or \"eip155:84532\" (base_sepolia) etc.\n // This allows provider to serve both mainnet and testnet without separate configuration\n const paymentNetwork = payment.accepted?.network || payment.network || this.networkId;\n const paymentWallet = this.getWalletForNetwork(paymentNetwork);\n\n // Build requirements for facilitator using the detected token and network\n const requirements = this.buildPaymentRequirements(skill.config, paymentNetwork, paymentWallet, paymentToken);\n\n // Verify payment with facilitator (via registry)\n console.log(`[MoltsPay] Verifying payment on ${paymentNetwork}...`);\n const verifyResult = await this.registry.verify(payment, requirements);\n if (!verifyResult.valid) {\n return this.sendJson(res, 402, { \n error: `Payment verification failed: ${verifyResult.error}`,\n facilitator: verifyResult.facilitator,\n });\n }\n console.log(`[MoltsPay] Verified by ${verifyResult.facilitator}`);\n\n // Execute skill FIRST (pay-for-success) with timeout\n const timeoutSeconds = parseInt(process.env.SKILL_TIMEOUT_SECONDS || '1200');\n console.log(`[MoltsPay] Executing skill: ${service} (timeout: ${timeoutSeconds}s)`);\n let result: any;\n try {\n result = await Promise.race([\n skill.handler(params || {}),\n new Promise((_, reject) => \n setTimeout(() => reject(new Error(`Skill timeout after ${timeoutSeconds}s`)), timeoutSeconds * 1000)\n )\n ]);\n } catch (err: any) {\n console.error('[MoltsPay] Skill execution failed:', err.message);\n return this.sendJson(res, 500, {\n error: 'Service execution failed',\n message: err.message,\n });\n }\n\n // Skill succeeded - now settle payment with facilitator\n console.log(`[MoltsPay] Skill succeeded, settling payment...`);\n let settlement: any = null;\n try {\n settlement = await this.registry.settle(payment, requirements);\n console.log(`[MoltsPay] Payment settled by ${settlement.facilitator}: ${settlement.transaction || 'pending'}`);\n } catch (err: any) {\n console.error('[MoltsPay] Settlement failed:', err.message);\n }\n\n // Build response\n const responseHeaders: Record<string, string> = {};\n if (settlement?.success) {\n const responsePayload = {\n success: true,\n transaction: settlement.transaction,\n network: payment.network || payment.accepted?.network,\n facilitator: settlement.facilitator,\n };\n responseHeaders[PAYMENT_RESPONSE_HEADER] = Buffer.from(\n JSON.stringify(responsePayload)\n ).toString('base64');\n }\n\n this.sendJson(res, 200, {\n success: true,\n result,\n payment: settlement?.success \n ? { transaction: settlement.transaction, status: 'settled', facilitator: settlement.facilitator }\n : { status: 'pending' },\n }, responseHeaders);\n }\n\n /**\n * Handle MPP (Machine Payments Protocol) request\n * Supports both x402 and MPP protocols on service endpoints\n */\n private async handleMPPRequest(\n skill: RegisteredSkill,\n body: any,\n authHeader: string | undefined,\n x402Header: string | undefined,\n res: ServerResponse\n ): Promise<void> {\n const config = skill.config;\n const params = body || {};\n\n // Check for x402 payment header first (backward compatibility)\n if (x402Header) {\n return await this.handleExecute({ service: config.id, params }, x402Header, res);\n }\n\n // Check for MPP payment credential\n if (authHeader && authHeader.toLowerCase().startsWith('payment ')) {\n return await this.handleMPPPayment(skill, params, authHeader, res);\n }\n\n // No payment provided - return 402 with both x402 and MPP headers\n return this.sendMPPPaymentRequired(config, res);\n }\n\n /**\n * Handle MPP payment verification and service execution\n */\n private async handleMPPPayment(\n skill: RegisteredSkill,\n params: any,\n authHeader: string,\n res: ServerResponse\n ): Promise<void> {\n const config = skill.config;\n\n // Parse MPP credential: \"Payment <base64>\"\n const credentialMatch = authHeader.match(/Payment\\s+(.+)/i);\n if (!credentialMatch) {\n return this.sendJson(res, 400, { error: 'Invalid Authorization header format' });\n }\n\n let mppCredential: {\n challenge: {\n id: string;\n realm: string;\n method: string;\n intent: string;\n request: any;\n };\n payload: {\n hash?: string;\n signature?: string;\n type: 'hash' | 'transaction';\n };\n source?: string;\n };\n \n try {\n // mppx uses base64url encoding without padding\n const base64 = credentialMatch[1].replace(/-/g, '+').replace(/_/g, '/');\n const decoded = Buffer.from(base64, 'base64').toString('utf-8');\n mppCredential = JSON.parse(decoded);\n } catch (err) {\n console.error('[MoltsPay] Failed to parse MPP credential:', err);\n return this.sendJson(res, 400, { error: 'Invalid payment credential encoding' });\n }\n\n // Extract transaction hash from payload\n let txHash: string | undefined;\n if (mppCredential.payload?.type === 'hash' && mppCredential.payload?.hash) {\n txHash = mppCredential.payload.hash;\n } else if (mppCredential.payload?.type === 'transaction') {\n // For 'transaction' type, server would need to submit the signed tx\n // For now, we only support 'hash' type (push mode)\n return this.sendJson(res, 400, { \n error: 'Transaction type not supported. Please use push mode (hash type).' \n });\n }\n\n if (!txHash) {\n return this.sendJson(res, 400, { error: 'Missing transaction hash in credential' });\n }\n\n // Extract chainId from challenge or source\n let chainId = mppCredential.challenge?.request?.methodDetails?.chainId;\n if (!chainId && mppCredential.source) {\n const chainMatch = mppCredential.source.match(/eip155:(\\d+)/);\n if (chainMatch) chainId = parseInt(chainMatch[1], 10);\n }\n chainId = chainId || 42431; // Default to Tempo Moderato\n\n // Determine network from chainId\n const network = `eip155:${chainId}`;\n\n if (!this.isNetworkAccepted(network)) {\n return this.sendJson(res, 402, { \n error: `Network not accepted: ${network}` \n });\n }\n\n // Build requirements for verification\n const requirements = this.buildPaymentRequirements(\n config,\n network,\n this.getWalletForNetwork(network),\n 'USDC'\n );\n\n // Create x402-compatible payload for facilitator\n const paymentPayload: X402PaymentPayload = {\n x402Version: X402_VERSION,\n scheme: 'exact',\n network,\n payload: {\n txHash,\n chainId,\n },\n };\n\n console.log(`[MoltsPay] Verifying MPP payment: txHash=${txHash}, chainId=${chainId}`);\n\n // Verify payment using facilitator registry\n const verification = await this.registry.verify(paymentPayload, requirements);\n \n if (!verification.valid) {\n return this.sendJson(res, 402, { \n error: `Payment verification failed: ${verification.error}` \n });\n }\n\n console.log(`[MoltsPay] Payment verified! Executing service: ${config.id}`);\n\n // Execute the skill\n let result: any;\n try {\n result = await skill.handler(params);\n } catch (err: any) {\n console.error(`[MoltsPay] Skill execution error:`, err);\n return this.sendJson(res, 500, { \n error: `Service execution failed: ${err.message}` \n });\n }\n\n // Build receipt\n const receipt = {\n success: true,\n txHash,\n network,\n facilitator: verification.facilitator,\n };\n const receiptEncoded = Buffer.from(JSON.stringify(receipt)).toString('base64');\n\n // Return success with MPP receipt header\n res.writeHead(200, {\n 'Content-Type': 'application/json',\n [MPP_RECEIPT_HEADER]: receiptEncoded,\n });\n res.end(JSON.stringify({\n success: true,\n result,\n payment: {\n txHash,\n status: 'verified',\n facilitator: verification.facilitator,\n },\n }, null, 2));\n }\n\n /**\n * Return 402 with both x402 and MPP payment requirements\n */\n private sendMPPPaymentRequired(config: ServiceConfig, res: ServerResponse): void {\n const acceptedTokens = getAcceptedCurrencies(config);\n const providerChains = this.getProviderChains();\n \n // === x402 format (existing) ===\n const accepts: X402PaymentRequirements[] = [];\n for (const chainConfig of providerChains) {\n for (const token of acceptedTokens) {\n if (chainConfig.tokens.includes(token)) {\n accepts.push(this.buildPaymentRequirements(config, chainConfig.network, chainConfig.wallet, token));\n }\n }\n }\n\n const x402PaymentRequired = {\n x402Version: X402_VERSION,\n accepts,\n acceptedCurrencies: acceptedTokens,\n resource: {\n url: `/${config.id}`,\n description: `${config.name} - $${config.price} ${config.currency}`,\n },\n };\n const x402Encoded = Buffer.from(JSON.stringify(x402PaymentRequired)).toString('base64');\n\n // === MPP format ===\n // Find Tempo chain if available\n const tempoChain = providerChains.find(c => c.network === 'eip155:42431');\n \n let mppWwwAuth = '';\n if (tempoChain) {\n const challengeId = this.generateChallengeId();\n const amountInUnits = Math.floor(config.price * 1e6).toString();\n const tokenAddress = TOKEN_ADDRESSES['eip155:42431']?.USDC || '0x20c0000000000000000000000000000000000000';\n \n const mppRequest = {\n amount: amountInUnits,\n currency: tokenAddress,\n methodDetails: {\n chainId: 42431,\n feePayer: true,\n },\n recipient: tempoChain.wallet,\n };\n const mppRequestEncoded = Buffer.from(JSON.stringify(mppRequest)).toString('base64');\n \n const expiresAt = new Date(Date.now() + 5 * 60 * 1000).toISOString();\n \n mppWwwAuth = `Payment id=\"${challengeId}\", realm=\"${this.manifest.provider.name}\", method=\"tempo\", intent=\"charge\", request=\"${mppRequestEncoded}\", description=\"${config.name}\", expires=\"${expiresAt}\"`;\n }\n\n // Build response headers\n const headers: Record<string, string> = {\n 'Content-Type': 'application/problem+json',\n [PAYMENT_REQUIRED_HEADER]: x402Encoded,\n };\n \n if (mppWwwAuth) {\n headers[MPP_WWW_AUTH_HEADER] = mppWwwAuth;\n }\n\n res.writeHead(402, headers);\n res.end(JSON.stringify({\n type: 'https://paymentauth.org/problems/payment-required',\n title: 'Payment Required',\n status: 402,\n detail: `Payment is required (${config.name}).`,\n service: config.id,\n price: config.price,\n currency: config.currency,\n acceptedCurrencies: acceptedTokens,\n }, null, 2));\n }\n\n /**\n * Generate a unique challenge ID for MPP\n */\n private generateChallengeId(): string {\n const bytes = new Uint8Array(24);\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = Math.floor(Math.random() * 256);\n }\n return Buffer.from(bytes).toString('base64url');\n }\n\n /**\n * Return 402 with x402 payment requirements (v2 format)\n * Includes requirements for all chains and all accepted currencies\n */\n private sendPaymentRequired(config: ServiceConfig, res: ServerResponse): void {\n const acceptedTokens = getAcceptedCurrencies(config);\n const providerChains = this.getProviderChains();\n \n // Build requirements for each chain x token combination\n const accepts: X402PaymentRequirements[] = [];\n for (const chainConfig of providerChains) {\n for (const token of acceptedTokens) {\n // Only add if this chain supports this token\n if (chainConfig.tokens.includes(token)) {\n accepts.push(this.buildPaymentRequirements(config, chainConfig.network, chainConfig.wallet, token));\n }\n }\n }\n\n // Get list of accepted chains for response\n const acceptedChains = providerChains.map(c => {\n // Convert network ID to chain name for readability\n if (c.network === 'eip155:8453') return 'base';\n if (c.network === 'eip155:137') return 'polygon';\n return c.network;\n });\n\n const paymentRequired = {\n x402Version: X402_VERSION,\n accepts,\n acceptedCurrencies: acceptedTokens,\n acceptedChains,\n resource: {\n url: `/execute?service=${config.id}`,\n description: `${config.name} - $${config.price} ${config.currency}`,\n mimeType: 'application/json',\n },\n };\n\n const encoded = Buffer.from(JSON.stringify(paymentRequired)).toString('base64');\n\n res.writeHead(402, {\n 'Content-Type': 'application/json',\n [PAYMENT_REQUIRED_HEADER]: encoded,\n });\n res.end(JSON.stringify({\n error: 'Payment required',\n message: `Service requires $${config.price} ${config.currency}`,\n acceptedCurrencies: acceptedTokens,\n acceptedChains,\n x402: paymentRequired,\n }, null, 2));\n }\n\n /**\n * Basic payment validation\n */\n private validatePayment(\n payment: X402PaymentPayload,\n config: ServiceConfig\n ): { valid: boolean; error?: string } {\n if (payment.x402Version !== X402_VERSION) {\n return { valid: false, error: `Unsupported x402 version: ${payment.x402Version}` };\n }\n\n const scheme = payment.accepted?.scheme || payment.scheme;\n const network = payment.accepted?.network || payment.network || this.networkId;\n\n if (scheme !== 'exact') {\n return { valid: false, error: `Unsupported scheme: ${scheme}` };\n }\n\n // Check if payment network is one of our accepted networks\n if (!this.isNetworkAccepted(network)) {\n const acceptedChains = this.getProviderChains().map(c => c.network).join(', ');\n return { valid: false, error: `Network not accepted: ${network}. Accepted: ${acceptedChains}` };\n }\n\n return { valid: true };\n }\n\n /**\n * Build payment requirements for facilitator\n * Now supports multi-chain: takes network and wallet as parameters\n */\n private buildPaymentRequirements(\n config: ServiceConfig, \n network?: string, \n wallet?: string,\n token?: string\n ): X402PaymentRequirements {\n const amountInUnits = Math.floor(config.price * 1e6).toString();\n const acceptedTokens = getAcceptedCurrencies(config);\n \n // Use specified values or defaults\n const selectedNetwork = network || this.networkId;\n const selectedWallet = wallet || this.manifest.provider.wallet;\n const selectedToken = token && acceptedTokens.includes(token) ? token : acceptedTokens[0];\n \n const tokenAddresses = TOKEN_ADDRESSES[selectedNetwork] || {};\n const tokenAddress = tokenAddresses[selectedToken];\n const tokenDomain = getTokenDomain(selectedNetwork, selectedToken);\n\n return {\n scheme: 'exact',\n network: selectedNetwork,\n asset: tokenAddress,\n amount: amountInUnits,\n payTo: selectedWallet,\n maxTimeoutSeconds: 300,\n extra: tokenDomain,\n };\n }\n\n /**\n * Detect which token is being used in the payment\n * Checks across all supported networks\n */\n private detectPaymentToken(payment: X402PaymentPayload): string | undefined {\n const asset = payment.accepted?.asset || (payment.payload as any)?.asset;\n if (!asset) return undefined;\n\n // Get payment network to check correct token addresses\n const paymentNetwork = payment.accepted?.network || payment.network || this.networkId;\n const tokenAddresses = TOKEN_ADDRESSES[paymentNetwork] || {};\n \n for (const [symbol, address] of Object.entries(tokenAddresses)) {\n if (address && (address as string).toLowerCase() === asset.toLowerCase()) {\n return symbol;\n }\n }\n return undefined;\n }\n\n /**\n * Check if payment token is accepted for service\n */\n private isTokenAccepted(config: ServiceConfig, token: string): boolean {\n const accepted = getAcceptedCurrencies(config);\n return accepted.includes(token);\n }\n\n private async readBody(req: IncomingMessage): Promise<any> {\n return new Promise((resolve, reject) => {\n let body = '';\n req.on('data', chunk => body += chunk);\n req.on('end', () => {\n try {\n resolve(body ? JSON.parse(body) : {});\n } catch {\n reject(new Error('Invalid JSON'));\n }\n });\n req.on('error', reject);\n });\n }\n\n private sendJson(\n res: ServerResponse, \n status: number, \n data: any,\n extraHeaders?: Record<string, string>\n ): void {\n const headers: Record<string, string> = { 'Content-Type': 'application/json' };\n if (extraHeaders) {\n Object.assign(headers, extraHeaders);\n }\n res.writeHead(status, headers);\n res.end(JSON.stringify(data, null, 2));\n }\n\n /**\n * Check if IP is allowed for /proxy endpoint\n */\n private isProxyAllowed(clientIP: string): boolean {\n const allowedIPs = process.env.PROXY_ALLOWED_IPS?.split(',').map(ip => ip.trim()) || [];\n \n // If no whitelist configured, deny all (secure by default)\n if (allowedIPs.length === 0) {\n console.log(`[MoltsPay] /proxy denied: no PROXY_ALLOWED_IPS configured`);\n return false;\n }\n \n // Normalize IPv6 localhost\n const normalizedIP = clientIP === '::1' ? '127.0.0.1' : clientIP.replace('::ffff:', '');\n \n const allowed = allowedIPs.includes(normalizedIP) || allowedIPs.includes(clientIP);\n if (!allowed) {\n console.log(`[MoltsPay] /proxy denied for IP: ${clientIP} (normalized: ${normalizedIP})`);\n }\n return allowed;\n }\n\n /**\n * POST /proxy - Handle payment for external services (moltspay-creators)\n * \n * This endpoint allows other services to delegate x402 payment handling.\n * It does NOT execute any skill - just handles payment verification/settlement.\n * \n * Request body:\n * { wallet, amount, currency, chain, memo, serviceId, description }\n * \n * Without X-Payment header: returns 402 with payment requirements\n * With X-Payment header: verifies payment and returns result\n */\n private async handleProxy(\n body: any,\n paymentHeader: string | undefined,\n res: ServerResponse\n ): Promise<void> {\n const { wallet, amount, currency, chain, memo, serviceId, description } = body;\n\n // Validate required fields\n if (!wallet || !amount) {\n return this.sendJson(res, 400, { error: 'Missing required fields: wallet, amount' });\n }\n\n // Validate wallet format\n if (!/^0x[a-fA-F0-9]{40}$/.test(wallet)) {\n return this.sendJson(res, 400, { error: 'Invalid wallet address format' });\n }\n\n // Validate amount\n const amountNum = parseFloat(amount);\n if (isNaN(amountNum) || amountNum <= 0) {\n return this.sendJson(res, 400, { error: 'Invalid amount' });\n }\n \n // Validate chain if provided\n const supportedChains = ['base', 'polygon', 'base_sepolia'];\n if (chain && !supportedChains.includes(chain)) {\n return this.sendJson(res, 400, { error: `Unsupported chain: ${chain}. Supported: ${supportedChains.join(', ')}` });\n }\n\n // Build a synthetic service config for payment\n const proxyConfig: ServiceConfig = {\n id: serviceId || 'proxy',\n name: description || 'Proxy Payment',\n description: description || '',\n price: amountNum,\n currency: currency || 'USDC',\n function: '', // Not used\n input: {},\n output: {},\n };\n\n // Build payment requirements with the provided wallet and chain\n const requirements = this.buildProxyPaymentRequirements(proxyConfig, wallet, currency, chain);\n\n // If no payment header, return 402 with payment requirements\n if (!paymentHeader) {\n return this.sendProxyPaymentRequired(proxyConfig, wallet, memo, chain, res);\n }\n\n // Parse payment payload\n let payment: X402PaymentPayload;\n try {\n const decoded = Buffer.from(paymentHeader, 'base64').toString('utf-8');\n payment = JSON.parse(decoded);\n } catch {\n return this.sendJson(res, 400, { error: 'Invalid X-Payment header' });\n }\n\n // Validate basic payment fields\n if (payment.x402Version !== X402_VERSION) {\n return this.sendJson(res, 402, { error: `Unsupported x402 version: ${payment.x402Version}` });\n }\n\n const scheme = payment.accepted?.scheme || payment.scheme;\n const network = payment.accepted?.network || payment.network;\n\n if (scheme !== 'exact') {\n return this.sendJson(res, 402, { error: `Unsupported scheme: ${scheme}` });\n }\n\n // Validate network matches requested chain (or default to provider's network)\n const expectedNetwork = chain ? (CHAIN_TO_NETWORK[chain] || this.networkId) : this.networkId;\n if (network !== expectedNetwork) {\n return this.sendJson(res, 402, { error: `Network mismatch: expected ${expectedNetwork}, got ${network}` });\n }\n\n // Verify payment with facilitator\n console.log(`[MoltsPay] /proxy: Verifying payment for ${wallet}...`);\n const verifyResult = await this.registry.verify(payment, requirements);\n if (!verifyResult.valid) {\n return this.sendJson(res, 402, { \n success: false,\n error: `Payment verification failed: ${verifyResult.error}`,\n facilitator: verifyResult.facilitator,\n });\n }\n console.log(`[MoltsPay] /proxy: Verified by ${verifyResult.facilitator}`);\n\n // Check if execution requested\n const { execute, service, params } = body;\n \n // If execute requested, run skill BEFORE settling (pay on success)\n if (execute && service) {\n console.log(`[MoltsPay] /proxy: Executing skill first (pay on success): ${service}`);\n const skill = this.skills.get(service);\n if (!skill) {\n // Service not found - don't settle, return error\n console.log(`[MoltsPay] /proxy: Service not found: ${service} - NOT settling`);\n return this.sendJson(res, 404, {\n success: false,\n paymentSettled: false,\n error: `Service not found: ${service}`,\n });\n }\n\n // Execute skill first (with timeout)\n const timeoutSeconds = parseInt(process.env.SKILL_TIMEOUT_SECONDS || '1200');\n let result: any;\n try {\n result = await Promise.race([\n skill.handler(params || {}),\n new Promise((_, reject) => \n setTimeout(() => reject(new Error(`Skill timeout after ${timeoutSeconds}s`)), timeoutSeconds * 1000)\n )\n ]);\n console.log(`[MoltsPay] /proxy: Skill succeeded, now settling payment...`);\n } catch (err: any) {\n // Skill failed or timeout - don't settle, client keeps their money\n console.error(`[MoltsPay] /proxy: Skill failed: ${err.message} - NOT settling`);\n return this.sendJson(res, 500, {\n success: false,\n paymentSettled: false,\n error: `Service execution failed: ${err.message}`,\n });\n }\n\n // Skill succeeded - now settle payment\n let settlement: any = null;\n try {\n settlement = await this.registry.settle(payment, requirements);\n console.log(`[MoltsPay] /proxy: Payment settled by ${settlement.facilitator}: ${settlement.transaction || 'pending'}`);\n } catch (err: any) {\n console.error('[MoltsPay] /proxy: Settlement failed:', err.message);\n // Skill succeeded but settlement failed - return result anyway with warning\n return this.sendJson(res, 200, {\n success: true,\n verified: true,\n settled: false,\n settlementError: err.message,\n from: (payment.payload as any)?.authorization?.from, // Buyer's wallet address\n paidTo: wallet,\n amount: amountNum,\n currency: currency || 'USDC',\n memo,\n result,\n });\n }\n\n return this.sendJson(res, 200, {\n success: true,\n verified: true,\n settled: settlement?.success || false,\n txHash: settlement?.transaction,\n from: (payment.payload as any)?.authorization?.from, // Buyer's wallet address\n paidTo: wallet,\n amount: amountNum,\n currency: currency || 'USDC',\n facilitator: settlement?.facilitator,\n memo,\n result,\n });\n }\n\n // No execution requested - settle immediately (payment-only mode)\n console.log(`[MoltsPay] /proxy: Settling payment (no execution)...`);\n let settlement: any = null;\n try {\n settlement = await this.registry.settle(payment, requirements);\n console.log(`[MoltsPay] /proxy: Payment settled by ${settlement.facilitator}: ${settlement.transaction || 'pending'}`);\n } catch (err: any) {\n console.error('[MoltsPay] /proxy: Settlement failed:', err.message);\n return this.sendJson(res, 500, {\n success: false,\n error: `Settlement failed: ${err.message}`,\n });\n }\n\n // Return success (payment only, no execution)\n this.sendJson(res, 200, {\n success: true,\n verified: true,\n settled: settlement?.success || false,\n txHash: settlement?.transaction,\n from: (payment.payload as any)?.authorization?.from, // Buyer's wallet address\n paidTo: wallet,\n amount: amountNum,\n currency: currency || 'USDC',\n facilitator: settlement?.facilitator,\n memo,\n });\n }\n\n /**\n * Build payment requirements for proxy endpoint (uses provided wallet)\n */\n private buildProxyPaymentRequirements(config: ServiceConfig, wallet: string, token?: string, chain?: string): X402PaymentRequirements {\n const amountInUnits = Math.floor(config.price * 1e6).toString();\n const acceptedTokens = getAcceptedCurrencies(config);\n \n // Determine network from chain parameter or use default\n const networkId = chain ? (CHAIN_TO_NETWORK[chain] || this.networkId) : this.networkId;\n \n // Use specified token or default to first accepted\n const selectedToken = token && acceptedTokens.includes(token) ? token : acceptedTokens[0];\n const tokenAddresses = TOKEN_ADDRESSES[networkId] || TOKEN_ADDRESSES[this.networkId] || {};\n const tokenAddress = tokenAddresses[selectedToken];\n const tokenDomain = getTokenDomain(networkId, selectedToken);\n\n return {\n scheme: 'exact',\n network: networkId,\n asset: tokenAddress,\n amount: amountInUnits,\n payTo: wallet, // Use provided wallet, not manifest\n maxTimeoutSeconds: 300,\n extra: tokenDomain,\n };\n }\n\n /**\n * Return 402 with x402 payment requirements for proxy endpoint\n */\n private sendProxyPaymentRequired(\n config: ServiceConfig, \n wallet: string,\n memo: string | undefined,\n chain: string | undefined,\n res: ServerResponse\n ): void {\n const requirements = this.buildProxyPaymentRequirements(config, wallet, config.currency, chain);\n\n const paymentRequired = {\n x402Version: X402_VERSION,\n accepts: [requirements],\n resource: {\n url: `/proxy`,\n description: `${config.name} - $${config.price} ${config.currency}`,\n mimeType: 'application/json',\n memo,\n },\n };\n\n const encoded = Buffer.from(JSON.stringify(paymentRequired)).toString('base64');\n\n res.writeHead(402, {\n 'Content-Type': 'application/json',\n [PAYMENT_REQUIRED_HEADER]: encoded,\n });\n res.end(JSON.stringify({\n error: 'Payment required',\n message: `Payment requires $${config.price} ${config.currency}`,\n x402: paymentRequired,\n }, null, 2));\n }\n}\n","/**\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","/**\n * MoltsPay Client - Pay for AI Agent services\n * \n * Uses x402 protocol for gasless, pay-for-success payments.\n * \n * Usage:\n * const client = new MoltsPayClient(); // Loads from ~/.moltspay/\n * const services = await client.getServices('http://provider:3000');\n * const result = await client.pay('http://provider:3000', 'text-to-video', { prompt: '...' });\n */\n\nimport { existsSync, readFileSync, writeFileSync, mkdirSync, statSync, chmodSync } from 'fs';\nimport { homedir } from 'os';\nimport { join } from 'path';\nimport { Wallet, ethers } from 'ethers';\nimport { getChain, type ChainName, type TokenSymbol } from '../chains/index.js';\nimport {\n ClientConfig,\n WalletData,\n ServicesResponse,\n MoltsPayClientOptions,\n} from './types.js';\n\nexport * from './types.js';\n\nexport interface PayOptions {\n /** Token to pay with (default: USDC, or auto-select based on balance) */\n token?: TokenSymbol;\n /** Auto-select token based on balance (default: false) */\n autoSelect?: boolean;\n /** Chain to pay on (base, polygon, or base_sepolia, default: base) */\n chain?: 'base' | 'polygon' | 'base_sepolia';\n}\n\n// x402 constants\nconst X402_VERSION = 2;\nconst PAYMENT_REQUIRED_HEADER = 'x-payment-required';\nconst PAYMENT_HEADER = 'x-payment';\n\ninterface X402PaymentRequirements {\n scheme: string;\n network: string;\n // v2 fields\n amount?: string;\n asset?: string;\n payTo?: string;\n maxTimeoutSeconds?: number;\n extra?: Record<string, unknown>;\n // v1 fields (legacy)\n maxAmountRequired?: string;\n resource?: string;\n description?: string;\n}\n\ninterface EIP3009Authorization {\n from: string;\n to: string;\n value: string;\n validAfter: string;\n validBefore: string;\n nonce: string;\n}\n\nconst DEFAULT_CONFIG: ClientConfig = {\n chain: 'base',\n limits: {\n maxPerTx: 100,\n maxPerDay: 1000,\n },\n};\n\nexport class MoltsPayClient {\n private configDir: string;\n private config: ClientConfig;\n private walletData: WalletData | null = null;\n private wallet: Wallet | null = null;\n private todaySpending: number = 0;\n private lastSpendingReset: number = 0;\n\n constructor(options: MoltsPayClientOptions = {}) {\n this.configDir = options.configDir || join(homedir(), '.moltspay');\n this.config = this.loadConfig();\n this.walletData = this.loadWallet();\n this.loadSpending(); // Load persisted spending data\n \n if (this.walletData) {\n this.wallet = new Wallet(this.walletData.privateKey);\n }\n }\n\n /**\n * Check if client is initialized (has wallet)\n */\n get isInitialized(): boolean {\n return this.wallet !== null;\n }\n\n /**\n * Get wallet address\n */\n get address(): string | null {\n return this.wallet?.address || null;\n }\n\n /**\n * Get current config\n */\n getConfig(): ClientConfig {\n return { ...this.config };\n }\n\n /**\n * Update config\n */\n updateConfig(updates: Partial<ClientConfig['limits']>): void {\n if (updates.maxPerTx !== undefined) {\n this.config.limits.maxPerTx = updates.maxPerTx;\n }\n if (updates.maxPerDay !== undefined) {\n this.config.limits.maxPerDay = updates.maxPerDay;\n }\n this.saveConfig();\n }\n\n /**\n * Get services from a provider\n */\n async getServices(serverUrl: string): Promise<ServicesResponse> {\n // Normalize URL - don't append /services if already present\n const normalizedUrl = serverUrl.replace(/\\/(services|api\\/services|registry\\/services)\\/?$/, '');\n \n // Try /services first (standard provider endpoint)\n const endpoints = ['/services', '/api/services', '/registry/services'];\n \n for (const endpoint of endpoints) {\n try {\n const res = await fetch(`${normalizedUrl}${endpoint}`);\n if (!res.ok) continue;\n \n const contentType = res.headers.get('content-type') || '';\n if (!contentType.includes('application/json')) continue;\n \n return await res.json() as ServicesResponse;\n } catch {\n continue;\n }\n }\n \n throw new Error(`Failed to get services: no valid endpoint found at ${normalizedUrl}`);\n }\n\n /**\n * Pay for a service and get the result (x402 protocol)\n * \n * This is GASLESS for the client - server pays gas to claim payment.\n * This is PAY-FOR-SUCCESS - payment only claimed if service succeeds.\n * \n * @param serverUrl - Server URL\n * @param service - Service ID\n * @param params - Service parameters\n * @param options - Payment options (token selection)\n */\n async pay(\n serverUrl: string,\n service: string,\n params: Record<string, any>,\n options: PayOptions = {}\n ): Promise<Record<string, any>> {\n if (!this.wallet || !this.walletData) {\n throw new Error('Client not initialized. Run: npx moltspay init');\n }\n\n // Step 1: Make initial request without payment\n console.log(`[MoltsPay] Requesting service: ${service}`);\n const requestBody: any = { service, params };\n if (options.chain) {\n requestBody.chain = options.chain;\n }\n const initialRes = await fetch(`${serverUrl}/execute`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(requestBody),\n });\n\n // If not 402, check for success or error\n if (initialRes.status !== 402) {\n const data = await initialRes.json() as any;\n if (initialRes.ok && data.result) {\n return data.result;\n }\n throw new Error(data.error || 'Unexpected response');\n }\n\n // Step 2: Parse payment requirements from 402 response\n const paymentRequiredHeader = initialRes.headers.get(PAYMENT_REQUIRED_HEADER);\n if (!paymentRequiredHeader) {\n throw new Error('Missing x-payment-required header');\n }\n\n let requirements: X402PaymentRequirements[];\n try {\n const decoded = Buffer.from(paymentRequiredHeader, 'base64').toString('utf-8');\n const parsed = JSON.parse(decoded);\n \n // Handle both v1 (array) and v2 (object with accepts) formats\n if (Array.isArray(parsed)) {\n // v1 format: direct array of requirements\n requirements = parsed;\n } else if (parsed.accepts && Array.isArray(parsed.accepts)) {\n // v2 format: { x402Version: 2, accepts: [...] }\n requirements = parsed.accepts;\n } else {\n // Single requirement object\n requirements = [parsed];\n }\n } catch {\n throw new Error('Invalid x-payment-required header');\n }\n\n // Helper to convert network ID to chain name\n const networkToChainName = (network: string): string | null => {\n const match = network.match(/^eip155:(\\d+)$/);\n if (!match) return null;\n const chainId = parseInt(match[1]);\n if (chainId === 8453) return 'base';\n if (chainId === 137) return 'polygon';\n if (chainId === 84532) return 'base_sepolia';\n return null;\n };\n\n // Get server's accepted chains\n const serverChains = requirements\n .map(r => networkToChainName(r.network))\n .filter((c): c is string => c !== null);\n\n // Determine which chain to use\n let chainName: ChainName;\n const userSpecifiedChain = options.chain;\n\n if (userSpecifiedChain) {\n // User specified --chain, validate it's accepted by server\n if (!serverChains.includes(userSpecifiedChain)) {\n throw new Error(\n `Server doesn't accept '${userSpecifiedChain}'.\\n` +\n `Server accepts: ${serverChains.join(', ')}`\n );\n }\n chainName = userSpecifiedChain as ChainName;\n } else {\n // No --chain provided\n if (serverChains.length === 1 && serverChains[0] === 'base') {\n // Only default to base if server ONLY accepts base\n chainName = 'base';\n } else {\n throw new Error(\n `Server accepts: ${serverChains.join(', ')}\\n` +\n `Please specify: --chain base, --chain polygon, or --chain base_sepolia`\n );\n }\n }\n\n const chain = getChain(chainName);\n const network = `eip155:${chain.chainId}`;\n const req = requirements.find(r => r.scheme === 'exact' && r.network === network);\n\n if (!req) {\n throw new Error(`Failed to find payment requirement for ${chainName}`);\n }\n\n // Step 3: Check limits\n // v2 uses 'amount', v1 uses 'maxAmountRequired'\n const amountRaw = req.amount || req.maxAmountRequired;\n if (!amountRaw) {\n throw new Error('Missing amount in payment requirements');\n }\n const amount = Number(amountRaw) / 1e6;\n this.checkLimits(amount);\n\n // Determine which token to use\n let token: TokenSymbol = options.token || 'USDC';\n \n // Auto-select token based on balance if requested\n if (options.autoSelect) {\n const balances = await this.getBalance();\n if (balances.usdc >= amount) {\n token = 'USDC';\n } else if (balances.usdt >= amount) {\n token = 'USDT';\n } else {\n throw new Error(`Insufficient balance: need $${amount}, have ${balances.usdc} USDC / ${balances.usdt} USDT`);\n }\n }\n\n // USDT does not support gasless transfers (no EIP-2612 permit)\n // It requires on-chain approve + transfer, meaning the user pays gas\n if (token === 'USDT') {\n const balances = await this.getBalance();\n if (balances.native < 0.0001) {\n throw new Error(\n `USDT requires ETH for gas (~$0.01 on Base). ` +\n `Your ETH balance: ${balances.native.toFixed(6)} ETH. ` +\n `Please add a small amount of ETH to your wallet, or use USDC (gasless).`\n );\n }\n console.log(`[MoltsPay] ⚠️ USDT requires gas (~$0.01). Proceeding with payment...`);\n } else {\n console.log(`[MoltsPay] Signing payment: $${amount} ${token} (gasless)`);\n }\n\n // Step 4: Sign EIP-3009 authorization (GASLESS - just signing)\n // payTo is the recipient address (v2 format)\n const payTo = req.payTo || req.resource; // fallback for v1 compatibility\n if (!payTo) {\n throw new Error('Missing payTo address in payment requirements');\n }\n \n // Use server's extra field for domain info (contains correct EIP-712 domain for the token on this network)\n const domainOverride = (req.extra && typeof req.extra === 'object' && req.extra.name) \n ? { name: req.extra.name as string, version: (req.extra.version as string) || '2' }\n : undefined;\n \n const authorization = await this.signEIP3009(payTo, amount, chain, token, domainOverride);\n\n // Get token-specific info for accepted field\n const tokenConfig = chain.tokens[token];\n\n // Step 5: Create x402 payment payload (v2 requires scheme, network, payload, AND accepted)\n // Use server's extra field if provided (contains correct EIP-712 domain for the token on this network)\n // Fall back to local config for backward compatibility\n const extra = (req.extra && typeof req.extra === 'object') \n ? req.extra \n : {\n name: (tokenConfig as any).eip712Name || 'USD Coin',\n version: '2',\n };\n \n const payload = {\n x402Version: X402_VERSION,\n scheme: 'exact',\n network,\n payload: authorization, // { authorization: {...}, signature: \"0x...\" }\n accepted: {\n scheme: 'exact',\n network,\n asset: tokenConfig.address,\n amount: amountRaw,\n payTo,\n maxTimeoutSeconds: req.maxTimeoutSeconds || 300,\n extra,\n },\n };\n const paymentHeader = Buffer.from(JSON.stringify(payload)).toString('base64');\n\n // Step 6: Retry with payment header\n console.log(`[MoltsPay] Sending request with payment...`);\n const paidRequestBody: any = { service, params };\n if (options.chain) {\n paidRequestBody.chain = options.chain;\n }\n const paidRes = await fetch(`${serverUrl}/execute`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n [PAYMENT_HEADER]: paymentHeader,\n },\n body: JSON.stringify(paidRequestBody),\n });\n\n const result = await paidRes.json() as any;\n\n if (!paidRes.ok) {\n throw new Error(result.error || 'Service execution failed');\n }\n\n // Update spending tracking\n this.recordSpending(amount);\n\n console.log(`[MoltsPay] Success! Payment: ${result.payment?.status || 'claimed'}`);\n \n return result.result;\n }\n\n /**\n * Sign EIP-3009 transferWithAuthorization (GASLESS)\n * This only signs - no on-chain transaction, no gas needed.\n * Supports both USDC and USDT.\n */\n private async signEIP3009(\n to: string,\n amount: number,\n chain: { chainId: number; tokens: Record<TokenSymbol, { address: string; decimals: number }> },\n token: TokenSymbol = 'USDC',\n domainOverride?: { name: string; version: string }\n ): Promise<{ authorization: EIP3009Authorization; signature: string }> {\n const validAfter = 0;\n const validBefore = Math.floor(Date.now() / 1000) + 3600; // 1 hour\n const nonce = ethers.hexlify(ethers.randomBytes(32));\n \n const tokenConfig = chain.tokens[token];\n const value = BigInt(Math.floor(amount * (10 ** tokenConfig.decimals))).toString();\n\n const authorization: EIP3009Authorization = {\n from: this.wallet!.address,\n to,\n value,\n validAfter: validAfter.toString(),\n validBefore: validBefore.toString(),\n nonce,\n };\n\n // EIP-712 domain - use server's domain info if provided (handles mainnet vs testnet differences)\n // Fall back to local token config for backward compatibility\n const tokenName = domainOverride?.name || (tokenConfig as any).eip712Name || (token === 'USDC' ? 'USD Coin' : 'Tether USD');\n const tokenVersion = domainOverride?.version || '2';\n const domain = {\n name: tokenName,\n version: tokenVersion,\n chainId: chain.chainId,\n verifyingContract: tokenConfig.address,\n };\n\n // EIP-3009 types\n const types = {\n TransferWithAuthorization: [\n { name: 'from', type: 'address' },\n { name: 'to', type: 'address' },\n { name: 'value', type: 'uint256' },\n { name: 'validAfter', type: 'uint256' },\n { name: 'validBefore', type: 'uint256' },\n { name: 'nonce', type: 'bytes32' },\n ],\n };\n\n const signature = await this.wallet!.signTypedData(domain, types, authorization);\n\n return { authorization, signature };\n }\n\n /**\n * Check spending limits\n */\n private checkLimits(amount: number): void {\n // Check per-tx limit\n if (amount > this.config.limits.maxPerTx) {\n throw new Error(\n `Amount $${amount} exceeds max per transaction ($${this.config.limits.maxPerTx})`\n );\n }\n\n // Reset daily spending if new day\n const today = new Date().setHours(0, 0, 0, 0);\n if (today > this.lastSpendingReset) {\n this.todaySpending = 0;\n this.lastSpendingReset = today;\n this.saveSpending(); // Persist reset\n }\n\n // Check daily limit\n if (this.todaySpending + amount > this.config.limits.maxPerDay) {\n throw new Error(\n `Would exceed daily limit ($${this.todaySpending} + $${amount} > $${this.config.limits.maxPerDay})`\n );\n }\n }\n\n /**\n * Record spending and persist to disk\n */\n private recordSpending(amount: number): void {\n this.todaySpending += amount;\n this.saveSpending();\n }\n\n // --- Config & Wallet Management ---\n\n private loadConfig(): ClientConfig {\n const configPath = join(this.configDir, 'config.json');\n if (existsSync(configPath)) {\n const content = readFileSync(configPath, 'utf-8');\n return { ...DEFAULT_CONFIG, ...JSON.parse(content) };\n }\n return { ...DEFAULT_CONFIG };\n }\n\n private saveConfig(): void {\n mkdirSync(this.configDir, { recursive: true });\n const configPath = join(this.configDir, 'config.json');\n writeFileSync(configPath, JSON.stringify(this.config, null, 2));\n }\n\n /**\n * Load spending data from disk\n */\n private loadSpending(): void {\n const spendingPath = join(this.configDir, 'spending.json');\n if (existsSync(spendingPath)) {\n try {\n const data = JSON.parse(readFileSync(spendingPath, 'utf-8'));\n const today = new Date().setHours(0, 0, 0, 0);\n \n // Only load if it's from today\n if (data.date && data.date === today) {\n this.todaySpending = data.amount || 0;\n this.lastSpendingReset = data.date;\n } else {\n // Data is from a previous day, reset\n this.todaySpending = 0;\n this.lastSpendingReset = today;\n }\n } catch {\n // Ignore parse errors, start fresh\n this.todaySpending = 0;\n this.lastSpendingReset = new Date().setHours(0, 0, 0, 0);\n }\n }\n }\n\n /**\n * Save spending data to disk\n */\n private saveSpending(): void {\n mkdirSync(this.configDir, { recursive: true });\n const spendingPath = join(this.configDir, 'spending.json');\n const data = {\n date: this.lastSpendingReset || new Date().setHours(0, 0, 0, 0),\n amount: this.todaySpending,\n updatedAt: Date.now(),\n };\n writeFileSync(spendingPath, JSON.stringify(data, null, 2));\n }\n\n private loadWallet(): WalletData | null {\n const walletPath = join(this.configDir, 'wallet.json');\n if (existsSync(walletPath)) {\n // Security check: warn and fix if permissions are too open\n try {\n const stats = statSync(walletPath);\n const mode = stats.mode & 0o777;\n if (mode !== 0o600) {\n console.warn(`[MoltsPay] WARNING: wallet.json has insecure permissions (${mode.toString(8)})`);\n console.warn(`[MoltsPay] Fixing permissions to 0600...`);\n chmodSync(walletPath, 0o600);\n }\n } catch (err) {\n // Ignore permission check errors on Windows\n }\n \n const content = readFileSync(walletPath, 'utf-8');\n return JSON.parse(content);\n }\n return null;\n }\n\n /**\n * Initialize a new wallet (called by CLI)\n */\n static init(\n configDir: string,\n options: { chain: string; maxPerTx: number; maxPerDay: number }\n ): { address: string; configDir: string } {\n mkdirSync(configDir, { recursive: true });\n\n // Create wallet\n const wallet = Wallet.createRandom();\n const walletData: WalletData = {\n address: wallet.address,\n privateKey: wallet.privateKey,\n createdAt: Date.now(),\n };\n\n // Save wallet with secure permissions (0o600 = owner read/write only)\n const walletPath = join(configDir, 'wallet.json');\n writeFileSync(walletPath, JSON.stringify(walletData, null, 2), { mode: 0o600 });\n\n // Save config\n const config: ClientConfig = {\n chain: options.chain,\n limits: {\n maxPerTx: options.maxPerTx,\n maxPerDay: options.maxPerDay,\n },\n };\n const configPath = join(configDir, 'config.json');\n writeFileSync(configPath, JSON.stringify(config, null, 2));\n\n return { address: wallet.address, configDir };\n }\n\n /**\n * Get wallet balance (USDC, USDT, and native token) on default chain\n */\n async getBalance(): Promise<{ usdc: number; usdt: number; native: number }> {\n if (!this.wallet) {\n throw new Error('Client not initialized');\n }\n\n let chain;\n try {\n chain = getChain(this.config.chain as ChainName);\n } catch {\n throw new Error(`Unknown chain: ${this.config.chain}`);\n }\n\n const provider = new ethers.JsonRpcProvider(chain.rpc);\n const tokenAbi = ['function balanceOf(address) view returns (uint256)'];\n\n // Get all balances in parallel\n const [nativeBalance, usdcBalance, usdtBalance] = await Promise.all([\n provider.getBalance(this.wallet.address),\n new ethers.Contract(chain.tokens.USDC.address, tokenAbi, provider).balanceOf(this.wallet.address),\n new ethers.Contract(chain.tokens.USDT.address, tokenAbi, provider).balanceOf(this.wallet.address),\n ]);\n\n return {\n usdc: parseFloat(ethers.formatUnits(usdcBalance, chain.tokens.USDC.decimals)),\n usdt: parseFloat(ethers.formatUnits(usdtBalance, chain.tokens.USDT.decimals)),\n native: parseFloat(ethers.formatEther(nativeBalance)),\n };\n }\n\n /**\n * Get wallet balances on all supported chains (Base + Polygon + Tempo)\n */\n async getAllBalances(): Promise<Record<string, { usdc: number; usdt: number; native: number; tempo?: { pathUSD: number; alphaUSD: number; betaUSD: number; thetaUSD: number } }>> {\n if (!this.wallet) {\n throw new Error('Client not initialized');\n }\n\n const supportedChains: ChainName[] = ['base', 'polygon', 'base_sepolia', 'tempo_moderato'];\n const tokenAbi = ['function balanceOf(address) view returns (uint256)'];\n const results: Record<string, { usdc: number; usdt: number; native: number; tempo?: { pathUSD: number; alphaUSD: number; betaUSD: number; thetaUSD: number } }> = {};\n\n // Tempo testnet token addresses\n const tempoTokens = {\n pathUSD: '0x20c0000000000000000000000000000000000000',\n alphaUSD: '0x20c0000000000000000000000000000000000001',\n betaUSD: '0x20c0000000000000000000000000000000000002',\n thetaUSD: '0x20c0000000000000000000000000000000000003',\n };\n\n // Query all chains in parallel\n await Promise.all(\n supportedChains.map(async (chainName) => {\n try {\n const chain = getChain(chainName);\n const provider = new ethers.JsonRpcProvider(chain.rpc);\n\n if (chainName === 'tempo_moderato') {\n // Tempo: fetch all 4 testnet tokens\n const [nativeBalance, pathUSD, alphaUSD, betaUSD, thetaUSD] = await Promise.all([\n provider.getBalance(this.wallet!.address),\n new ethers.Contract(tempoTokens.pathUSD, tokenAbi, provider).balanceOf(this.wallet!.address),\n new ethers.Contract(tempoTokens.alphaUSD, tokenAbi, provider).balanceOf(this.wallet!.address),\n new ethers.Contract(tempoTokens.betaUSD, tokenAbi, provider).balanceOf(this.wallet!.address),\n new ethers.Contract(tempoTokens.thetaUSD, tokenAbi, provider).balanceOf(this.wallet!.address),\n ]);\n\n results[chainName] = {\n usdc: parseFloat(ethers.formatUnits(pathUSD, 6)), // pathUSD as default USDC\n usdt: parseFloat(ethers.formatUnits(alphaUSD, 6)), // alphaUSD as default USDT\n native: parseFloat(ethers.formatEther(nativeBalance)),\n tempo: {\n pathUSD: parseFloat(ethers.formatUnits(pathUSD, 6)),\n alphaUSD: parseFloat(ethers.formatUnits(alphaUSD, 6)),\n betaUSD: parseFloat(ethers.formatUnits(betaUSD, 6)),\n thetaUSD: parseFloat(ethers.formatUnits(thetaUSD, 6)),\n },\n };\n } else {\n // Other chains: fetch USDC and USDT\n const [nativeBalance, usdcBalance, usdtBalance] = await Promise.all([\n provider.getBalance(this.wallet!.address),\n new ethers.Contract(chain.tokens.USDC.address, tokenAbi, provider).balanceOf(this.wallet!.address),\n new ethers.Contract(chain.tokens.USDT.address, tokenAbi, provider).balanceOf(this.wallet!.address),\n ]);\n\n results[chainName] = {\n usdc: parseFloat(ethers.formatUnits(usdcBalance, chain.tokens.USDC.decimals)),\n usdt: parseFloat(ethers.formatUnits(usdtBalance, chain.tokens.USDT.decimals)),\n native: parseFloat(ethers.formatEther(nativeBalance)),\n };\n }\n } catch (err) {\n // If chain query fails, show zeros\n results[chainName] = { usdc: 0, usdt: 0, native: 0 };\n }\n })\n );\n\n return results;\n }\n\n /**\n * Pay for a service using MPP (Machine Payments Protocol)\n * \n * This implements the MPP flow manually for EOA wallets:\n * 1. Request service → get 402 with WWW-Authenticate\n * 2. Parse payment requirements\n * 3. Execute transfer on Tempo chain\n * 4. Retry with transaction hash as credential\n * \n * @param url - Full URL of the MPP-enabled endpoint\n * @param options - Request options (body, headers)\n * @returns Response from the service\n */\n async payWithMPP(\n url: string,\n options: {\n body?: any;\n headers?: Record<string, string>;\n } = {}\n ): Promise<any> {\n if (!this.wallet || !this.walletData) {\n throw new Error('Client not initialized. Run: npx moltspay init');\n }\n\n // Dynamic imports for ESM-only packages\n const { privateKeyToAccount } = await import('viem/accounts');\n const { createWalletClient, createPublicClient, http } = await import('viem');\n const { tempoModerato } = await import('viem/chains');\n const { Actions } = await import('viem/tempo');\n\n // Get private key from wallet data\n const privateKey = this.walletData.privateKey as `0x${string}`;\n const account = privateKeyToAccount(privateKey);\n\n console.log(`[MoltsPay] Making MPP request to: ${url}`);\n console.log(`[MoltsPay] Using account: ${account.address}`);\n\n // Step 1: Initial request to get 402 with payment requirements\n const initResponse = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...options.headers,\n },\n body: options.body ? JSON.stringify(options.body) : undefined,\n });\n\n // If not 402, handle directly\n if (initResponse.status !== 402) {\n if (initResponse.ok) {\n return initResponse.json();\n }\n const errorText = await initResponse.text();\n throw new Error(`Request failed (${initResponse.status}): ${errorText}`);\n }\n\n // Step 2: Parse WWW-Authenticate header\n const wwwAuth = initResponse.headers.get('www-authenticate');\n if (!wwwAuth || !wwwAuth.toLowerCase().includes('payment')) {\n throw new Error('No WWW-Authenticate Payment challenge in 402 response');\n }\n\n console.log(`[MoltsPay] Got 402, parsing payment challenge...`);\n\n // Parse WWW-Authenticate: Payment id=\"...\", method=\"tempo\", request=\"...\"\n const parseAuthParam = (header: string, key: string): string | null => {\n const match = header.match(new RegExp(`${key}=\"([^\"]+)\"`, 'i'));\n return match ? match[1] : null;\n };\n\n const challengeId = parseAuthParam(wwwAuth, 'id');\n const method = parseAuthParam(wwwAuth, 'method');\n const realm = parseAuthParam(wwwAuth, 'realm');\n const requestB64 = parseAuthParam(wwwAuth, 'request');\n\n if (method !== 'tempo') {\n throw new Error(`Unsupported payment method: ${method}`);\n }\n\n if (!requestB64) {\n throw new Error('Missing request in WWW-Authenticate');\n }\n\n // Decode payment request\n const requestJson = Buffer.from(requestB64, 'base64').toString('utf-8');\n const paymentRequest = JSON.parse(requestJson);\n \n console.log(`[MoltsPay] Payment request:`, paymentRequest);\n\n const { amount, currency, recipient, methodDetails } = paymentRequest;\n const chainId = methodDetails?.chainId || 42431;\n\n // Step 3: Execute transfer on Tempo\n console.log(`[MoltsPay] Executing transfer on Tempo (chainId: ${chainId})...`);\n console.log(`[MoltsPay] Amount: ${amount}, To: ${recipient}`);\n\n // Create viem client for Tempo (with feeToken for gas-free transactions)\n const tempoChain = { ...tempoModerato, feeToken: currency as `0x${string}` };\n \n const publicClient = createPublicClient({\n chain: tempoChain,\n transport: http('https://rpc.moderato.tempo.xyz'),\n });\n\n const walletClient = createWalletClient({\n account,\n chain: tempoChain,\n transport: http('https://rpc.moderato.tempo.xyz'),\n });\n\n // Use viem's Tempo Actions for TIP-20 transfer\n const txHash = await Actions.token.transfer(walletClient, {\n to: recipient as `0x${string}`,\n amount: BigInt(amount),\n token: currency as `0x${string}`,\n });\n\n console.log(`[MoltsPay] Transaction sent: ${txHash}`);\n\n // Wait for confirmation\n console.log(`[MoltsPay] Waiting for confirmation...`);\n await publicClient.waitForTransactionReceipt({ hash: txHash });\n console.log(`[MoltsPay] Transaction confirmed!`);\n\n // Step 4: Build credential and retry\n const challenge = {\n id: challengeId,\n realm,\n method: 'tempo',\n intent: 'charge',\n request: paymentRequest,\n };\n\n const credential = {\n challenge,\n payload: { hash: txHash, type: 'hash' },\n source: `did:pkh:eip155:${chainId}:${account.address}`,\n };\n\n const credentialB64 = Buffer.from(JSON.stringify(credential))\n .toString('base64')\n .replace(/\\+/g, '-')\n .replace(/\\//g, '_')\n .replace(/=+$/, ''); // base64url without padding\n\n console.log(`[MoltsPay] Retrying with payment credential...`);\n\n // Retry with credential\n const paidResponse = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Payment ${credentialB64}`,\n ...options.headers,\n },\n body: options.body ? JSON.stringify(options.body) : undefined,\n });\n\n if (!paidResponse.ok) {\n const errorText = await paidResponse.text();\n throw new Error(`Payment verification failed (${paidResponse.status}): ${errorText}`);\n }\n\n console.log(`[MoltsPay] Payment verified! Service completed.`);\n return paidResponse.json();\n }\n}\n","/**\n * Wallet - Basic Custody Wallet\n * \n * Features:\n * - Query balance (USDC, USDT, ETH)\n * - Send token transfers (USDC or USDT)\n */\n\nimport { ethers } from 'ethers';\nimport { getChain, ERC20_ABI } from '../chains/index.js';\nimport type {\n ChainName,\n ChainConfig,\n WalletBalance,\n TransferResult,\n TokenSymbol,\n} from '../types/index.js';\n\nexport interface WalletConfig {\n chain?: ChainName;\n privateKey?: string;\n rpcUrl?: string;\n}\n\nexport class Wallet {\n readonly chain: ChainName;\n readonly chainConfig: ChainConfig;\n readonly address: string;\n \n private wallet: ethers.Wallet;\n private provider: ethers.JsonRpcProvider;\n private tokenContracts: Record<TokenSymbol, ethers.Contract>;\n\n constructor(config: WalletConfig = {}) {\n this.chain = config.chain || 'base_sepolia';\n this.chainConfig = getChain(this.chain);\n \n const privateKey = config.privateKey || process.env.PAYMENT_AGENT_PRIVATE_KEY;\n if (!privateKey) {\n throw new Error('privateKey is required. Set via config or PAYMENT_AGENT_PRIVATE_KEY env var.');\n }\n\n const rpcUrl = config.rpcUrl || this.chainConfig.rpc;\n this.provider = new ethers.JsonRpcProvider(rpcUrl);\n this.wallet = new ethers.Wallet(privateKey, this.provider);\n this.address = this.wallet.address;\n \n // Initialize token contracts\n this.tokenContracts = {\n USDC: new ethers.Contract(\n this.chainConfig.tokens.USDC.address,\n ERC20_ABI,\n this.wallet\n ),\n USDT: new ethers.Contract(\n this.chainConfig.tokens.USDT.address,\n ERC20_ABI,\n this.wallet\n ),\n };\n }\n\n /**\n * Get wallet balance for all tokens\n */\n async getBalance(): Promise<WalletBalance> {\n const [ethBalance, usdcBalance, usdtBalance] = await Promise.all([\n this.provider.getBalance(this.address),\n this.tokenContracts.USDC.balanceOf(this.address),\n this.tokenContracts.USDT.balanceOf(this.address),\n ]);\n\n return {\n address: this.address,\n eth: ethers.formatEther(ethBalance),\n usdc: (Number(usdcBalance) / 1e6).toFixed(2),\n usdt: (Number(usdtBalance) / 1e6).toFixed(2),\n chain: this.chain,\n };\n }\n\n /**\n * Send token transfer (USDC or USDT)\n * @param to - recipient address\n * @param amount - amount to send\n * @param token - token to send (default: USDC)\n */\n async transfer(to: string, amount: number, token: TokenSymbol = 'USDC'): Promise<TransferResult> {\n try {\n // Validate address\n to = ethers.getAddress(to);\n \n // Get token contract and config\n const tokenContract = this.tokenContracts[token];\n const tokenConfig = this.chainConfig.tokens[token];\n \n if (!tokenContract || !tokenConfig) {\n return {\n success: false,\n error: `Token ${token} not supported on ${this.chain}`,\n };\n }\n \n // Convert amount (both USDC and USDT have 6 decimals)\n const decimals = tokenConfig.decimals;\n const amountWei = BigInt(Math.floor(amount * (10 ** decimals)));\n\n // Check balance\n const balance = await tokenContract.balanceOf(this.address);\n if (BigInt(balance) < amountWei) {\n return {\n success: false,\n error: `Insufficient ${token} balance: ${Number(balance) / (10 ** decimals)} < ${amount}`,\n };\n }\n\n // Send transaction\n const tx = await tokenContract.transfer(to, amountWei);\n const receipt = await tx.wait();\n\n if (receipt.status === 1) {\n return {\n success: true,\n tx_hash: tx.hash,\n from: this.address,\n to,\n amount,\n token,\n gas_used: Number(receipt.gasUsed),\n block_number: receipt.blockNumber,\n explorer_url: `${this.chainConfig.explorerTx}${tx.hash}`,\n };\n } else {\n return {\n success: false,\n tx_hash: tx.hash,\n token,\n error: 'Transaction reverted',\n };\n }\n } catch (error) {\n return {\n success: false,\n token,\n error: (error as Error).message,\n };\n }\n }\n\n /**\n * Get ETH balance\n */\n async getEthBalance(): Promise<string> {\n const balance = await this.provider.getBalance(this.address);\n return ethers.formatEther(balance);\n }\n\n /**\n * Get token balance\n * @param token - token symbol (default: USDC)\n */\n async getTokenBalance(token: TokenSymbol = 'USDC'): Promise<string> {\n const tokenContract = this.tokenContracts[token];\n const tokenConfig = this.chainConfig.tokens[token];\n const balance = await tokenContract.balanceOf(this.address);\n return (Number(balance) / (10 ** tokenConfig.decimals)).toFixed(2);\n }\n\n /**\n * @deprecated Use getTokenBalance('USDC') instead\n */\n async getUsdcBalance(): Promise<string> {\n return this.getTokenBalance('USDC');\n }\n}\n","/**\n * createWallet - Create a new wallet for Agent\n * \n * Features:\n * - Generate new Ethereum wallet\n * - Securely store private key (encrypted or plaintext, depending on config)\n * - Return wallet address (never return private key)\n */\n\nimport { ethers } from 'ethers';\nimport { writeFileSync, readFileSync, existsSync, mkdirSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { createCipheriv, createDecipheriv, randomBytes, scryptSync } from 'crypto';\n\nexport interface CreateWalletOptions {\n /** Storage path, default ~/.moltspay/wallet.json */\n storagePath?: string;\n /** Encryption password (optional, plaintext if not provided) */\n password?: string;\n /** Wallet label/name */\n label?: string;\n /** Overwrite if wallet exists */\n overwrite?: boolean;\n}\n\nexport interface WalletData {\n address: string;\n label?: string;\n createdAt: string;\n encrypted: boolean;\n /** Encrypted or plaintext private key */\n privateKey: string;\n /** Encryption IV */\n iv?: string;\n /** Encryption salt */\n salt?: string;\n}\n\nexport interface CreateWalletResult {\n success: boolean;\n address?: string;\n storagePath?: string;\n error?: string;\n /** Whether newly created (false means loaded existing) */\n isNew?: boolean;\n}\n\nconst DEFAULT_STORAGE_DIR = join(process.env.HOME || '~', '.moltspay');\nconst DEFAULT_STORAGE_FILE = 'wallet.json';\n\n/**\n * Encrypt private key\n */\nfunction encryptPrivateKey(privateKey: string, password: string): { encrypted: string; iv: string; salt: string } {\n const salt = randomBytes(16);\n const key = scryptSync(password, salt, 32);\n const iv = randomBytes(16);\n \n const cipher = createCipheriv('aes-256-cbc', key, iv);\n let encrypted = cipher.update(privateKey, 'utf8', 'hex');\n encrypted += cipher.final('hex');\n \n return {\n encrypted,\n iv: iv.toString('hex'),\n salt: salt.toString('hex'),\n };\n}\n\n/**\n * Decrypt private key\n */\nfunction decryptPrivateKey(encrypted: string, password: string, iv: string, salt: string): string {\n const key = scryptSync(password, Buffer.from(salt, 'hex'), 32);\n const decipher = createDecipheriv('aes-256-cbc', key, Buffer.from(iv, 'hex'));\n \n let decrypted = decipher.update(encrypted, 'hex', 'utf8');\n decrypted += decipher.final('utf8');\n \n return decrypted;\n}\n\n/**\n * Create new wallet\n * \n * @example\n * ```typescript\n * // Create unencrypted wallet\n * const result = await createWallet();\n * console.log('Wallet address:', result.address);\n * \n * // Create encrypted wallet\n * const result = await createWallet({ password: 'mySecurePassword' });\n * \n * // Specify storage path\n * const result = await createWallet({ storagePath: './my-wallet.json' });\n * ```\n */\nexport function createWallet(options: CreateWalletOptions = {}): CreateWalletResult {\n const storagePath = options.storagePath || join(DEFAULT_STORAGE_DIR, DEFAULT_STORAGE_FILE);\n \n // Check if exists\n if (existsSync(storagePath) && !options.overwrite) {\n // Load existing wallet\n try {\n const existing = JSON.parse(readFileSync(storagePath, 'utf8')) as WalletData;\n return {\n success: true,\n address: existing.address,\n storagePath,\n isNew: false,\n };\n } catch (error) {\n return {\n success: false,\n error: `Failed to load existing wallet: ${(error as Error).message}`,\n };\n }\n }\n\n try {\n // Create new wallet\n const wallet = ethers.Wallet.createRandom();\n \n // Prepare storage data\n const walletData: WalletData = {\n address: wallet.address,\n label: options.label,\n createdAt: new Date().toISOString(),\n encrypted: !!options.password,\n privateKey: '',\n };\n\n if (options.password) {\n // Encrypted storage\n const { encrypted, iv, salt } = encryptPrivateKey(wallet.privateKey, options.password);\n walletData.privateKey = encrypted;\n walletData.iv = iv;\n walletData.salt = salt;\n } else {\n // Plaintext storage (not recommended, but convenient for testing/dev)\n walletData.privateKey = wallet.privateKey;\n }\n\n // Ensure directory exists\n const dir = dirname(storagePath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n\n // Write file\n writeFileSync(storagePath, JSON.stringify(walletData, null, 2), { mode: 0o600 });\n\n return {\n success: true,\n address: wallet.address,\n storagePath,\n isNew: true,\n };\n } catch (error) {\n return {\n success: false,\n error: (error as Error).message,\n };\n }\n}\n\n/**\n * Load existing wallet\n */\nexport function loadWallet(options: { storagePath?: string; password?: string } = {}): {\n success: boolean;\n address?: string;\n privateKey?: string;\n error?: string;\n} {\n const storagePath = options.storagePath || join(DEFAULT_STORAGE_DIR, DEFAULT_STORAGE_FILE);\n\n if (!existsSync(storagePath)) {\n return { success: false, error: 'Wallet not found. Run createWallet() first.' };\n }\n\n try {\n const data = JSON.parse(readFileSync(storagePath, 'utf8')) as WalletData;\n\n if (data.encrypted) {\n if (!options.password) {\n return { success: false, error: 'Wallet is encrypted. Password required.' };\n }\n const privateKey = decryptPrivateKey(data.privateKey, options.password, data.iv!, data.salt!);\n return { success: true, address: data.address, privateKey };\n } else {\n return { success: true, address: data.address, privateKey: data.privateKey };\n }\n } catch (error) {\n return { success: false, error: (error as Error).message };\n }\n}\n\n/**\n * Get wallet address (no password required)\n */\nexport function getWalletAddress(storagePath?: string): string | null {\n const path = storagePath || join(DEFAULT_STORAGE_DIR, DEFAULT_STORAGE_FILE);\n \n if (!existsSync(path)) {\n return null;\n }\n\n try {\n const data = JSON.parse(readFileSync(path, 'utf8')) as WalletData;\n return data.address;\n } catch {\n return null;\n }\n}\n\n/**\n * Check if wallet exists\n */\nexport function walletExists(storagePath?: string): boolean {\n const path = storagePath || join(DEFAULT_STORAGE_DIR, DEFAULT_STORAGE_FILE);\n return existsSync(path);\n}\n","/**\n * On-chain Payment Verification Module\n */\n\nimport { ethers } from 'ethers';\nimport { getChain, getChainById, type ChainConfig, type ChainName, type TokenSymbol } from '../chains';\n\n// ERC20 Transfer event signature\nconst TRANSFER_EVENT_TOPIC = ethers.id('Transfer(address,address,uint256)');\n\nexport interface VerifyPaymentParams {\n txHash: string;\n expectedAmount: number;\n expectedTo?: string;\n chain?: string | number;\n /** Expected token (if not specified, accepts both USDC and USDT) */\n expectedToken?: TokenSymbol;\n}\n\nexport interface VerifyPaymentResult {\n verified: boolean;\n amount?: number;\n token?: TokenSymbol;\n from?: string;\n to?: string;\n txHash?: string;\n blockNumber?: number;\n error?: string;\n}\n\n/**\n * Verify on-chain payment\n * Supports both USDC and USDT transfers\n */\nexport async function verifyPayment(params: VerifyPaymentParams): Promise<VerifyPaymentResult> {\n const { txHash, expectedAmount, expectedTo, expectedToken } = params;\n \n // Get chain config\n let chain: ChainConfig | undefined;\n try {\n if (typeof params.chain === 'number') {\n chain = getChainById(params.chain);\n } else {\n chain = getChain((params.chain || 'base') as ChainName);\n }\n if (!chain) {\n return { verified: false, error: `Unsupported chain: ${params.chain}` };\n }\n } catch (e) {\n return { verified: false, error: `Unsupported chain: ${params.chain}` };\n }\n\n try {\n const provider = new ethers.JsonRpcProvider(chain.rpc);\n \n // Get transaction receipt\n const receipt = await provider.getTransactionReceipt(txHash);\n \n if (!receipt) {\n return { verified: false, error: 'Transaction not found or not confirmed' };\n }\n\n if (receipt.status !== 1) {\n return { verified: false, error: 'Transaction failed' };\n }\n\n // Build map of accepted token addresses\n const tokenAddresses: Record<string, TokenSymbol> = {};\n \n if (!expectedToken || expectedToken === 'USDC') {\n tokenAddresses[chain.tokens.USDC.address.toLowerCase()] = 'USDC';\n }\n if (!expectedToken || expectedToken === 'USDT') {\n tokenAddresses[chain.tokens.USDT.address.toLowerCase()] = 'USDT';\n }\n\n if (Object.keys(tokenAddresses).length === 0) {\n return { verified: false, error: `No token addresses configured for ${chain.name}` };\n }\n\n for (const log of receipt.logs) {\n const logAddress = log.address.toLowerCase();\n \n // Check if this is one of our accepted tokens\n const detectedToken = tokenAddresses[logAddress];\n if (!detectedToken) {\n continue;\n }\n\n // Check if Transfer event\n if (log.topics.length < 3 || log.topics[0] !== TRANSFER_EVENT_TOPIC) {\n continue;\n }\n\n // Parse Transfer event params\n const from = '0x' + log.topics[1].slice(-40);\n const to = '0x' + log.topics[2].slice(-40);\n const amountRaw = BigInt(log.data);\n const tokenConfig = chain.tokens[detectedToken];\n const amount = Number(amountRaw) / (10 ** tokenConfig.decimals);\n\n // Verify recipient address\n if (expectedTo && to.toLowerCase() !== expectedTo.toLowerCase()) {\n continue;\n }\n\n // Verify amount\n if (amount < expectedAmount) {\n return {\n verified: false,\n error: `Insufficient amount: received ${amount} ${detectedToken}, expected ${expectedAmount}`,\n amount,\n token: detectedToken,\n from,\n to,\n txHash,\n blockNumber: receipt.blockNumber,\n };\n }\n\n // Verification successful\n return {\n verified: true,\n amount,\n token: detectedToken,\n from,\n to,\n txHash,\n blockNumber: receipt.blockNumber,\n };\n }\n\n const tokenList = expectedToken ? expectedToken : 'USDC/USDT';\n return { verified: false, error: `No ${tokenList} transfer found` };\n\n } catch (e: any) {\n return { verified: false, error: e.message || String(e) };\n }\n}\n\n/**\n * Get transaction status\n */\nexport async function getTransactionStatus(\n txHash: string,\n chain: string | number = 'base'\n): Promise<{\n status: 'pending' | 'confirmed' | 'failed' | 'not_found';\n blockNumber?: number;\n confirmations?: number;\n}> {\n let chainConfig: ChainConfig | undefined;\n try {\n chainConfig = typeof chain === 'number' ? getChainById(chain) : getChain(chain as ChainName);\n if (!chainConfig) return { status: 'not_found' };\n } catch {\n return { status: 'not_found' };\n }\n\n try {\n const provider = new ethers.JsonRpcProvider(chainConfig.rpc);\n const receipt = await provider.getTransactionReceipt(txHash);\n\n if (!receipt) {\n // Check if in pending pool\n const tx = await provider.getTransaction(txHash);\n if (tx) {\n return { status: 'pending' };\n }\n return { status: 'not_found' };\n }\n\n const currentBlock = await provider.getBlockNumber();\n const confirmations = currentBlock - receipt.blockNumber;\n\n if (receipt.status === 1) {\n return {\n status: 'confirmed',\n blockNumber: receipt.blockNumber,\n confirmations,\n };\n } else {\n return {\n status: 'failed',\n blockNumber: receipt.blockNumber,\n };\n }\n } catch {\n return { status: 'not_found' };\n }\n}\n\n/**\n * Wait for transaction confirmation\n */\nexport async function waitForTransaction(\n txHash: string,\n chain: string | number = 'base',\n confirmations = 1,\n timeoutMs = 60000\n): Promise<VerifyPaymentResult & { confirmed: boolean }> {\n let chainConfig: ChainConfig | undefined;\n try {\n chainConfig = typeof chain === 'number' ? getChainById(chain) : getChain(chain as ChainName);\n if (!chainConfig) {\n return { verified: false, confirmed: false, error: `Unsupported chain: ${chain}` };\n }\n } catch (e) {\n return { verified: false, confirmed: false, error: `Unsupported chain: ${chain}` };\n }\n\n const provider = new ethers.JsonRpcProvider(chainConfig.rpc);\n \n try {\n const receipt = await provider.waitForTransaction(txHash, confirmations, timeoutMs);\n \n if (!receipt) {\n return { verified: false, confirmed: false, error: 'Timeout waiting' };\n }\n\n if (receipt.status !== 1) {\n return { verified: false, confirmed: true, error: 'Transaction failed' };\n }\n\n return {\n verified: true,\n confirmed: true,\n txHash,\n blockNumber: receipt.blockNumber,\n };\n } catch (e: any) {\n return { verified: false, confirmed: false, error: e.message || String(e) };\n }\n}\n","/**\n * CDP (Coinbase Developer Platform) Wallet Integration\n * \n * Creates and manages wallets via Coinbase's CDP SDK.\n * These wallets are hosted by Coinbase, making them easy to use for AI Agents.\n * \n * @see https://docs.cdp.coinbase.com/\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport type { ChainName } from '../types/index.js';\nimport { getChain } from '../chains/index.js';\n\n// CDP config file location\nconst DEFAULT_STORAGE_DIR = path.join(process.env.HOME || '.', '.moltspay');\nconst CDP_CONFIG_FILE = 'cdp-wallet.json';\n\nexport interface CDPWalletConfig {\n /** Storage directory (default: ~/.moltspay) */\n storageDir?: string;\n /** Chain name */\n chain?: ChainName;\n /** CDP API credentials (or use env vars) */\n apiKeyId?: string;\n apiKeySecret?: string;\n walletSecret?: string;\n}\n\nexport interface CDPWalletData {\n /** Wallet address */\n address: string;\n /** CDP wallet ID */\n walletId: string;\n /** Chain */\n chain: ChainName;\n /** Created timestamp */\n createdAt: string;\n /** CDP account data (for restoration) */\n accountData?: string;\n}\n\nexport interface CDPInitResult {\n success: boolean;\n address?: string;\n walletId?: string;\n isNew?: boolean;\n error?: string;\n storagePath?: string;\n}\n\n/**\n * Check if CDP SDK is available\n */\nexport function isCDPAvailable(): boolean {\n try {\n require.resolve('@coinbase/cdp-sdk');\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Get CDP credentials from environment\n */\nfunction getCDPCredentials(config: CDPWalletConfig): {\n apiKeyId: string;\n apiKeySecret: string;\n walletSecret?: string;\n} | null {\n const apiKeyId = config.apiKeyId || process.env.CDP_API_KEY_ID;\n const apiKeySecret = config.apiKeySecret || process.env.CDP_API_KEY_SECRET;\n const walletSecret = config.walletSecret || process.env.CDP_WALLET_SECRET;\n\n if (!apiKeyId || !apiKeySecret) {\n return null;\n }\n\n return { apiKeyId, apiKeySecret, walletSecret };\n}\n\n/**\n * Initialize CDP wallet\n * \n * Creates a new CDP wallet or loads existing one.\n * \n * @example\n * ```bash\n * # Set credentials\n * export CDP_API_KEY_ID=your-key-id\n * export CDP_API_KEY_SECRET=your-key-secret\n * \n * # Initialize\n * npx moltspay init --cdp --chain base\n * ```\n */\nexport async function initCDPWallet(config: CDPWalletConfig = {}): Promise<CDPInitResult> {\n const storageDir = config.storageDir || DEFAULT_STORAGE_DIR;\n const chain = config.chain || 'base';\n const storagePath = path.join(storageDir, CDP_CONFIG_FILE);\n\n // Check for existing wallet\n if (fs.existsSync(storagePath)) {\n try {\n const data = JSON.parse(fs.readFileSync(storagePath, 'utf-8')) as CDPWalletData;\n return {\n success: true,\n address: data.address,\n walletId: data.walletId,\n isNew: false,\n storagePath,\n };\n } catch (error) {\n // Continue to create new\n }\n }\n\n // Check CDP availability\n if (!isCDPAvailable()) {\n return {\n success: false,\n error: 'CDP SDK not installed. Run: npm install @coinbase/cdp-sdk',\n };\n }\n\n // Get credentials\n const creds = getCDPCredentials(config);\n if (!creds) {\n return {\n success: false,\n error: 'CDP credentials not found. Set CDP_API_KEY_ID and CDP_API_KEY_SECRET environment variables.',\n };\n }\n\n try {\n // Dynamic import to avoid errors when CDP SDK is not installed\n const { CdpClient } = await import('@coinbase/cdp-sdk');\n\n // Initialize CDP client\n const cdp = new CdpClient({\n apiKeyId: creds.apiKeyId,\n apiKeySecret: creds.apiKeySecret,\n walletSecret: creds.walletSecret,\n });\n\n // Create EVM account\n const account = await cdp.evm.createAccount();\n\n // Ensure storage directory exists\n if (!fs.existsSync(storageDir)) {\n fs.mkdirSync(storageDir, { recursive: true });\n }\n\n // Save wallet data\n const walletData: CDPWalletData = {\n address: account.address,\n walletId: account.address, // CDP uses address as ID for EVM\n chain,\n createdAt: new Date().toISOString(),\n };\n\n fs.writeFileSync(storagePath, JSON.stringify(walletData, null, 2), { mode: 0o600 });\n\n return {\n success: true,\n address: account.address,\n walletId: account.address,\n isNew: true,\n storagePath,\n };\n } catch (error) {\n return {\n success: false,\n error: (error as Error).message,\n };\n }\n}\n\n/**\n * Load existing CDP wallet\n */\nexport function loadCDPWallet(config: CDPWalletConfig = {}): CDPWalletData | null {\n const storageDir = config.storageDir || DEFAULT_STORAGE_DIR;\n const storagePath = path.join(storageDir, CDP_CONFIG_FILE);\n\n if (!fs.existsSync(storagePath)) {\n return null;\n }\n\n try {\n return JSON.parse(fs.readFileSync(storagePath, 'utf-8')) as CDPWalletData;\n } catch {\n return null;\n }\n}\n\n/**\n * Get CDP wallet address (quick check without full init)\n */\nexport function getCDPWalletAddress(storageDir?: string): string | null {\n const data = loadCDPWallet({ storageDir });\n return data?.address || null;\n}\n\n/**\n * CDP Wallet class for making payments\n * \n * Uses CDP SDK for wallet operations with x402 support.\n */\nexport class CDPWallet {\n readonly address: string;\n readonly chain: ChainName;\n readonly chainConfig: ReturnType<typeof getChain>;\n private storageDir: string;\n\n constructor(config: CDPWalletConfig = {}) {\n this.storageDir = config.storageDir || DEFAULT_STORAGE_DIR;\n this.chain = config.chain || 'base';\n this.chainConfig = getChain(this.chain);\n\n // Load existing wallet\n const data = loadCDPWallet(config);\n if (!data) {\n throw new Error('CDP wallet not initialized. Run: npx moltspay init --cdp');\n }\n this.address = data.address;\n }\n\n /**\n * Get USDC balance\n */\n async getBalance(): Promise<{ usdc: string; eth: string }> {\n // Use ethers to check balance (read-only, no CDP needed)\n const { ethers } = await import('ethers');\n const provider = new ethers.JsonRpcProvider(this.chainConfig.rpc);\n \n const usdcContract = new ethers.Contract(\n this.chainConfig.usdc,\n ['function balanceOf(address) view returns (uint256)'],\n provider\n );\n\n const [usdcBalance, ethBalance] = await Promise.all([\n usdcContract.balanceOf(this.address),\n provider.getBalance(this.address),\n ]);\n\n return {\n usdc: (Number(usdcBalance) / 1e6).toFixed(2),\n eth: ethers.formatEther(ethBalance),\n };\n }\n\n /**\n * Transfer USDC to a recipient\n * \n * Requires CDP SDK and credentials to sign transactions.\n */\n async transfer(params: { to: string; amount: number }): Promise<{\n success: boolean;\n txHash?: string;\n error?: string;\n explorerUrl?: string;\n }> {\n if (!isCDPAvailable()) {\n return { success: false, error: 'CDP SDK not installed' };\n }\n\n const creds = getCDPCredentials({});\n if (!creds) {\n return { success: false, error: 'CDP credentials not found' };\n }\n\n try {\n const { CdpClient } = await import('@coinbase/cdp-sdk');\n const { ethers } = await import('ethers');\n\n const cdp = new CdpClient({\n apiKeyId: creds.apiKeyId,\n apiKeySecret: creds.apiKeySecret,\n walletSecret: creds.walletSecret,\n });\n\n // Get the account\n const account = await cdp.evm.getAccount({ address: this.address as `0x${string}` });\n\n // Build transfer transaction\n const amountWei = BigInt(Math.floor(params.amount * 1e6));\n const iface = new ethers.Interface([\n 'function transfer(address to, uint256 amount) returns (bool)',\n ]);\n const callData = iface.encodeFunctionData('transfer', [params.to, amountWei]);\n\n // Send transaction (use any to avoid type issues with CDP SDK versions)\n const txOptions: any = {\n to: this.chainConfig.usdc,\n data: callData,\n };\n const tx = await account.sendTransaction(txOptions);\n\n return {\n success: true,\n txHash: tx.transactionHash,\n explorerUrl: `${this.chainConfig.explorerTx}${tx.transactionHash}`,\n };\n } catch (error) {\n return {\n success: false,\n error: (error as Error).message,\n };\n }\n }\n\n /**\n * Create viem-compatible signer for x402\n * \n * This allows using CDP wallet with x402 protocol.\n */\n async getViemAccount(): Promise<unknown> {\n if (!isCDPAvailable()) {\n throw new Error('CDP SDK not installed');\n }\n\n const creds = getCDPCredentials({});\n if (!creds) {\n throw new Error('CDP credentials not found');\n }\n\n const { CdpClient } = await import('@coinbase/cdp-sdk');\n const { toAccount } = await import('viem/accounts');\n\n const cdp = new CdpClient({\n apiKeyId: creds.apiKeyId,\n apiKeySecret: creds.apiKeySecret,\n walletSecret: creds.walletSecret,\n });\n\n const account = await cdp.evm.getAccount({ address: this.address as `0x${string}` });\n return toAccount(account);\n }\n}\n"],"mappings":"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","names":["import_fs","path","X402_VERSION","loadEnvFile","settlement","import_fs","X402_VERSION","PAYMENT_REQUIRED_HEADER","PAYMENT_HEADER","network","import_ethers","import_ethers","import_fs","import_path","path","import_ethers","TRANSFER_EVENT_TOPIC","path","DEFAULT_STORAGE_DIR","ethers"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/server/index.ts","../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","../src/client/index.ts","../src/wallet/solana.ts","../src/wallet/Wallet.ts","../src/wallet/createWallet.ts","../src/verify/index.ts","../src/cdp/index.ts"],"sourcesContent":["/**\n * MoltsPay - Payment infrastructure for AI Agents\n * \n * Server (for agents selling services):\n * import { MoltsPayServer } from 'moltspay';\n * const server = new MoltsPayServer('./moltspay.services.json');\n * server.skill('my-service', async (params) => { ... });\n * server.listen(3000);\n * \n * Client (for agents buying services):\n * import { MoltsPayClient } from 'moltspay';\n * const client = new MoltsPayClient();\n * const result = await client.pay('http://provider:3000', 'my-service', { ... });\n * \n * @packageDocumentation\n */\n\n// Server - for selling services\nexport { MoltsPayServer } from './server/index.js';\nexport type {\n ServicesManifest,\n ServiceConfig,\n ProviderConfig,\n SkillFunction,\n RegisteredSkill,\n Charge,\n ChargeStatus,\n PaymentRequest,\n MoltsPayServerOptions,\n} from './server/types.js';\n\n// Client - for buying services\nexport { MoltsPayClient } from './client/index.js';\nexport type {\n ClientConfig,\n WalletData,\n PaymentRequired,\n ServiceInfo,\n ProviderInfo,\n ServicesResponse,\n VerifyResponse,\n MoltsPayClientOptions,\n} from './client/types.js';\n\n// Chain configuration\nexport { CHAINS, getChain, listChains, getChainById, ERC20_ABI } from './chains/index.js';\n\n// Wallet utilities\nexport {\n createWallet,\n loadWallet,\n getWalletAddress,\n walletExists,\n} from './wallet/index.js';\n\n// Payment verification\nexport {\n verifyPayment,\n getTransactionStatus,\n waitForTransaction,\n type VerifyPaymentParams,\n type VerifyPaymentResult,\n} from './verify/index.js';\n\n// CDP Wallet (optional)\nexport {\n initCDPWallet,\n loadCDPWallet,\n getCDPWalletAddress,\n isCDPAvailable,\n CDPWallet,\n} from './cdp/index.js';\n\n// Facilitators (v0.9.0+)\nexport {\n Facilitator,\n BaseFacilitator,\n FacilitatorRegistry,\n CDPFacilitator,\n getDefaultRegistry,\n createRegistry,\n} from './facilitators/index.js';\nexport type {\n FacilitatorConfig,\n FacilitatorSelection,\n SelectionStrategy,\n X402PaymentPayload,\n X402PaymentRequirements,\n VerifyResult,\n SettleResult,\n HealthCheckResult,\n FacilitatorFee,\n CDPFacilitatorConfig,\n} from './facilitators/index.js';\n","/**\n * MoltsPay Server - Payment infrastructure for AI Agents\n * \n * Now uses pluggable Facilitator abstraction for payment verification/settlement.\n * \n * Environment variables (from ~/.moltspay/.env or process.env):\n * USE_MAINNET=true - Use Base mainnet (requires CDP keys)\n * CDP_API_KEY_ID=xxx - Coinbase Developer Platform API key ID\n * CDP_API_KEY_SECRET=xxx - CDP API key secret\n * \n * Usage:\n * const server = new MoltsPayServer('./moltspay.services.json');\n * server.skill('text-to-video', async (params) => { ... });\n * server.listen(3000);\n */\n\nimport { readFileSync, existsSync } from 'fs';\nimport { createServer, IncomingMessage, ServerResponse } from 'http';\nimport * as path from 'path';\nimport {\n FacilitatorRegistry,\n FacilitatorSelection,\n X402PaymentPayload,\n X402PaymentRequirements,\n} from '../facilitators/index.js';\nimport {\n ServicesManifest,\n ServiceConfig,\n SkillFunction,\n RegisteredSkill,\n MoltsPayServerOptions,\n} from './types.js';\n\nexport * from './types.js';\n\n// x402 constants\nconst X402_VERSION = 2;\nconst PAYMENT_REQUIRED_HEADER = 'x-payment-required';\nconst PAYMENT_HEADER = 'x-payment';\nconst PAYMENT_RESPONSE_HEADER = 'x-payment-response';\n\n// MPP (Machine Payments Protocol) constants\nconst MPP_AUTH_HEADER = 'authorization';\nconst MPP_WWW_AUTH_HEADER = 'www-authenticate';\nconst MPP_RECEIPT_HEADER = 'payment-receipt';\n\n// Token contract addresses by network\nconst TOKEN_ADDRESSES: Record<string, Record<string, string>> = {\n 'eip155:8453': {\n USDC: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\n USDT: '0xfde4C96c8593536E31F229EA8f37b2ADa2699bb2',\n },\n 'eip155:84532': {\n USDC: '0x036CbD53842c5426634e7929541eC2318f3dCF7e',\n USDT: '0x036CbD53842c5426634e7929541eC2318f3dCF7e', // Same as USDC on testnet\n },\n 'eip155:137': {\n USDC: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',\n USDT: '0xc2132D05D31c914a87C6611C10748AEb04B58e8F',\n },\n 'eip155:42431': {\n // Tempo Moderato testnet - TIP-20 stablecoins\n USDC: '0x20c0000000000000000000000000000000000000', // pathUSD\n USDT: '0x20c0000000000000000000000000000000000001', // alphaUSD\n },\n // BNB Smart Chain mainnet\n 'eip155:56': {\n USDC: '0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d',\n USDT: '0x55d398326f99059fF775485246999027B3197955',\n },\n // BNB Smart Chain testnet\n 'eip155:97': {\n USDC: '0x64544969ed7EBf5f083679233325356EbE738930',\n USDT: '0x337610d27c682E347C9cD60BD4b3b107C9d34dDd',\n },\n // Solana networks use mint addresses (SPL tokens)\n 'solana:mainnet': {\n USDC: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', // Circle USDC\n },\n 'solana:devnet': {\n USDC: '4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU', // Devnet USDC\n },\n};\n\n// Chain name to network ID mapping\nconst CHAIN_TO_NETWORK: Record<string, string> = {\n 'base': 'eip155:8453',\n 'base_sepolia': 'eip155:84532',\n 'polygon': 'eip155:137',\n 'tempo_moderato': 'eip155:42431',\n 'bnb': 'eip155:56',\n 'bnb_testnet': 'eip155:97',\n 'solana': 'solana:mainnet',\n 'solana_devnet': 'solana:devnet',\n};\n\n// Helper to check if a network is Solana\nfunction isSolanaNetwork(network: string): boolean {\n return network.startsWith('solana:');\n}\n\n// EIP-712 domain info for tokens (per network)\n// Different networks may have different domain names for the same token\nconst TOKEN_DOMAINS: Record<string, Record<string, { name: string; version: string }>> = {\n // Base mainnet\n 'eip155:8453': {\n USDC: { name: 'USD Coin', version: '2' },\n USDT: { name: 'Tether USD', version: '2' },\n },\n // Base Sepolia testnet - USDC uses 'USDC' not 'USD Coin'\n 'eip155:84532': {\n USDC: { name: 'USDC', version: '2' },\n USDT: { name: 'USDC', version: '2' }, // Same contract as USDC on testnet\n },\n // Polygon mainnet\n 'eip155:137': {\n USDC: { name: 'USD Coin', version: '2' },\n USDT: { name: '(PoS) Tether USD', version: '2' },\n },\n // Tempo Moderato testnet - TIP-20 stablecoins\n 'eip155:42431': {\n USDC: { name: 'pathUSD', version: '1' },\n USDT: { name: 'alphaUSD', version: '1' },\n },\n // BNB Smart Chain mainnet\n 'eip155:56': {\n USDC: { name: 'USD Coin', version: '1' },\n USDT: { name: 'Tether USD', version: '1' },\n },\n // BNB Smart Chain testnet\n 'eip155:97': {\n USDC: { name: 'USD Coin', version: '1' },\n USDT: { name: 'Tether USD', version: '1' },\n },\n};\n\n// Helper to get token domain for a network\nfunction getTokenDomain(network: string, token: string): { name: string; version: string } {\n const networkDomains = TOKEN_DOMAINS[network] || TOKEN_DOMAINS['eip155:8453']; // fallback to base mainnet\n return networkDomains[token] || { name: 'USD Coin', version: '2' };\n}\n\n// Helper to get accepted currencies with backward compatibility\nfunction getAcceptedCurrencies(config: ServiceConfig): string[] {\n return config.acceptedCurrencies ?? [config.currency];\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 console.log(`[MoltsPay] Loaded config from ${envPath}`);\n break;\n } catch {\n // Ignore errors\n }\n }\n }\n}\n\n/**\n * Extended server options with facilitator config\n */\nexport interface MoltsPayServerOptionsExtended extends MoltsPayServerOptions {\n /** Facilitator selection configuration */\n facilitators?: FacilitatorSelection;\n}\n\nexport class MoltsPayServer {\n private manifest: ServicesManifest;\n private skills: Map<string, RegisteredSkill> = new Map();\n private options: MoltsPayServerOptionsExtended;\n private registry: FacilitatorRegistry;\n private networkId: string;\n private useMainnet: boolean;\n\n constructor(servicesPath: string, options: MoltsPayServerOptionsExtended = {}) {\n // Load env files FIRST (before reading USE_MAINNET)\n loadEnvFile();\n \n // Load services manifest\n const content = readFileSync(servicesPath, 'utf-8');\n this.manifest = JSON.parse(content) as ServicesManifest;\n \n this.options = {\n port: options.port || 3000,\n host: options.host || '0.0.0.0',\n ...options,\n };\n\n // Determine default network from env (fallback only)\n // NOTE: Chain is auto-detected from client payment header (payment.network)\n // USE_MAINNET is only used as fallback when payment header omits network\n // Recommended: configure \"chains\" array in manifest instead\n this.useMainnet = process.env.USE_MAINNET?.toLowerCase() === 'true';\n this.networkId = this.useMainnet ? 'eip155:8453' : 'eip155:84532';\n\n // Create facilitator registry with config (env vars take precedence)\n // Always include 'tempo', 'bnb', and 'solana' in fallback for multi-chain support\n const defaultFallback = ['tempo', 'bnb', 'solana'];\n const envFallback = process.env.FACILITATOR_FALLBACK?.split(',').filter(Boolean);\n const facilitatorConfig: FacilitatorSelection = options.facilitators || {\n primary: process.env.FACILITATOR_PRIMARY || 'cdp',\n fallback: envFallback || defaultFallback,\n strategy: (process.env.FACILITATOR_STRATEGY as any) || 'failover',\n config: {\n cdp: { useMainnet: this.useMainnet },\n },\n };\n this.registry = new FacilitatorRegistry(facilitatorConfig);\n\n // Get primary facilitator for logging\n const primaryFacilitator = this.registry.get(facilitatorConfig.primary);\n \n console.log(`[MoltsPay] Loaded ${this.manifest.services.length} services from ${servicesPath}`);\n console.log(`[MoltsPay] Provider: ${this.manifest.provider.name}`);\n console.log(`[MoltsPay] Receive wallet: ${this.manifest.provider.wallet}`);\n \n // Log configured chains\n const chains = this.manifest.provider.chains;\n if (chains && chains.length > 0) {\n const chainNames = chains.map(c => c.chain || c.network).join(', ');\n console.log(`[MoltsPay] Chains: ${chainNames} (multi-chain enabled)`);\n } else {\n const networkName = this.useMainnet ? 'Base mainnet' : 'Base Sepolia (testnet)';\n console.log(`[MoltsPay] Network: ${this.networkId} (${networkName})`);\n }\n \n console.log(`[MoltsPay] Facilitator: ${primaryFacilitator.displayName} (${facilitatorConfig.strategy || 'failover'})`);\n console.log(`[MoltsPay] Protocol: x402 (gasless for both client AND server)`);\n }\n\n /**\n * Register a skill handler for a service\n */\n skill(serviceId: string, handler: SkillFunction): this {\n const config = this.manifest.services.find(s => s.id === serviceId);\n if (!config) {\n throw new Error(`Service '${serviceId}' not found in manifest`);\n }\n this.skills.set(serviceId, { id: serviceId, config, handler });\n return this;\n }\n\n /**\n * Get all configured chains for this provider\n * Returns array of { network, wallet, tokens } for each chain\n */\n private getProviderChains(): Array<{ network: string; wallet: string; tokens: string[] }> {\n const provider = this.manifest.provider;\n \n // Helper to get the right wallet for a chain\n const getWalletForChain = (chainName: string, explicitWallet?: string): string => {\n // If explicit wallet provided (object format), use it\n if (explicitWallet) return explicitWallet;\n // For Solana chains, use solana_wallet if available\n if ((chainName === 'solana' || chainName === 'solana_devnet') && provider.solana_wallet) {\n return provider.solana_wallet;\n }\n // Default to EVM wallet\n return provider.wallet;\n };\n \n // If chains array is defined, use it\n // Supports both string array [\"base\", \"polygon\"] and object array [{chain, wallet, tokens}]\n if (provider.chains && provider.chains.length > 0) {\n return provider.chains.map(c => {\n const chainName = typeof c === 'string' ? c : c.chain;\n const explicitWallet = typeof c === 'object' ? c.wallet : null;\n return {\n network: CHAIN_TO_NETWORK[chainName] || 'eip155:8453',\n wallet: getWalletForChain(chainName, explicitWallet || undefined),\n tokens: (typeof c === 'object' ? c.tokens : null) || ['USDC'],\n };\n });\n }\n \n // Fallback to single chain (backward compat)\n const chain = provider.chain || 'base';\n const network = CHAIN_TO_NETWORK[chain] || this.networkId;\n return [{\n network,\n wallet: getWalletForChain(chain),\n tokens: ['USDC'],\n }];\n }\n\n /**\n * Get wallet address for a specific network\n */\n private getWalletForNetwork(network: string): string {\n const chains = this.getProviderChains();\n const chain = chains.find(c => c.network === network);\n return chain?.wallet || this.manifest.provider.wallet;\n }\n\n /**\n * Check if a network is accepted by this provider\n */\n private isNetworkAccepted(network: string): boolean {\n const chains = this.getProviderChains();\n return chains.some(c => c.network === network);\n }\n\n /**\n * Start HTTP server\n */\n listen(port?: number): void {\n const p = port || this.options.port || 3000;\n const host = this.options.host || '0.0.0.0';\n\n const server = createServer((req, res) => this.handleRequest(req, res));\n server.listen(p, host, () => {\n console.log(`[MoltsPay] Server listening on http://${host}:${p}`);\n console.log(`[MoltsPay] Endpoints:`);\n console.log(` GET /services - List available services`);\n console.log(` POST /execute - Execute service (x402 payment)`);\n console.log(` POST /proxy - Proxy payment for external services`);\n console.log(` GET /health - Health check (incl. facilitators)`);\n });\n }\n\n /**\n * Handle incoming request\n */\n private async handleRequest(req: IncomingMessage, res: ServerResponse): Promise<void> {\n // CORS\n res.setHeader('Access-Control-Allow-Origin', '*');\n res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');\n res.setHeader('Access-Control-Allow-Headers', 'Content-Type, X-Payment, Authorization');\n res.setHeader('Access-Control-Expose-Headers', 'X-Payment-Required, X-Payment-Response, WWW-Authenticate, Payment-Receipt');\n\n if (req.method === 'OPTIONS') {\n res.writeHead(204);\n res.end();\n return;\n }\n\n try {\n const url = new URL(req.url || '/', `http://${req.headers.host}`);\n \n if (url.pathname === '/services' && req.method === 'GET') {\n return this.handleGetServices(res);\n }\n\n // Standard discovery endpoint\n if (url.pathname === '/.well-known/agent-services.json' && req.method === 'GET') {\n return this.handleAgentServicesDiscovery(res);\n }\n\n if (url.pathname === '/health' && req.method === 'GET') {\n return await this.handleHealthCheck(res);\n }\n\n if (url.pathname === '/execute' && req.method === 'POST') {\n const body = await this.readBody(req);\n const paymentHeader = req.headers[PAYMENT_HEADER] as string | undefined;\n return await this.handleExecute(body, paymentHeader, res);\n }\n\n if (url.pathname === '/proxy' && req.method === 'POST') {\n // Check IP whitelist\n const clientIP = (req.headers['x-real-ip'] as string) || \n (req.headers['x-forwarded-for'] as string)?.split(',')[0]?.trim() ||\n req.socket.remoteAddress || '';\n if (!this.isProxyAllowed(clientIP)) {\n return this.sendJson(res, 403, { error: 'Forbidden: IP not allowed' });\n }\n const body = await this.readBody(req);\n const paymentHeader = req.headers[PAYMENT_HEADER] as string | undefined;\n const authHeader = req.headers[MPP_AUTH_HEADER] as string | undefined;\n return await this.handleProxy(body, paymentHeader, authHeader, res);\n }\n\n // MPP Protocol: Handle service-specific endpoints like /text-to-video, /ping\n // Check if URL matches a registered service ID\n const servicePath = url.pathname.replace(/^\\//, ''); // Remove leading slash\n const skill = this.skills.get(servicePath);\n if (skill && (req.method === 'POST' || req.method === 'GET')) {\n const body = req.method === 'POST' ? await this.readBody(req) : {};\n const authHeader = req.headers[MPP_AUTH_HEADER] as string | undefined;\n const x402Header = req.headers[PAYMENT_HEADER] as string | undefined;\n return await this.handleMPPRequest(skill, body, authHeader, x402Header, res);\n }\n\n // Not found\n this.sendJson(res, 404, { error: 'Not found' });\n } catch (err: any) {\n console.error('[MoltsPay] Error:', err);\n this.sendJson(res, 500, { error: err.message || 'Internal error' });\n }\n }\n\n /**\n * GET /.well-known/agent-services.json - Standard discovery endpoint\n */\n private handleAgentServicesDiscovery(res: ServerResponse): void {\n const services = this.manifest.services.map(s => ({\n id: s.id,\n name: s.name,\n description: s.description,\n price: s.price,\n currency: s.currency,\n acceptedCurrencies: getAcceptedCurrencies(s),\n input: s.input,\n output: s.output,\n available: this.skills.has(s.id),\n }));\n\n this.sendJson(res, 200, {\n version: '1.0',\n provider: {\n name: this.manifest.provider.name,\n description: this.manifest.provider.description,\n wallet: this.manifest.provider.wallet,\n chain: this.manifest.provider.chain || 'base',\n solana_wallet: this.manifest.provider.solana_wallet,\n chains: this.manifest.provider.chains,\n },\n services,\n endpoints: {\n services: '/services',\n execute: '/execute',\n health: '/health',\n },\n payment: {\n protocol: 'x402',\n version: X402_VERSION,\n network: this.networkId,\n schemes: ['exact'],\n mainnet: this.useMainnet,\n },\n });\n }\n\n /**\n * GET /services - List available services\n */\n private handleGetServices(res: ServerResponse): void {\n const services = this.manifest.services.map(s => ({\n id: s.id,\n name: s.name,\n description: s.description,\n price: s.price,\n currency: s.currency,\n acceptedCurrencies: getAcceptedCurrencies(s),\n input: s.input,\n output: s.output,\n available: this.skills.has(s.id),\n }));\n\n const selection = this.registry.getSelection();\n \n this.sendJson(res, 200, {\n provider: this.manifest.provider,\n services,\n x402: {\n version: X402_VERSION,\n network: this.networkId,\n schemes: ['exact'],\n facilitators: {\n primary: selection.primary,\n fallback: selection.fallback,\n strategy: selection.strategy,\n },\n mainnet: this.useMainnet,\n },\n });\n }\n\n /**\n * GET /health - Health check endpoint\n */\n private async handleHealthCheck(res: ServerResponse): Promise<void> {\n const facilitatorHealth = await this.registry.healthCheckAll();\n \n const allHealthy = Object.values(facilitatorHealth).every(h => h.healthy);\n \n this.sendJson(res, allHealthy ? 200 : 503, {\n status: allHealthy ? 'healthy' : 'degraded',\n network: this.networkId,\n facilitators: facilitatorHealth,\n services: this.manifest.services.length,\n registered: this.skills.size,\n });\n }\n\n /**\n * POST /execute - Execute service with x402 payment\n */\n private async handleExecute(\n body: any,\n paymentHeader: string | undefined,\n res: ServerResponse\n ): Promise<void> {\n const { service, params } = body;\n\n if (!service) {\n return this.sendJson(res, 400, { error: 'Missing service' });\n }\n\n const skill = this.skills.get(service);\n if (!skill) {\n return this.sendJson(res, 404, { error: `Service '${service}' not found or not registered` });\n }\n\n // Validate required params\n for (const [key, field] of Object.entries(skill.config.input)) {\n if (field.required && (!params || params[key] === undefined)) {\n return this.sendJson(res, 400, { error: `Missing required param: ${key}` });\n }\n }\n\n // If no payment header, return 402 with payment requirements\n if (!paymentHeader) {\n return this.sendPaymentRequired(skill.config, res);\n }\n\n // Parse payment payload\n let payment: X402PaymentPayload;\n try {\n const decoded = Buffer.from(paymentHeader, 'base64').toString('utf-8');\n payment = JSON.parse(decoded);\n } catch {\n return this.sendJson(res, 400, { error: 'Invalid X-Payment header' });\n }\n\n // Validate basic payment fields\n const validation = this.validatePayment(payment, skill.config);\n if (!validation.valid) {\n return this.sendJson(res, 402, { error: validation.error });\n }\n\n // Detect which token is being used\n const paymentToken = this.detectPaymentToken(payment);\n if (paymentToken && !this.isTokenAccepted(skill.config, paymentToken)) {\n const accepted = getAcceptedCurrencies(skill.config);\n return this.sendJson(res, 402, { \n error: `Token ${paymentToken} not accepted. Accepted: ${accepted.join(', ')}` \n });\n }\n\n // Auto-detect chain from payment header (key insight: client specifies chain via --chain flag)\n // payment.network contains \"eip155:8453\" (base) or \"eip155:84532\" (base_sepolia) etc.\n // This allows provider to serve both mainnet and testnet without separate configuration\n const paymentNetwork = payment.accepted?.network || payment.network || this.networkId;\n const paymentWallet = this.getWalletForNetwork(paymentNetwork);\n\n // Build requirements for facilitator using the detected token and network\n const requirements = this.buildPaymentRequirements(skill.config, paymentNetwork, paymentWallet, paymentToken);\n\n // Verify payment with facilitator (via registry)\n console.log(`[MoltsPay] Verifying payment on ${paymentNetwork}...`);\n const verifyResult = await this.registry.verify(payment, requirements);\n if (!verifyResult.valid) {\n return this.sendJson(res, 402, { \n error: `Payment verification failed: ${verifyResult.error}`,\n facilitator: verifyResult.facilitator,\n });\n }\n console.log(`[MoltsPay] Verified by ${verifyResult.facilitator}`);\n\n // For Solana: settle FIRST (blockhash expires quickly ~60s)\n // For EVM: pay-for-success (execute first, settle after)\n const isSolana = isSolanaNetwork(paymentNetwork);\n let settlement: any = null;\n\n if (isSolana) {\n console.log(`[MoltsPay] Solana detected - settling payment FIRST (blockhash expiry protection)`);\n try {\n settlement = await this.registry.settle(payment, requirements);\n console.log(`[MoltsPay] Payment settled by ${settlement.facilitator}: ${settlement.transaction || 'pending'}`);\n } catch (err: any) {\n console.error('[MoltsPay] Solana settlement failed:', err.message);\n return this.sendJson(res, 402, {\n error: 'Payment settlement failed',\n message: err.message,\n });\n }\n }\n\n // Execute skill (with timeout)\n const timeoutSeconds = parseInt(process.env.SKILL_TIMEOUT_SECONDS || '1200');\n console.log(`[MoltsPay] Executing skill: ${service} (timeout: ${timeoutSeconds}s)`);\n let result: any;\n try {\n result = await Promise.race([\n skill.handler(params || {}),\n new Promise((_, reject) => \n setTimeout(() => reject(new Error(`Skill timeout after ${timeoutSeconds}s`)), timeoutSeconds * 1000)\n )\n ]);\n } catch (err: any) {\n console.error('[MoltsPay] Skill execution failed:', err.message);\n // For Solana: payment already settled, skill failed - no refund (user accepted risk)\n // For EVM: payment not settled yet, user keeps their money\n return this.sendJson(res, 500, {\n error: 'Service execution failed',\n message: err.message,\n paymentSettled: isSolana ? true : false,\n note: isSolana ? 'Payment was settled before execution. Contact support for refund.' : undefined,\n });\n }\n\n // For EVM: settle payment now (pay-for-success)\n if (!isSolana) {\n console.log(`[MoltsPay] Skill succeeded, settling payment...`);\n try {\n settlement = await this.registry.settle(payment, requirements);\n console.log(`[MoltsPay] Payment settled by ${settlement.facilitator}: ${settlement.transaction || 'pending'}`);\n } catch (err: any) {\n console.error('[MoltsPay] Settlement failed:', err.message);\n }\n }\n\n // Build response\n const responseHeaders: Record<string, string> = {};\n if (settlement?.success) {\n const responsePayload = {\n success: true,\n transaction: settlement.transaction,\n network: payment.network || payment.accepted?.network,\n facilitator: settlement.facilitator,\n };\n responseHeaders[PAYMENT_RESPONSE_HEADER] = Buffer.from(\n JSON.stringify(responsePayload)\n ).toString('base64');\n }\n\n this.sendJson(res, 200, {\n success: true,\n result,\n payment: settlement?.success \n ? { transaction: settlement.transaction, status: 'settled', facilitator: settlement.facilitator }\n : { status: 'pending' },\n }, responseHeaders);\n }\n\n /**\n * Handle MPP (Machine Payments Protocol) request\n * Supports both x402 and MPP protocols on service endpoints\n */\n private async handleMPPRequest(\n skill: RegisteredSkill,\n body: any,\n authHeader: string | undefined,\n x402Header: string | undefined,\n res: ServerResponse\n ): Promise<void> {\n const config = skill.config;\n const params = body || {};\n\n // Check for x402 payment header first (backward compatibility)\n if (x402Header) {\n return await this.handleExecute({ service: config.id, params }, x402Header, res);\n }\n\n // Check for MPP payment credential\n if (authHeader && authHeader.toLowerCase().startsWith('payment ')) {\n return await this.handleMPPPayment(skill, params, authHeader, res);\n }\n\n // No payment provided - return 402 with both x402 and MPP headers\n return this.sendMPPPaymentRequired(config, res);\n }\n\n /**\n * Handle MPP payment verification and service execution\n */\n private async handleMPPPayment(\n skill: RegisteredSkill,\n params: any,\n authHeader: string,\n res: ServerResponse\n ): Promise<void> {\n const config = skill.config;\n\n // Parse MPP credential: \"Payment <base64>\"\n const credentialMatch = authHeader.match(/Payment\\s+(.+)/i);\n if (!credentialMatch) {\n return this.sendJson(res, 400, { error: 'Invalid Authorization header format' });\n }\n\n let mppCredential: {\n challenge: {\n id: string;\n realm: string;\n method: string;\n intent: string;\n request: any;\n };\n payload: {\n hash?: string;\n signature?: string;\n type: 'hash' | 'transaction';\n };\n source?: string;\n };\n \n try {\n // mppx uses base64url encoding without padding\n const base64 = credentialMatch[1].replace(/-/g, '+').replace(/_/g, '/');\n const decoded = Buffer.from(base64, 'base64').toString('utf-8');\n mppCredential = JSON.parse(decoded);\n } catch (err) {\n console.error('[MoltsPay] Failed to parse MPP credential:', err);\n return this.sendJson(res, 400, { error: 'Invalid payment credential encoding' });\n }\n\n // Extract transaction hash from payload\n let txHash: string | undefined;\n if (mppCredential.payload?.type === 'hash' && mppCredential.payload?.hash) {\n txHash = mppCredential.payload.hash;\n } else if (mppCredential.payload?.type === 'transaction') {\n // For 'transaction' type, server would need to submit the signed tx\n // For now, we only support 'hash' type (push mode)\n return this.sendJson(res, 400, { \n error: 'Transaction type not supported. Please use push mode (hash type).' \n });\n }\n\n if (!txHash) {\n return this.sendJson(res, 400, { error: 'Missing transaction hash in credential' });\n }\n\n // Extract chainId from challenge or source\n let chainId = mppCredential.challenge?.request?.methodDetails?.chainId;\n if (!chainId && mppCredential.source) {\n const chainMatch = mppCredential.source.match(/eip155:(\\d+)/);\n if (chainMatch) chainId = parseInt(chainMatch[1], 10);\n }\n chainId = chainId || 42431; // Default to Tempo Moderato\n\n // Determine network from chainId\n const network = `eip155:${chainId}`;\n\n if (!this.isNetworkAccepted(network)) {\n return this.sendJson(res, 402, { \n error: `Network not accepted: ${network}` \n });\n }\n\n // Build requirements for verification\n const requirements = this.buildPaymentRequirements(\n config,\n network,\n this.getWalletForNetwork(network),\n 'USDC'\n );\n\n // Create x402-compatible payload for facilitator\n const paymentPayload: X402PaymentPayload = {\n x402Version: X402_VERSION,\n scheme: 'exact',\n network,\n payload: {\n txHash,\n chainId,\n },\n };\n\n console.log(`[MoltsPay] Verifying MPP payment: txHash=${txHash}, chainId=${chainId}`);\n\n // Verify payment using facilitator registry\n const verification = await this.registry.verify(paymentPayload, requirements);\n \n if (!verification.valid) {\n return this.sendJson(res, 402, { \n error: `Payment verification failed: ${verification.error}` \n });\n }\n\n console.log(`[MoltsPay] Payment verified! Executing service: ${config.id}`);\n\n // Execute the skill\n let result: any;\n try {\n result = await skill.handler(params);\n } catch (err: any) {\n console.error(`[MoltsPay] Skill execution error:`, err);\n return this.sendJson(res, 500, { \n error: `Service execution failed: ${err.message}` \n });\n }\n\n // Build receipt\n const receipt = {\n success: true,\n txHash,\n network,\n facilitator: verification.facilitator,\n };\n const receiptEncoded = Buffer.from(JSON.stringify(receipt)).toString('base64');\n\n // Return success with MPP receipt header\n res.writeHead(200, {\n 'Content-Type': 'application/json',\n [MPP_RECEIPT_HEADER]: receiptEncoded,\n });\n res.end(JSON.stringify({\n success: true,\n result,\n payment: {\n txHash,\n status: 'verified',\n facilitator: verification.facilitator,\n },\n }, null, 2));\n }\n\n /**\n * Return 402 with both x402 and MPP payment requirements\n */\n private sendMPPPaymentRequired(config: ServiceConfig, res: ServerResponse): void {\n const acceptedTokens = getAcceptedCurrencies(config);\n const providerChains = this.getProviderChains();\n \n // === x402 format (existing) ===\n const accepts: X402PaymentRequirements[] = [];\n for (const chainConfig of providerChains) {\n for (const token of acceptedTokens) {\n if (chainConfig.tokens.includes(token)) {\n accepts.push(this.buildPaymentRequirements(config, chainConfig.network, chainConfig.wallet, token));\n }\n }\n }\n\n const x402PaymentRequired = {\n x402Version: X402_VERSION,\n accepts,\n acceptedCurrencies: acceptedTokens,\n resource: {\n url: `/${config.id}`,\n description: `${config.name} - $${config.price} ${config.currency}`,\n },\n };\n const x402Encoded = Buffer.from(JSON.stringify(x402PaymentRequired)).toString('base64');\n\n // === MPP format ===\n // Find Tempo chain if available\n const tempoChain = providerChains.find(c => c.network === 'eip155:42431');\n \n let mppWwwAuth = '';\n if (tempoChain) {\n const challengeId = this.generateChallengeId();\n const amountInUnits = Math.floor(config.price * 1e6).toString();\n const tokenAddress = TOKEN_ADDRESSES['eip155:42431']?.USDC || '0x20c0000000000000000000000000000000000000';\n \n const mppRequest = {\n amount: amountInUnits,\n currency: tokenAddress,\n methodDetails: {\n chainId: 42431,\n feePayer: true,\n },\n recipient: tempoChain.wallet,\n };\n const mppRequestEncoded = Buffer.from(JSON.stringify(mppRequest)).toString('base64');\n \n const expiresAt = new Date(Date.now() + 5 * 60 * 1000).toISOString();\n \n mppWwwAuth = `Payment id=\"${challengeId}\", realm=\"${this.manifest.provider.name}\", method=\"tempo\", intent=\"charge\", request=\"${mppRequestEncoded}\", description=\"${config.name}\", expires=\"${expiresAt}\"`;\n }\n\n // Build response headers\n const headers: Record<string, string> = {\n 'Content-Type': 'application/problem+json',\n [PAYMENT_REQUIRED_HEADER]: x402Encoded,\n };\n \n if (mppWwwAuth) {\n headers[MPP_WWW_AUTH_HEADER] = mppWwwAuth;\n }\n\n res.writeHead(402, headers);\n res.end(JSON.stringify({\n type: 'https://paymentauth.org/problems/payment-required',\n title: 'Payment Required',\n status: 402,\n detail: `Payment is required (${config.name}).`,\n service: config.id,\n price: config.price,\n currency: config.currency,\n acceptedCurrencies: acceptedTokens,\n }, null, 2));\n }\n\n /**\n * Generate a unique challenge ID for MPP\n */\n private generateChallengeId(): string {\n const bytes = new Uint8Array(24);\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = Math.floor(Math.random() * 256);\n }\n return Buffer.from(bytes).toString('base64url');\n }\n\n /**\n * Return 402 with x402 payment requirements (v2 format)\n * Includes requirements for all chains and all accepted currencies\n */\n private sendPaymentRequired(config: ServiceConfig, res: ServerResponse): void {\n const acceptedTokens = getAcceptedCurrencies(config);\n const providerChains = this.getProviderChains();\n \n // Build requirements for each chain x token combination\n const accepts: X402PaymentRequirements[] = [];\n for (const chainConfig of providerChains) {\n for (const token of acceptedTokens) {\n // Only add if this chain supports this token\n if (chainConfig.tokens.includes(token)) {\n accepts.push(this.buildPaymentRequirements(config, chainConfig.network, chainConfig.wallet, token));\n }\n }\n }\n\n // Get list of accepted chains for response\n const acceptedChains = providerChains.map(c => {\n // Convert network ID to chain name for readability\n if (c.network === 'eip155:8453') return 'base';\n if (c.network === 'eip155:137') return 'polygon';\n return c.network;\n });\n\n const paymentRequired = {\n x402Version: X402_VERSION,\n accepts,\n acceptedCurrencies: acceptedTokens,\n acceptedChains,\n resource: {\n url: `/execute?service=${config.id}`,\n description: `${config.name} - $${config.price} ${config.currency}`,\n mimeType: 'application/json',\n },\n };\n\n const encoded = Buffer.from(JSON.stringify(paymentRequired)).toString('base64');\n\n res.writeHead(402, {\n 'Content-Type': 'application/json',\n [PAYMENT_REQUIRED_HEADER]: encoded,\n });\n res.end(JSON.stringify({\n error: 'Payment required',\n message: `Service requires $${config.price} ${config.currency}`,\n acceptedCurrencies: acceptedTokens,\n acceptedChains,\n x402: paymentRequired,\n }, null, 2));\n }\n\n /**\n * Basic payment validation\n */\n private validatePayment(\n payment: X402PaymentPayload,\n config: ServiceConfig\n ): { valid: boolean; error?: string } {\n if (payment.x402Version !== X402_VERSION) {\n return { valid: false, error: `Unsupported x402 version: ${payment.x402Version}` };\n }\n\n const scheme = payment.accepted?.scheme || payment.scheme;\n const network = payment.accepted?.network || payment.network || this.networkId;\n\n if (scheme !== 'exact') {\n return { valid: false, error: `Unsupported scheme: ${scheme}` };\n }\n\n // Check if payment network is one of our accepted networks\n if (!this.isNetworkAccepted(network)) {\n const acceptedChains = this.getProviderChains().map(c => c.network).join(', ');\n return { valid: false, error: `Network not accepted: ${network}. Accepted: ${acceptedChains}` };\n }\n\n return { valid: true };\n }\n\n /**\n * Build payment requirements for facilitator\n * Now supports multi-chain: takes network and wallet as parameters\n */\n private buildPaymentRequirements(\n config: ServiceConfig, \n network?: string, \n wallet?: string,\n token?: string\n ): X402PaymentRequirements {\n const amountInUnits = Math.floor(config.price * 1e6).toString();\n const acceptedTokens = getAcceptedCurrencies(config);\n \n // Use specified values or defaults\n const selectedNetwork = network || this.networkId;\n const selectedWallet = wallet || this.manifest.provider.wallet;\n const selectedToken = token && acceptedTokens.includes(token) ? token : acceptedTokens[0];\n \n const tokenAddresses = TOKEN_ADDRESSES[selectedNetwork] || {};\n const tokenAddress = tokenAddresses[selectedToken];\n const tokenDomain = getTokenDomain(selectedNetwork, selectedToken);\n\n const requirements: X402PaymentRequirements = {\n scheme: 'exact',\n network: selectedNetwork,\n asset: tokenAddress,\n amount: amountInUnits,\n payTo: selectedWallet,\n maxTimeoutSeconds: 300,\n extra: tokenDomain,\n };\n \n // For Solana: include fee payer pubkey if available (gasless mode)\n if (selectedNetwork === 'solana:mainnet' || selectedNetwork === 'solana:devnet') {\n const solanaFacilitator = this.registry.get('solana') as any;\n const feePayerPubkey = solanaFacilitator?.getFeePayerPubkey?.();\n if (feePayerPubkey) {\n (requirements.extra as any) = {\n ...(requirements.extra || {}),\n solanaFeePayer: feePayerPubkey,\n };\n }\n }\n \n // For BNB: include spender address for client approval\n if (selectedNetwork === 'eip155:56' || selectedNetwork === 'eip155:97') {\n const bnbFacilitator = this.registry.get('bnb') as any;\n const spenderAddress = bnbFacilitator?.getSpenderAddress?.();\n if (spenderAddress) {\n (requirements.extra as any) = {\n ...(requirements.extra || {}),\n bnbSpender: spenderAddress,\n };\n }\n }\n \n return requirements;\n }\n\n /**\n * Detect which token is being used in the payment\n * Checks across all supported networks\n */\n private detectPaymentToken(payment: X402PaymentPayload): string | undefined {\n const asset = payment.accepted?.asset || (payment.payload as any)?.asset;\n if (!asset) return undefined;\n\n // Get payment network to check correct token addresses\n const paymentNetwork = payment.accepted?.network || payment.network || this.networkId;\n const tokenAddresses = TOKEN_ADDRESSES[paymentNetwork] || {};\n \n for (const [symbol, address] of Object.entries(tokenAddresses)) {\n if (address && (address as string).toLowerCase() === asset.toLowerCase()) {\n return symbol;\n }\n }\n return undefined;\n }\n\n /**\n * Check if payment token is accepted for service\n */\n private isTokenAccepted(config: ServiceConfig, token: string): boolean {\n const accepted = getAcceptedCurrencies(config);\n return accepted.includes(token);\n }\n\n private async readBody(req: IncomingMessage): Promise<any> {\n return new Promise((resolve, reject) => {\n let body = '';\n req.on('data', chunk => body += chunk);\n req.on('end', () => {\n try {\n resolve(body ? JSON.parse(body) : {});\n } catch {\n reject(new Error('Invalid JSON'));\n }\n });\n req.on('error', reject);\n });\n }\n\n private sendJson(\n res: ServerResponse, \n status: number, \n data: any,\n extraHeaders?: Record<string, string>\n ): void {\n const headers: Record<string, string> = { 'Content-Type': 'application/json' };\n if (extraHeaders) {\n Object.assign(headers, extraHeaders);\n }\n res.writeHead(status, headers);\n res.end(JSON.stringify(data, null, 2));\n }\n\n /**\n * Check if IP is allowed for /proxy endpoint\n */\n private isProxyAllowed(clientIP: string): boolean {\n const allowedIPs = process.env.PROXY_ALLOWED_IPS?.split(',').map(ip => ip.trim()) || [];\n \n // If no whitelist configured, deny all (secure by default)\n if (allowedIPs.length === 0) {\n console.log(`[MoltsPay] /proxy denied: no PROXY_ALLOWED_IPS configured`);\n return false;\n }\n \n // Normalize IPv6 localhost\n const normalizedIP = clientIP === '::1' ? '127.0.0.1' : clientIP.replace('::ffff:', '');\n \n const allowed = allowedIPs.includes(normalizedIP) || allowedIPs.includes(clientIP);\n if (!allowed) {\n console.log(`[MoltsPay] /proxy denied for IP: ${clientIP} (normalized: ${normalizedIP})`);\n }\n return allowed;\n }\n\n /**\n * POST /proxy - Handle payment for external services (moltspay-creators)\n * \n * This endpoint allows other services to delegate x402/MPP payment handling.\n * It does NOT execute any skill - just handles payment verification/settlement.\n * \n * Request body:\n * { wallet, amount, currency, chain, memo, serviceId, description }\n * \n * For x402 (base, polygon, base_sepolia):\n * Without X-Payment header: returns 402 with X-Payment-Required\n * With X-Payment header: verifies payment via CDP\n * \n * For MPP (tempo_moderato):\n * Without Authorization header: returns 402 with WWW-Authenticate\n * With Authorization: Payment header: verifies tx on Tempo chain\n */\n private async handleProxy(\n body: any,\n paymentHeader: string | undefined,\n authHeader: string | undefined,\n res: ServerResponse\n ): Promise<void> {\n const { wallet, amount, currency, chain, memo, serviceId, description } = body;\n\n // Validate required fields\n if (!wallet || !amount) {\n return this.sendJson(res, 400, { error: 'Missing required fields: wallet, amount' });\n }\n\n // Validate chain if provided\n const supportedChains = ['base', 'polygon', 'base_sepolia', 'tempo_moderato', 'bnb', 'bnb_testnet', 'solana', 'solana_devnet'];\n if (chain && !supportedChains.includes(chain)) {\n return this.sendJson(res, 400, { error: `Unsupported chain: ${chain}. Supported: ${supportedChains.join(', ')}` });\n }\n\n // Validate wallet format based on chain\n const isSolanaChain = chain === 'solana' || chain === 'solana_devnet';\n const isValidEvmAddress = /^0x[a-fA-F0-9]{40}$/.test(wallet);\n const isValidSolanaAddress = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/.test(wallet);\n \n if (isSolanaChain && !isValidSolanaAddress) {\n return this.sendJson(res, 400, { error: 'Invalid Solana wallet address format' });\n }\n if (!isSolanaChain && !isValidEvmAddress) {\n return this.sendJson(res, 400, { error: 'Invalid EVM wallet address format' });\n }\n\n // Validate amount\n const amountNum = parseFloat(amount);\n if (isNaN(amountNum) || amountNum <= 0) {\n return this.sendJson(res, 400, { error: 'Invalid amount' });\n }\n\n // Build a synthetic service config for payment\n const proxyConfig: ServiceConfig = {\n id: serviceId || 'proxy',\n name: description || 'Proxy Payment',\n description: description || '',\n price: amountNum,\n currency: currency || 'USDC',\n function: '', // Not used\n input: {},\n output: {},\n };\n\n // ========== MPP Protocol for tempo_moderato ==========\n if (chain === 'tempo_moderato') {\n return await this.handleProxyMPP(body, proxyConfig, authHeader, res);\n }\n\n // ========== x402 Protocol for other chains ==========\n // Build payment requirements with the provided wallet and chain\n const requirements = this.buildProxyPaymentRequirements(proxyConfig, wallet, currency, chain);\n\n // If no payment header, return 402 with payment requirements\n if (!paymentHeader) {\n return this.sendProxyPaymentRequired(proxyConfig, wallet, memo, chain, res);\n }\n\n // Parse payment payload\n let payment: X402PaymentPayload;\n try {\n const decoded = Buffer.from(paymentHeader, 'base64').toString('utf-8');\n payment = JSON.parse(decoded);\n } catch {\n return this.sendJson(res, 400, { error: 'Invalid X-Payment header' });\n }\n\n // Validate basic payment fields\n if (payment.x402Version !== X402_VERSION) {\n return this.sendJson(res, 402, { error: `Unsupported x402 version: ${payment.x402Version}` });\n }\n\n const scheme = payment.accepted?.scheme || payment.scheme;\n const network = payment.accepted?.network || payment.network;\n\n if (scheme !== 'exact') {\n return this.sendJson(res, 402, { error: `Unsupported scheme: ${scheme}` });\n }\n\n // Validate network matches requested chain (or default to provider's network)\n const expectedNetwork = chain ? (CHAIN_TO_NETWORK[chain] || this.networkId) : this.networkId;\n if (network !== expectedNetwork) {\n return this.sendJson(res, 402, { error: `Network mismatch: expected ${expectedNetwork}, got ${network}` });\n }\n\n // Verify payment with facilitator\n console.log(`[MoltsPay] /proxy: Verifying payment for ${wallet}...`);\n const verifyResult = await this.registry.verify(payment, requirements);\n if (!verifyResult.valid) {\n return this.sendJson(res, 402, { \n success: false,\n error: `Payment verification failed: ${verifyResult.error}`,\n facilitator: verifyResult.facilitator,\n });\n }\n console.log(`[MoltsPay] /proxy: Verified by ${verifyResult.facilitator}`);\n\n // Check if execution requested\n const { execute, service, params } = body;\n \n // If execute requested, handle skill + payment\n if (execute && service) {\n const skill = this.skills.get(service);\n if (!skill) {\n // Service not found - don't settle, return error\n console.log(`[MoltsPay] /proxy: Service not found: ${service} - NOT settling`);\n return this.sendJson(res, 404, {\n success: false,\n paymentSettled: false,\n error: `Service not found: ${service}`,\n });\n }\n\n // For Solana: settle FIRST (blockhash expires quickly ~60s)\n // For EVM: pay-for-success (execute first, settle after)\n const isSolana = isSolanaNetwork(network);\n let settlement: any = null;\n\n if (isSolana) {\n console.log(`[MoltsPay] /proxy: Solana detected - settling payment FIRST`);\n try {\n settlement = await this.registry.settle(payment, requirements);\n console.log(`[MoltsPay] /proxy: Payment settled by ${settlement.facilitator}: ${settlement.transaction || 'pending'}`);\n \n // Check if settlement actually succeeded (registry returns {success: false} on failure)\n if (!settlement.success) {\n console.error(`[MoltsPay] /proxy: Solana settlement failed: ${settlement.error}`);\n return this.sendJson(res, 402, {\n success: false,\n paymentSettled: false,\n error: `Payment settlement failed: ${settlement.error || 'Unknown error'}`,\n });\n }\n } catch (err: any) {\n console.error('[MoltsPay] /proxy: Solana settlement failed:', err.message);\n return this.sendJson(res, 402, {\n success: false,\n paymentSettled: false,\n error: `Payment settlement failed: ${err.message}`,\n });\n }\n } else {\n console.log(`[MoltsPay] /proxy: Executing skill first (pay on success): ${service}`);\n }\n\n // Execute skill (with timeout)\n const timeoutSeconds = parseInt(process.env.SKILL_TIMEOUT_SECONDS || '1200');\n let result: any;\n try {\n result = await Promise.race([\n skill.handler(params || {}),\n new Promise((_, reject) => \n setTimeout(() => reject(new Error(`Skill timeout after ${timeoutSeconds}s`)), timeoutSeconds * 1000)\n )\n ]);\n console.log(`[MoltsPay] /proxy: Skill succeeded`);\n } catch (err: any) {\n // Skill failed or timeout\n console.error(`[MoltsPay] /proxy: Skill failed: ${err.message}`);\n // For Solana: payment already settled, skill failed - no refund (user accepted risk)\n // For EVM: payment not settled yet, user keeps their money\n return this.sendJson(res, 500, {\n success: false,\n paymentSettled: isSolana ? true : false,\n error: `Service execution failed: ${err.message}`,\n note: isSolana ? 'Payment was settled before execution. Contact support for refund.' : undefined,\n });\n }\n\n // For EVM: settle payment now (pay-for-success)\n if (!isSolana) {\n console.log(`[MoltsPay] /proxy: Settling payment...`);\n try {\n settlement = await this.registry.settle(payment, requirements);\n console.log(`[MoltsPay] /proxy: Payment settled by ${settlement.facilitator}: ${settlement.transaction || 'pending'}`);\n } catch (err: any) {\n console.error('[MoltsPay] /proxy: Settlement failed:', err.message);\n // Skill succeeded but settlement failed - return result anyway with warning\n return this.sendJson(res, 200, {\n success: true,\n verified: true,\n settled: false,\n settlementError: err.message,\n from: (payment.payload as any)?.authorization?.from,\n paidTo: wallet,\n amount: amountNum,\n currency: currency || 'USDC',\n memo,\n result,\n });\n }\n }\n\n return this.sendJson(res, 200, {\n success: true,\n verified: true,\n settled: settlement?.success || false,\n txHash: settlement?.transaction,\n from: (payment.payload as any)?.authorization?.from,\n paidTo: wallet,\n amount: amountNum,\n currency: currency || 'USDC',\n facilitator: settlement?.facilitator,\n memo,\n result,\n });\n }\n\n // No execution requested - settle immediately (payment-only mode)\n console.log(`[MoltsPay] /proxy: Settling payment (no execution)...`);\n let settlement: any = null;\n try {\n settlement = await this.registry.settle(payment, requirements);\n console.log(`[MoltsPay] /proxy: Payment settled by ${settlement.facilitator}: ${settlement.transaction || 'pending'}`);\n } catch (err: any) {\n console.error('[MoltsPay] /proxy: Settlement failed:', err.message);\n return this.sendJson(res, 500, {\n success: false,\n error: `Settlement failed: ${err.message}`,\n });\n }\n\n // Return success (payment only, no execution)\n this.sendJson(res, 200, {\n success: true,\n verified: true,\n settled: settlement?.success || false,\n txHash: settlement?.transaction,\n from: (payment.payload as any)?.authorization?.from, // Buyer's wallet address\n paidTo: wallet,\n amount: amountNum,\n currency: currency || 'USDC',\n facilitator: settlement?.facilitator,\n memo,\n });\n }\n\n /**\n * Handle MPP payment flow for /proxy endpoint (tempo_moderato chain)\n */\n private async handleProxyMPP(\n body: any,\n config: ServiceConfig,\n authHeader: string | undefined,\n res: ServerResponse\n ): Promise<void> {\n const { wallet, amount, memo, serviceId } = body;\n const amountNum = parseFloat(amount);\n const amountInUnits = Math.floor(amountNum * 1e6).toString();\n \n // If no Authorization header, return 402 with WWW-Authenticate\n if (!authHeader || !authHeader.toLowerCase().startsWith('payment ')) {\n const challengeId = this.generateChallengeId();\n const tokenAddress = TOKEN_ADDRESSES['eip155:42431']?.USDC || '0x20c0000000000000000000000000000000000000';\n \n const mppRequest = {\n amount: amountInUnits,\n currency: tokenAddress,\n methodDetails: {\n chainId: 42431,\n feePayer: true,\n },\n recipient: wallet,\n };\n const mppRequestEncoded = Buffer.from(JSON.stringify(mppRequest)).toString('base64');\n \n const expiresAt = new Date(Date.now() + 5 * 60 * 1000).toISOString();\n \n const wwwAuth = `Payment id=\"${challengeId}\", realm=\"MoltsPay Proxy\", method=\"tempo\", intent=\"charge\", request=\"${mppRequestEncoded}\", description=\"${config.name}\", expires=\"${expiresAt}\"`;\n \n res.writeHead(402, {\n 'Content-Type': 'application/problem+json',\n [MPP_WWW_AUTH_HEADER]: wwwAuth,\n });\n res.end(JSON.stringify({\n type: 'https://paymentauth.org/problems/payment-required',\n title: 'Payment Required',\n status: 402,\n detail: `Payment is required (${config.name}).`,\n service: serviceId || 'proxy',\n price: amountNum,\n currency: 'USDC',\n }, null, 2));\n return;\n }\n\n // Parse MPP credential: \"Payment <base64>\"\n const credentialMatch = authHeader.match(/Payment\\s+(.+)/i);\n if (!credentialMatch) {\n return this.sendJson(res, 400, { error: 'Invalid Authorization header format' });\n }\n\n let mppCredential: {\n challenge: { id: string; realm: string; method: string; intent: string; request: any };\n payload: { hash?: string; type: 'hash' | 'transaction' };\n source?: string;\n };\n \n try {\n const base64 = credentialMatch[1].replace(/-/g, '+').replace(/_/g, '/');\n const decoded = Buffer.from(base64, 'base64').toString('utf-8');\n mppCredential = JSON.parse(decoded);\n } catch (err) {\n console.error('[MoltsPay] /proxy MPP: Failed to parse credential:', err);\n return this.sendJson(res, 400, { error: 'Invalid payment credential encoding' });\n }\n\n // Extract transaction hash\n let txHash: string | undefined;\n if (mppCredential.payload?.type === 'hash' && mppCredential.payload?.hash) {\n txHash = mppCredential.payload.hash;\n } else {\n return this.sendJson(res, 400, { error: 'Missing transaction hash in credential' });\n }\n\n console.log(`[MoltsPay] /proxy MPP: Verifying tx ${txHash} on Tempo...`);\n\n // Build requirements for verification\n const requirements = this.buildPaymentRequirements(config, 'eip155:42431', wallet, 'USDC');\n\n // Create x402-compatible payload for facilitator\n const paymentPayload: X402PaymentPayload = {\n x402Version: X402_VERSION,\n scheme: 'exact',\n network: 'eip155:42431',\n payload: { txHash, chainId: 42431 },\n };\n\n // Verify payment using facilitator registry\n const verification = await this.registry.verify(paymentPayload, requirements);\n \n if (!verification.valid) {\n return this.sendJson(res, 402, { \n error: `Payment verification failed: ${verification.error}` \n });\n }\n\n console.log(`[MoltsPay] /proxy MPP: Payment verified by ${verification.facilitator}`);\n\n // Check if execution requested\n const { execute, service, params } = body;\n \n if (execute && service) {\n console.log(`[MoltsPay] /proxy MPP: Executing skill: ${service}`);\n const skill = this.skills.get(service);\n if (!skill) {\n return this.sendJson(res, 404, {\n success: false,\n paymentSettled: true, // Payment already happened on Tempo\n error: `Service not found: ${service}`,\n });\n }\n\n // Execute skill\n const timeoutSeconds = parseInt(process.env.SKILL_TIMEOUT_SECONDS || '1200');\n let result: any;\n try {\n result = await Promise.race([\n skill.handler(params || {}),\n new Promise((_, reject) => \n setTimeout(() => reject(new Error(`Skill timeout after ${timeoutSeconds}s`)), timeoutSeconds * 1000)\n )\n ]);\n } catch (err: any) {\n console.error(`[MoltsPay] /proxy MPP: Skill failed: ${err.message}`);\n return this.sendJson(res, 500, {\n success: false,\n paymentSettled: true,\n error: `Service execution failed: ${err.message}`,\n });\n }\n\n return this.sendJson(res, 200, {\n success: true,\n verified: true,\n txHash,\n chain: 'tempo_moderato',\n paidTo: wallet,\n amount: amountNum,\n currency: 'USDC',\n facilitator: verification.facilitator,\n memo,\n result,\n });\n }\n\n // No execution requested - just return verification success\n this.sendJson(res, 200, {\n success: true,\n verified: true,\n txHash,\n chain: 'tempo_moderato',\n paidTo: wallet,\n amount: amountNum,\n currency: 'USDC',\n facilitator: verification.facilitator,\n memo,\n });\n }\n\n /**\n * Build payment requirements for proxy endpoint (uses provided wallet)\n */\n private buildProxyPaymentRequirements(config: ServiceConfig, wallet: string, token?: string, chain?: string): X402PaymentRequirements {\n const amountInUnits = Math.floor(config.price * 1e6).toString();\n const acceptedTokens = getAcceptedCurrencies(config);\n \n // Determine network from chain parameter or use default\n const networkId = chain ? (CHAIN_TO_NETWORK[chain] || this.networkId) : this.networkId;\n \n // Use specified token or default to first accepted\n const selectedToken = token && acceptedTokens.includes(token) ? token : acceptedTokens[0];\n const tokenAddresses = TOKEN_ADDRESSES[networkId] || TOKEN_ADDRESSES[this.networkId] || {};\n const tokenAddress = tokenAddresses[selectedToken];\n const tokenDomain = getTokenDomain(networkId, selectedToken);\n\n const requirements: X402PaymentRequirements = {\n scheme: 'exact',\n network: networkId,\n asset: tokenAddress,\n amount: amountInUnits,\n payTo: wallet, // Use provided wallet, not manifest\n maxTimeoutSeconds: 300,\n extra: tokenDomain,\n };\n\n // For BNB: include spender address for client approval\n if (networkId === 'eip155:56' || networkId === 'eip155:97') {\n const bnbFacilitator = this.registry.get('bnb') as any;\n const spenderAddress = bnbFacilitator?.getSpenderAddress?.();\n if (spenderAddress) {\n (requirements.extra as any) = {\n ...(requirements.extra || {}),\n bnbSpender: spenderAddress,\n };\n }\n }\n\n return requirements;\n }\n\n /**\n * Return 402 with x402 payment requirements for proxy endpoint\n */\n private sendProxyPaymentRequired(\n config: ServiceConfig, \n wallet: string,\n memo: string | undefined,\n chain: string | undefined,\n res: ServerResponse\n ): void {\n const requirements = this.buildProxyPaymentRequirements(config, wallet, config.currency, chain);\n\n const paymentRequired = {\n x402Version: X402_VERSION,\n accepts: [requirements],\n resource: {\n url: `/proxy`,\n description: `${config.name} - $${config.price} ${config.currency}`,\n mimeType: 'application/json',\n memo,\n },\n };\n\n const encoded = Buffer.from(JSON.stringify(paymentRequired)).toString('base64');\n\n res.writeHead(402, {\n 'Content-Type': 'application/json',\n [PAYMENT_REQUIRED_HEADER]: encoded,\n });\n res.end(JSON.stringify({\n error: 'Payment required',\n message: `Payment requires $${config.price} ${config.currency}`,\n x402: paymentRequired,\n }, null, 2));\n }\n}\n","/**\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","/**\n * MoltsPay Client - Pay for AI Agent services\n * \n * Uses x402 protocol for gasless, pay-for-success payments.\n * \n * Usage:\n * const client = new MoltsPayClient(); // Loads from ~/.moltspay/\n * const services = await client.getServices('http://provider:3000');\n * const result = await client.pay('http://provider:3000', 'text-to-video', { prompt: '...' });\n */\n\nimport { existsSync, readFileSync, writeFileSync, mkdirSync, statSync, chmodSync } from 'fs';\nimport { homedir } from 'os';\nimport { join } from 'path';\nimport { Wallet, ethers } from 'ethers';\nimport { getChain, type ChainName, type EvmChainName, type TokenSymbol, type ChainConfig } from '../chains/index.js';\nimport { SOLANA_CHAINS, type SolanaChainName } from '../chains/solana.js';\nimport { loadSolanaWallet, getSolanaAddress } from '../wallet/solana.js';\nimport { createSolanaPaymentTransaction } from '../facilitators/solana.js';\nimport { Connection, PublicKey, Keypair } from '@solana/web3.js';\nimport {\n ClientConfig,\n WalletData,\n ServicesResponse,\n MoltsPayClientOptions,\n} from './types.js';\n\nexport * from './types.js';\n\nexport interface PayOptions {\n /** Token to pay with (default: USDC, or auto-select based on balance) */\n token?: TokenSymbol;\n /** Auto-select token based on balance (default: false) */\n autoSelect?: boolean;\n /** Chain to pay on */\n chain?: 'base' | 'polygon' | 'base_sepolia' | 'tempo_moderato' | 'bnb' | 'bnb_testnet' | 'solana' | 'solana_devnet';\n}\n\n// x402 constants\nconst X402_VERSION = 2;\nconst PAYMENT_REQUIRED_HEADER = 'x-payment-required';\nconst PAYMENT_HEADER = 'x-payment';\n\ninterface X402PaymentRequirements {\n scheme: string;\n network: string;\n // v2 fields\n amount?: string;\n asset?: string;\n payTo?: string;\n maxTimeoutSeconds?: number;\n extra?: Record<string, unknown>;\n // v1 fields (legacy)\n maxAmountRequired?: string;\n resource?: string;\n description?: string;\n}\n\ninterface EIP3009Authorization {\n from: string;\n to: string;\n value: string;\n validAfter: string;\n validBefore: string;\n nonce: string;\n}\n\nconst DEFAULT_CONFIG: ClientConfig = {\n chain: 'base',\n limits: {\n maxPerTx: 100,\n maxPerDay: 1000,\n },\n};\n\nexport class MoltsPayClient {\n private configDir: string;\n private config: ClientConfig;\n private walletData: WalletData | null = null;\n private wallet: Wallet | null = null;\n private todaySpending: number = 0;\n private lastSpendingReset: number = 0;\n\n constructor(options: MoltsPayClientOptions = {}) {\n this.configDir = options.configDir || join(homedir(), '.moltspay');\n this.config = this.loadConfig();\n this.walletData = this.loadWallet();\n this.loadSpending(); // Load persisted spending data\n \n if (this.walletData) {\n this.wallet = new Wallet(this.walletData.privateKey);\n }\n }\n\n /**\n * Check if client is initialized (has wallet)\n */\n get isInitialized(): boolean {\n return this.wallet !== null;\n }\n\n /**\n * Get wallet address\n */\n get address(): string | null {\n return this.wallet?.address || null;\n }\n\n /**\n * Get wallet instance (for direct operations like approvals)\n */\n getWallet(): Wallet | null {\n return this.wallet;\n }\n\n /**\n * Get current config\n */\n getConfig(): ClientConfig {\n return { ...this.config };\n }\n\n /**\n * Update config\n */\n updateConfig(updates: Partial<ClientConfig['limits']>): void {\n if (updates.maxPerTx !== undefined) {\n this.config.limits.maxPerTx = updates.maxPerTx;\n }\n if (updates.maxPerDay !== undefined) {\n this.config.limits.maxPerDay = updates.maxPerDay;\n }\n this.saveConfig();\n }\n\n /**\n * Get services from a provider\n */\n async getServices(serverUrl: string): Promise<ServicesResponse> {\n // Normalize URL - don't append /services if already present\n const normalizedUrl = serverUrl.replace(/\\/(services|api\\/services|registry\\/services)\\/?$/, '');\n \n // Try /services first (standard provider endpoint)\n const endpoints = ['/services', '/api/services', '/registry/services'];\n \n for (const endpoint of endpoints) {\n try {\n const res = await fetch(`${normalizedUrl}${endpoint}`);\n if (!res.ok) continue;\n \n const contentType = res.headers.get('content-type') || '';\n if (!contentType.includes('application/json')) continue;\n \n return await res.json() as ServicesResponse;\n } catch {\n continue;\n }\n }\n \n throw new Error(`Failed to get services: no valid endpoint found at ${normalizedUrl}`);\n }\n\n /**\n * Pay for a service and get the result (x402 protocol)\n * \n * This is GASLESS for the client - server pays gas to claim payment.\n * This is PAY-FOR-SUCCESS - payment only claimed if service succeeds.\n * \n * @param serverUrl - Server URL\n * @param service - Service ID\n * @param params - Service parameters\n * @param options - Payment options (token selection)\n */\n async pay(\n serverUrl: string,\n service: string,\n params: Record<string, any>,\n options: PayOptions = {}\n ): Promise<Record<string, any>> {\n if (!this.wallet || !this.walletData) {\n throw new Error('Client not initialized. Run: npx moltspay init');\n }\n\n // Step 1: Make initial request without payment\n console.log(`[MoltsPay] Requesting service: ${service}`);\n const requestBody: any = { service, params };\n if (options.chain) {\n requestBody.chain = options.chain;\n }\n const initialRes = await fetch(`${serverUrl}/execute`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(requestBody),\n });\n\n // If not 402, check for success or error\n if (initialRes.status !== 402) {\n const data = await initialRes.json() as any;\n if (initialRes.ok && data.result) {\n return data.result;\n }\n throw new Error(data.error || 'Unexpected response');\n }\n\n // Step 2: Detect protocol from 402 response\n // MPP uses WWW-Authenticate header, x402 uses X-Payment-Required header\n const wwwAuthHeader = initialRes.headers.get('www-authenticate');\n const paymentRequiredHeader = initialRes.headers.get(PAYMENT_REQUIRED_HEADER);\n \n // If WWW-Authenticate with Payment scheme, use MPP flow\n if (wwwAuthHeader && wwwAuthHeader.toLowerCase().includes('payment')) {\n console.log('[MoltsPay] Detected MPP protocol, using Tempo flow...');\n return await this.handleMPPPayment(serverUrl, service, params, wwwAuthHeader);\n }\n \n if (!paymentRequiredHeader) {\n throw new Error('Missing payment header (x-payment-required or www-authenticate)');\n }\n\n let requirements: X402PaymentRequirements[];\n try {\n const decoded = Buffer.from(paymentRequiredHeader, 'base64').toString('utf-8');\n const parsed = JSON.parse(decoded);\n \n // Handle both v1 (array) and v2 (object with accepts) formats\n if (Array.isArray(parsed)) {\n // v1 format: direct array of requirements\n requirements = parsed;\n } else if (parsed.accepts && Array.isArray(parsed.accepts)) {\n // v2 format: { x402Version: 2, accepts: [...] }\n requirements = parsed.accepts;\n } else {\n // Single requirement object\n requirements = [parsed];\n }\n } catch {\n throw new Error('Invalid x-payment-required header');\n }\n\n // Helper to convert network ID to chain name\n const networkToChainName = (network: string): string | null => {\n // Handle Solana networks\n if (network === 'solana:mainnet') return 'solana';\n if (network === 'solana:devnet') return 'solana_devnet';\n \n // Handle EVM networks\n const match = network.match(/^eip155:(\\d+)$/);\n if (!match) return null;\n const chainId = parseInt(match[1]);\n if (chainId === 8453) return 'base';\n if (chainId === 137) return 'polygon';\n if (chainId === 84532) return 'base_sepolia';\n if (chainId === 42431) return 'tempo_moderato';\n if (chainId === 56) return 'bnb';\n if (chainId === 97) return 'bnb_testnet';\n return null;\n };\n\n // Get server's accepted chains\n const serverChains = requirements\n .map(r => networkToChainName(r.network))\n .filter((c): c is string => c !== null);\n\n // Determine which chain to use\n const userSpecifiedChain = options.chain;\n let selectedChain: string;\n\n if (userSpecifiedChain) {\n // User specified --chain, validate it's accepted by server\n if (!serverChains.includes(userSpecifiedChain)) {\n throw new Error(\n `Server doesn't accept '${userSpecifiedChain}'.\\n` +\n `Server accepts: ${serverChains.join(', ')}`\n );\n }\n selectedChain = userSpecifiedChain;\n } else {\n // No --chain provided\n if (serverChains.length === 1 && serverChains[0] === 'base') {\n // Only default to base if server ONLY accepts base\n selectedChain = 'base';\n } else {\n throw new Error(\n `Server accepts: ${serverChains.join(', ')}\\n` +\n `Please specify: --chain <chain_name>`\n );\n }\n }\n\n // Handle Solana chains separately\n if (selectedChain === 'solana' || selectedChain === 'solana_devnet') {\n const solanaChain = selectedChain as SolanaChainName;\n const network = solanaChain === 'solana' ? 'solana:mainnet' : 'solana:devnet';\n const req = requirements.find(r => r.network === network);\n \n if (!req) {\n throw new Error(`Failed to find payment requirement for ${selectedChain}`);\n }\n \n return await this.handleSolanaPayment(serverUrl, service, params, req, solanaChain);\n }\n\n // EVM chain handling\n const chainName = selectedChain as EvmChainName;\n const chain = getChain(chainName);\n const network = `eip155:${chain.chainId}`;\n const req = requirements.find(r => r.scheme === 'exact' && r.network === network);\n\n if (!req) {\n throw new Error(`Failed to find payment requirement for ${chainName}`);\n }\n\n // Step 3: Check limits\n // v2 uses 'amount', v1 uses 'maxAmountRequired'\n const amountRaw = req.amount || req.maxAmountRequired;\n if (!amountRaw) {\n throw new Error('Missing amount in payment requirements');\n }\n const amount = Number(amountRaw) / 1e6;\n this.checkLimits(amount);\n\n // Determine which token to use\n let token: TokenSymbol = options.token || 'USDC';\n \n // Auto-select token based on balance if requested\n if (options.autoSelect) {\n const balances = await this.getBalance();\n if (balances.usdc >= amount) {\n token = 'USDC';\n } else if (balances.usdt >= amount) {\n token = 'USDT';\n } else {\n throw new Error(`Insufficient balance: need $${amount}, have ${balances.usdc} USDC / ${balances.usdt} USDT`);\n }\n }\n\n // USDT does not support gasless transfers (no EIP-2612 permit)\n // It requires on-chain approve + transfer, meaning the user pays gas\n if (token === 'USDT') {\n const balances = await this.getBalance();\n if (balances.native < 0.0001) {\n throw new Error(\n `USDT requires ETH for gas (~$0.01 on Base). ` +\n `Your ETH balance: ${balances.native.toFixed(6)} ETH. ` +\n `Please add a small amount of ETH to your wallet, or use USDC (gasless).`\n );\n }\n console.log(`[MoltsPay] ⚠️ USDT requires gas (~$0.01). Proceeding with payment...`);\n } else {\n console.log(`[MoltsPay] Signing payment: $${amount} ${token} (gasless)`);\n }\n\n // BNB chains use intent-based flow (pre-approval + intent signature)\n if (chainName === 'bnb' || chainName === 'bnb_testnet') {\n console.log(`[MoltsPay] Using BNB intent-based payment flow...`);\n const payTo = req.payTo || req.resource;\n if (!payTo) {\n throw new Error('Missing payTo address in payment requirements');\n }\n // Get spender address from server response (dynamic, not hardcoded)\n const bnbSpender = (req.extra as any)?.bnbSpender;\n if (!bnbSpender) {\n throw new Error('Server did not provide bnbSpender address. Server may not support BNB payments.');\n }\n return await this.handleBNBPayment(serverUrl, service, params, {\n to: payTo,\n amount,\n token,\n chainName,\n chain,\n spender: bnbSpender,\n });\n }\n\n // Step 4: Sign EIP-3009 authorization (GASLESS - just signing)\n // payTo is the recipient address (v2 format)\n const payTo = req.payTo || req.resource; // fallback for v1 compatibility\n if (!payTo) {\n throw new Error('Missing payTo address in payment requirements');\n }\n \n // Use server's extra field for domain info (contains correct EIP-712 domain for the token on this network)\n const domainOverride = (req.extra && typeof req.extra === 'object' && req.extra.name) \n ? { name: req.extra.name as string, version: (req.extra.version as string) || '2' }\n : undefined;\n \n const authorization = await this.signEIP3009(payTo, amount, chain, token, domainOverride);\n\n // Get token-specific info for accepted field\n const tokenConfig = chain.tokens[token];\n\n // Step 5: Create x402 payment payload (v2 requires scheme, network, payload, AND accepted)\n // Use server's extra field if provided (contains correct EIP-712 domain for the token on this network)\n // Fall back to local config for backward compatibility\n const extra = (req.extra && typeof req.extra === 'object') \n ? req.extra \n : {\n name: (tokenConfig as any).eip712Name || 'USD Coin',\n version: '2',\n };\n \n const payload = {\n x402Version: X402_VERSION,\n scheme: 'exact',\n network,\n payload: authorization, // { authorization: {...}, signature: \"0x...\" }\n accepted: {\n scheme: 'exact',\n network,\n asset: tokenConfig.address,\n amount: amountRaw,\n payTo,\n maxTimeoutSeconds: req.maxTimeoutSeconds || 300,\n extra,\n },\n };\n const paymentHeader = Buffer.from(JSON.stringify(payload)).toString('base64');\n\n // Step 6: Retry with payment header\n console.log(`[MoltsPay] Sending request with payment...`);\n const paidRequestBody: any = { service, params };\n if (options.chain) {\n paidRequestBody.chain = options.chain;\n }\n const paidRes = await fetch(`${serverUrl}/execute`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n [PAYMENT_HEADER]: paymentHeader,\n },\n body: JSON.stringify(paidRequestBody),\n });\n\n const result = await paidRes.json() as any;\n\n if (!paidRes.ok) {\n throw new Error(result.error || 'Service execution failed');\n }\n\n // Update spending tracking\n this.recordSpending(amount);\n\n console.log(`[MoltsPay] Success! Payment: ${result.payment?.status || 'claimed'}`);\n \n return result.result;\n }\n\n /**\n * Handle MPP (Machine Payments Protocol) payment flow\n * Called when pay() detects WWW-Authenticate header in 402 response\n */\n private async handleMPPPayment(\n serverUrl: string,\n service: string,\n params: Record<string, any>,\n wwwAuthHeader: string\n ): Promise<Record<string, any>> {\n // Dynamic imports for ESM-only packages\n const { privateKeyToAccount } = await import('viem/accounts');\n const { createWalletClient, createPublicClient, http } = await import('viem');\n const { tempoModerato } = await import('viem/chains');\n const { Actions } = await import('viem/tempo');\n\n // Get private key from wallet data\n const privateKey = this.walletData!.privateKey as `0x${string}`;\n const account = privateKeyToAccount(privateKey);\n\n console.log(`[MoltsPay] Using MPP protocol on Tempo`);\n console.log(`[MoltsPay] Account: ${account.address}`);\n\n // Parse WWW-Authenticate: Payment id=\"...\", method=\"tempo\", request=\"...\"\n const parseAuthParam = (header: string, key: string): string | null => {\n const match = header.match(new RegExp(`${key}=\"([^\"]+)\"`, 'i'));\n return match ? match[1] : null;\n };\n\n const challengeId = parseAuthParam(wwwAuthHeader, 'id');\n const method = parseAuthParam(wwwAuthHeader, 'method');\n const realm = parseAuthParam(wwwAuthHeader, 'realm');\n const requestB64 = parseAuthParam(wwwAuthHeader, 'request');\n\n if (method !== 'tempo') {\n throw new Error(`Unsupported payment method: ${method}`);\n }\n\n if (!requestB64) {\n throw new Error('Missing request in WWW-Authenticate');\n }\n\n // Decode payment request\n const requestJson = Buffer.from(requestB64, 'base64').toString('utf-8');\n const paymentRequest = JSON.parse(requestJson);\n \n const { amount, currency, recipient, methodDetails } = paymentRequest;\n const chainId = methodDetails?.chainId || 42431;\n const amountDisplay = Number(amount) / 1e6;\n\n console.log(`[MoltsPay] Payment: $${amountDisplay} to ${recipient}`);\n\n // Check limits\n this.checkLimits(amountDisplay);\n\n // Execute transfer on Tempo\n console.log(`[MoltsPay] Sending transaction on Tempo...`);\n\n const tempoChain = { ...tempoModerato, feeToken: currency as `0x${string}` };\n \n const publicClient = createPublicClient({\n chain: tempoChain,\n transport: http('https://rpc.moderato.tempo.xyz'),\n });\n\n const walletClient = createWalletClient({\n account,\n chain: tempoChain,\n transport: http('https://rpc.moderato.tempo.xyz'),\n });\n\n // TIP-20 transfer\n const txHash = await Actions.token.transfer(walletClient, {\n to: recipient as `0x${string}`,\n amount: BigInt(amount),\n token: currency as `0x${string}`,\n });\n\n console.log(`[MoltsPay] Transaction: ${txHash}`);\n\n // Wait for confirmation\n await publicClient.waitForTransactionReceipt({ hash: txHash });\n console.log(`[MoltsPay] Confirmed! Retrying with credential...`);\n\n // Build credential\n const credential = {\n challenge: {\n id: challengeId,\n realm,\n method: 'tempo',\n intent: 'charge',\n request: paymentRequest,\n },\n payload: { hash: txHash, type: 'hash' },\n source: `did:pkh:eip155:${chainId}:${account.address}`,\n };\n\n const credentialB64 = Buffer.from(JSON.stringify(credential))\n .toString('base64')\n .replace(/\\+/g, '-')\n .replace(/\\//g, '_')\n .replace(/=+$/, '');\n\n // Retry with credential\n const paidRes = await fetch(`${serverUrl}/execute`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Payment ${credentialB64}`,\n },\n body: JSON.stringify({ service, params, chain: 'tempo_moderato' }),\n });\n\n const result = await paidRes.json() as any;\n\n if (!paidRes.ok) {\n throw new Error(result.error || 'Payment verification failed');\n }\n\n // Update spending tracking\n this.recordSpending(amountDisplay);\n\n console.log(`[MoltsPay] Success!`);\n return result.result || result;\n }\n\n /**\n * Handle BNB Chain payment flow (pre-approval + intent signature)\n * \n * Flow:\n * 1. Check client has approved server wallet (done via `moltspay init`)\n * 2. Sign EIP-712 payment intent (no gas, just signature)\n * 3. Send intent to server\n * 4. Server executes service\n * 5. Server calls transferFrom if successful (pay-for-success)\n */\n private async handleBNBPayment(\n serverUrl: string,\n service: string,\n params: Record<string, any>,\n paymentDetails: {\n to: string;\n amount: number;\n token: TokenSymbol;\n chainName: ChainName;\n chain: ChainConfig;\n spender: string;\n }\n ): Promise<Record<string, any>> {\n const { to, amount, token, chainName, chain, spender } = paymentDetails;\n const tokenConfig = chain.tokens[token];\n \n // Check approval status\n const provider = new ethers.JsonRpcProvider(chain.rpc);\n const allowance = await this.checkAllowance(tokenConfig.address, spender, provider);\n const amountWeiCheck = BigInt(Math.floor(amount * (10 ** tokenConfig.decimals)));\n \n if (allowance < amountWeiCheck) {\n // Check if user has enough BNB for gas to approve\n const nativeBalance = await provider.getBalance(this.wallet!.address);\n const minGasBalance = ethers.parseEther('0.0005'); // ~0.0005 BNB minimum for approval\n \n if (nativeBalance < minGasBalance) {\n const nativeBNB = parseFloat(ethers.formatEther(nativeBalance)).toFixed(4);\n const isTestnet = chainName === 'bnb_testnet';\n \n if (isTestnet) {\n throw new Error(\n `❌ Insufficient tBNB for approval transaction\\n\\n` +\n ` Current tBNB: ${nativeBNB}\\n` +\n ` Required: ~0.001 tBNB\\n\\n` +\n ` Get testnet tokens: npx moltspay faucet --chain bnb_testnet\\n` +\n ` (Gives USDC + tBNB for gas)`\n );\n } else {\n throw new Error(\n `❌ Insufficient BNB for approval transaction\\n\\n` +\n ` Current BNB: ${nativeBNB}\\n` +\n ` Required: ~0.001 BNB (~$0.60)\\n\\n` +\n ` To get BNB:\\n` +\n ` • Withdraw from Binance/exchange to your wallet\\n` +\n ` • Most exchanges include BNB dust with withdrawals\\n\\n` +\n ` After funding, run:\\n` +\n ` npx moltspay approve --chain ${chainName} --spender ${spender}`\n );\n }\n }\n \n throw new Error(\n `Insufficient allowance for ${spender.slice(0, 10)}...\\n` +\n `Run: npx moltspay approve --chain ${chainName} --spender ${spender}`\n );\n }\n \n // Convert amount to wei (BNB uses 18 decimals)\n const amountWei = BigInt(Math.floor(amount * (10 ** tokenConfig.decimals))).toString();\n \n // Create payment intent\n const intent = {\n from: this.wallet!.address,\n to,\n amount: amountWei,\n token: tokenConfig.address,\n service,\n nonce: Date.now(), // Use timestamp as nonce for simplicity\n deadline: Date.now() + 3600000, // 1 hour\n };\n\n // EIP-712 domain\n const domain = {\n name: 'MoltsPay',\n version: '1',\n chainId: chain.chainId,\n };\n\n // EIP-712 types\n const 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 // Sign the intent\n console.log(`[MoltsPay] Signing BNB payment intent...`);\n const signature = await this.wallet!.signTypedData(domain, types, intent);\n\n // Create x402 payment payload with BNB-specific format\n const network = `eip155:${chain.chainId}`;\n const payload = {\n x402Version: 2,\n scheme: 'exact',\n network,\n payload: {\n intent: {\n ...intent,\n signature,\n },\n chainId: chain.chainId,\n },\n accepted: {\n scheme: 'exact',\n network,\n asset: tokenConfig.address,\n amount: amountWei,\n payTo: to,\n maxTimeoutSeconds: 300,\n },\n };\n\n const paymentHeader = Buffer.from(JSON.stringify(payload)).toString('base64');\n\n // Send request with payment\n console.log(`[MoltsPay] Sending BNB payment request...`);\n const paidRes = await fetch(`${serverUrl}/execute`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-Payment': paymentHeader,\n },\n body: JSON.stringify({ service, params, chain: chainName }),\n });\n\n const result = await paidRes.json() as any;\n\n if (!paidRes.ok) {\n throw new Error(result.error || 'BNB payment failed');\n }\n\n // Update spending tracking\n this.recordSpending(amount);\n\n console.log(`[MoltsPay] Success! BNB payment settled.`);\n return result.result || result;\n }\n\n /**\n * Handle Solana payment flow\n * \n * Solana uses SPL token transfers with pay-for-success model:\n * 1. Client creates and signs a transfer transaction\n * 2. Server submits the transaction after service completes\n */\n private async handleSolanaPayment(\n serverUrl: string,\n service: string,\n params: Record<string, any>,\n requirements: X402PaymentRequirements,\n chain: SolanaChainName\n ): Promise<Record<string, any>> {\n // Load Solana wallet\n const solanaWallet = loadSolanaWallet(this.configDir);\n if (!solanaWallet) {\n throw new Error('No Solana wallet found. Run: npx moltspay init --chain solana_devnet');\n }\n\n const amount = Number(requirements.amount);\n const amountUSDC = amount / 1e6;\n \n // Check limits\n this.checkLimits(amountUSDC);\n\n console.log(`[MoltsPay] Creating Solana payment: $${amountUSDC} USDC`);\n\n // Validate payTo address\n if (!requirements.payTo) {\n throw new Error('Missing payTo address in payment requirements');\n }\n\n // Check for gasless mode (server pays fees)\n const solanaFeePayer = (requirements.extra as any)?.solanaFeePayer;\n const feePayerPubkey = solanaFeePayer ? new PublicKey(solanaFeePayer) : undefined;\n \n if (feePayerPubkey) {\n console.log(`[MoltsPay] Gasless mode: server pays fees`);\n }\n\n // Create the transfer transaction\n const recipientPubkey = new PublicKey(requirements.payTo);\n const transaction = await createSolanaPaymentTransaction(\n solanaWallet.publicKey,\n recipientPubkey,\n BigInt(amount),\n chain,\n feePayerPubkey // Optional fee payer for gasless mode\n );\n\n // Sign the transaction (partial sign if gasless mode)\n if (feePayerPubkey) {\n // Gasless mode: only sign for token transfer authority\n transaction.partialSign(solanaWallet);\n } else {\n // Normal mode: sign as both authority and fee payer\n transaction.sign(solanaWallet);\n }\n const signedTx = transaction.serialize({ requireAllSignatures: false }).toString('base64');\n\n console.log(`[MoltsPay] Transaction signed, sending to server...`);\n\n // Create x402 payload with Solana-specific format\n const network = chain === 'solana' ? 'solana:mainnet' : 'solana:devnet';\n const payload = {\n x402Version: 2,\n scheme: 'exact',\n network,\n payload: {\n signedTransaction: signedTx,\n sender: solanaWallet.publicKey.toBase58(),\n chain,\n },\n accepted: {\n scheme: 'exact',\n network,\n asset: requirements.asset,\n amount: requirements.amount,\n payTo: requirements.payTo,\n maxTimeoutSeconds: 300,\n },\n };\n\n const paymentHeader = Buffer.from(JSON.stringify(payload)).toString('base64');\n\n // Send request with payment\n const paidRes = await fetch(`${serverUrl}/execute`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-Payment': paymentHeader,\n },\n body: JSON.stringify({ service, params, chain }),\n });\n\n const result = await paidRes.json() as any;\n\n if (!paidRes.ok) {\n throw new Error(result.error || 'Solana payment failed');\n }\n\n // Update spending tracking\n this.recordSpending(amountUSDC);\n\n console.log(`[MoltsPay] Success! Solana payment settled.`);\n if (result.payment?.transaction) {\n const explorerUrl = chain === 'solana' \n ? `https://solscan.io/tx/${result.payment.transaction}`\n : `https://solscan.io/tx/${result.payment.transaction}?cluster=devnet`;\n console.log(`[MoltsPay] Transaction: ${explorerUrl}`);\n }\n\n return result.result || result;\n }\n\n /**\n * Check ERC20 allowance for a spender\n */\n private async checkAllowance(\n tokenAddress: string,\n spender: string,\n provider: ethers.JsonRpcProvider\n ): Promise<bigint> {\n const contract = new ethers.Contract(\n tokenAddress,\n ['function allowance(address owner, address spender) view returns (uint256)'],\n provider\n );\n return await contract.allowance(this.wallet!.address, spender);\n }\n\n /**\n * Sign EIP-3009 transferWithAuthorization (GASLESS)\n * This only signs - no on-chain transaction, no gas needed.\n * Supports both USDC and USDT.\n */\n private async signEIP3009(\n to: string,\n amount: number,\n chain: { chainId: number; tokens: Record<TokenSymbol, { address: string; decimals: number }> },\n token: TokenSymbol = 'USDC',\n domainOverride?: { name: string; version: string }\n ): Promise<{ authorization: EIP3009Authorization; signature: string }> {\n const validAfter = 0;\n const validBefore = Math.floor(Date.now() / 1000) + 3600; // 1 hour\n const nonce = ethers.hexlify(ethers.randomBytes(32));\n \n const tokenConfig = chain.tokens[token];\n const value = BigInt(Math.floor(amount * (10 ** tokenConfig.decimals))).toString();\n\n const authorization: EIP3009Authorization = {\n from: this.wallet!.address,\n to,\n value,\n validAfter: validAfter.toString(),\n validBefore: validBefore.toString(),\n nonce,\n };\n\n // EIP-712 domain - use server's domain info if provided (handles mainnet vs testnet differences)\n // Fall back to local token config for backward compatibility\n const tokenName = domainOverride?.name || (tokenConfig as any).eip712Name || (token === 'USDC' ? 'USD Coin' : 'Tether USD');\n const tokenVersion = domainOverride?.version || '2';\n const domain = {\n name: tokenName,\n version: tokenVersion,\n chainId: chain.chainId,\n verifyingContract: tokenConfig.address,\n };\n\n // EIP-3009 types\n const types = {\n TransferWithAuthorization: [\n { name: 'from', type: 'address' },\n { name: 'to', type: 'address' },\n { name: 'value', type: 'uint256' },\n { name: 'validAfter', type: 'uint256' },\n { name: 'validBefore', type: 'uint256' },\n { name: 'nonce', type: 'bytes32' },\n ],\n };\n\n const signature = await this.wallet!.signTypedData(domain, types, authorization);\n\n return { authorization, signature };\n }\n\n /**\n * Check spending limits\n */\n private checkLimits(amount: number): void {\n // Check per-tx limit\n if (amount > this.config.limits.maxPerTx) {\n throw new Error(\n `Amount $${amount} exceeds max per transaction ($${this.config.limits.maxPerTx})`\n );\n }\n\n // Reset daily spending if new day\n const today = new Date().setHours(0, 0, 0, 0);\n if (today > this.lastSpendingReset) {\n this.todaySpending = 0;\n this.lastSpendingReset = today;\n this.saveSpending(); // Persist reset\n }\n\n // Check daily limit\n if (this.todaySpending + amount > this.config.limits.maxPerDay) {\n throw new Error(\n `Would exceed daily limit ($${this.todaySpending} + $${amount} > $${this.config.limits.maxPerDay})`\n );\n }\n }\n\n /**\n * Record spending and persist to disk\n */\n private recordSpending(amount: number): void {\n this.todaySpending += amount;\n this.saveSpending();\n }\n\n // --- Config & Wallet Management ---\n\n private loadConfig(): ClientConfig {\n const configPath = join(this.configDir, 'config.json');\n if (existsSync(configPath)) {\n const content = readFileSync(configPath, 'utf-8');\n return { ...DEFAULT_CONFIG, ...JSON.parse(content) };\n }\n return { ...DEFAULT_CONFIG };\n }\n\n private saveConfig(): void {\n mkdirSync(this.configDir, { recursive: true });\n const configPath = join(this.configDir, 'config.json');\n writeFileSync(configPath, JSON.stringify(this.config, null, 2));\n }\n\n /**\n * Load spending data from disk\n */\n private loadSpending(): void {\n const spendingPath = join(this.configDir, 'spending.json');\n if (existsSync(spendingPath)) {\n try {\n const data = JSON.parse(readFileSync(spendingPath, 'utf-8'));\n const today = new Date().setHours(0, 0, 0, 0);\n \n // Only load if it's from today\n if (data.date && data.date === today) {\n this.todaySpending = data.amount || 0;\n this.lastSpendingReset = data.date;\n } else {\n // Data is from a previous day, reset\n this.todaySpending = 0;\n this.lastSpendingReset = today;\n }\n } catch {\n // Ignore parse errors, start fresh\n this.todaySpending = 0;\n this.lastSpendingReset = new Date().setHours(0, 0, 0, 0);\n }\n }\n }\n\n /**\n * Save spending data to disk\n */\n private saveSpending(): void {\n mkdirSync(this.configDir, { recursive: true });\n const spendingPath = join(this.configDir, 'spending.json');\n const data = {\n date: this.lastSpendingReset || new Date().setHours(0, 0, 0, 0),\n amount: this.todaySpending,\n updatedAt: Date.now(),\n };\n writeFileSync(spendingPath, JSON.stringify(data, null, 2));\n }\n\n private loadWallet(): WalletData | null {\n const walletPath = join(this.configDir, 'wallet.json');\n if (existsSync(walletPath)) {\n // Security check: warn and fix if permissions are too open\n try {\n const stats = statSync(walletPath);\n const mode = stats.mode & 0o777;\n if (mode !== 0o600) {\n console.warn(`[MoltsPay] WARNING: wallet.json has insecure permissions (${mode.toString(8)})`);\n console.warn(`[MoltsPay] Fixing permissions to 0600...`);\n chmodSync(walletPath, 0o600);\n }\n } catch (err) {\n // Ignore permission check errors on Windows\n }\n \n const content = readFileSync(walletPath, 'utf-8');\n return JSON.parse(content);\n }\n return null;\n }\n\n /**\n * Initialize a new wallet (called by CLI)\n */\n static init(\n configDir: string,\n options: { chain: string; maxPerTx: number; maxPerDay: number }\n ): { address: string; configDir: string } {\n mkdirSync(configDir, { recursive: true });\n\n // Create wallet\n const wallet = Wallet.createRandom();\n const walletData: WalletData = {\n address: wallet.address,\n privateKey: wallet.privateKey,\n createdAt: Date.now(),\n };\n\n // Save wallet with secure permissions (0o600 = owner read/write only)\n const walletPath = join(configDir, 'wallet.json');\n writeFileSync(walletPath, JSON.stringify(walletData, null, 2), { mode: 0o600 });\n\n // Save config\n const config: ClientConfig = {\n chain: options.chain,\n limits: {\n maxPerTx: options.maxPerTx,\n maxPerDay: options.maxPerDay,\n },\n };\n const configPath = join(configDir, 'config.json');\n writeFileSync(configPath, JSON.stringify(config, null, 2));\n\n return { address: wallet.address, configDir };\n }\n\n /**\n * Get wallet balance (USDC, USDT, and native token) on default chain\n */\n async getBalance(): Promise<{ usdc: number; usdt: number; native: number }> {\n if (!this.wallet) {\n throw new Error('Client not initialized');\n }\n\n let chain;\n try {\n chain = getChain(this.config.chain as EvmChainName);\n } catch {\n throw new Error(`Unknown chain: ${this.config.chain}`);\n }\n\n const provider = new ethers.JsonRpcProvider(chain.rpc);\n const tokenAbi = ['function balanceOf(address) view returns (uint256)'];\n\n // Get all balances in parallel\n const [nativeBalance, usdcBalance, usdtBalance] = await Promise.all([\n provider.getBalance(this.wallet.address),\n new ethers.Contract(chain.tokens.USDC.address, tokenAbi, provider).balanceOf(this.wallet.address),\n new ethers.Contract(chain.tokens.USDT.address, tokenAbi, provider).balanceOf(this.wallet.address),\n ]);\n\n return {\n usdc: parseFloat(ethers.formatUnits(usdcBalance, chain.tokens.USDC.decimals)),\n usdt: parseFloat(ethers.formatUnits(usdtBalance, chain.tokens.USDT.decimals)),\n native: parseFloat(ethers.formatEther(nativeBalance)),\n };\n }\n\n /**\n * Get wallet balances on all supported chains (Base + Polygon + Tempo)\n */\n async getAllBalances(): Promise<Record<string, { usdc: number; usdt: number; native: number; tempo?: { pathUSD: number; alphaUSD: number; betaUSD: number; thetaUSD: number } }>> {\n if (!this.wallet) {\n throw new Error('Client not initialized');\n }\n\n const supportedChains: EvmChainName[] = ['base', 'polygon', 'base_sepolia', 'tempo_moderato', 'bnb', 'bnb_testnet'];\n const tokenAbi = ['function balanceOf(address) view returns (uint256)'];\n const results: Record<string, { usdc: number; usdt: number; native: number; tempo?: { pathUSD: number; alphaUSD: number; betaUSD: number; thetaUSD: number } }> = {};\n\n // Tempo testnet token addresses\n const tempoTokens = {\n pathUSD: '0x20c0000000000000000000000000000000000000',\n alphaUSD: '0x20c0000000000000000000000000000000000001',\n betaUSD: '0x20c0000000000000000000000000000000000002',\n thetaUSD: '0x20c0000000000000000000000000000000000003',\n };\n\n // Query all chains in parallel\n await Promise.all(\n supportedChains.map(async (chainName) => {\n try {\n const chain = getChain(chainName);\n const provider = new ethers.JsonRpcProvider(chain.rpc);\n\n if (chainName === 'tempo_moderato') {\n // Tempo: fetch all 4 testnet tokens\n const [nativeBalance, pathUSD, alphaUSD, betaUSD, thetaUSD] = await Promise.all([\n provider.getBalance(this.wallet!.address),\n new ethers.Contract(tempoTokens.pathUSD, tokenAbi, provider).balanceOf(this.wallet!.address),\n new ethers.Contract(tempoTokens.alphaUSD, tokenAbi, provider).balanceOf(this.wallet!.address),\n new ethers.Contract(tempoTokens.betaUSD, tokenAbi, provider).balanceOf(this.wallet!.address),\n new ethers.Contract(tempoTokens.thetaUSD, tokenAbi, provider).balanceOf(this.wallet!.address),\n ]);\n\n results[chainName] = {\n usdc: parseFloat(ethers.formatUnits(pathUSD, 6)), // pathUSD as default USDC\n usdt: parseFloat(ethers.formatUnits(alphaUSD, 6)), // alphaUSD as default USDT\n native: parseFloat(ethers.formatEther(nativeBalance)),\n tempo: {\n pathUSD: parseFloat(ethers.formatUnits(pathUSD, 6)),\n alphaUSD: parseFloat(ethers.formatUnits(alphaUSD, 6)),\n betaUSD: parseFloat(ethers.formatUnits(betaUSD, 6)),\n thetaUSD: parseFloat(ethers.formatUnits(thetaUSD, 6)),\n },\n };\n } else {\n // Other chains: fetch USDC and USDT\n const [nativeBalance, usdcBalance, usdtBalance] = await Promise.all([\n provider.getBalance(this.wallet!.address),\n new ethers.Contract(chain.tokens.USDC.address, tokenAbi, provider).balanceOf(this.wallet!.address),\n new ethers.Contract(chain.tokens.USDT.address, tokenAbi, provider).balanceOf(this.wallet!.address),\n ]);\n\n results[chainName] = {\n usdc: parseFloat(ethers.formatUnits(usdcBalance, chain.tokens.USDC.decimals)),\n usdt: parseFloat(ethers.formatUnits(usdtBalance, chain.tokens.USDT.decimals)),\n native: parseFloat(ethers.formatEther(nativeBalance)),\n };\n }\n } catch (err) {\n // If chain query fails, show zeros\n results[chainName] = { usdc: 0, usdt: 0, native: 0 };\n }\n })\n );\n\n return results;\n }\n\n /**\n * Pay for a service using MPP (Machine Payments Protocol)\n * \n * This implements the MPP flow manually for EOA wallets:\n * 1. Request service → get 402 with WWW-Authenticate\n * 2. Parse payment requirements\n * 3. Execute transfer on Tempo chain\n * 4. Retry with transaction hash as credential\n * \n * @param url - Full URL of the MPP-enabled endpoint\n * @param options - Request options (body, headers)\n * @returns Response from the service\n */\n async payWithMPP(\n url: string,\n options: {\n body?: any;\n headers?: Record<string, string>;\n } = {}\n ): Promise<any> {\n if (!this.wallet || !this.walletData) {\n throw new Error('Client not initialized. Run: npx moltspay init');\n }\n\n // Dynamic imports for ESM-only packages\n const { privateKeyToAccount } = await import('viem/accounts');\n const { createWalletClient, createPublicClient, http } = await import('viem');\n const { tempoModerato } = await import('viem/chains');\n const { Actions } = await import('viem/tempo');\n\n // Get private key from wallet data\n const privateKey = this.walletData.privateKey as `0x${string}`;\n const account = privateKeyToAccount(privateKey);\n\n console.log(`[MoltsPay] Making MPP request to: ${url}`);\n console.log(`[MoltsPay] Using account: ${account.address}`);\n\n // Step 1: Initial request to get 402 with payment requirements\n const initResponse = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...options.headers,\n },\n body: options.body ? JSON.stringify(options.body) : undefined,\n });\n\n // If not 402, handle directly\n if (initResponse.status !== 402) {\n if (initResponse.ok) {\n return initResponse.json();\n }\n const errorText = await initResponse.text();\n throw new Error(`Request failed (${initResponse.status}): ${errorText}`);\n }\n\n // Step 2: Parse WWW-Authenticate header\n const wwwAuth = initResponse.headers.get('www-authenticate');\n if (!wwwAuth || !wwwAuth.toLowerCase().includes('payment')) {\n throw new Error('No WWW-Authenticate Payment challenge in 402 response');\n }\n\n console.log(`[MoltsPay] Got 402, parsing payment challenge...`);\n\n // Parse WWW-Authenticate: Payment id=\"...\", method=\"tempo\", request=\"...\"\n const parseAuthParam = (header: string, key: string): string | null => {\n const match = header.match(new RegExp(`${key}=\"([^\"]+)\"`, 'i'));\n return match ? match[1] : null;\n };\n\n const challengeId = parseAuthParam(wwwAuth, 'id');\n const method = parseAuthParam(wwwAuth, 'method');\n const realm = parseAuthParam(wwwAuth, 'realm');\n const requestB64 = parseAuthParam(wwwAuth, 'request');\n\n if (method !== 'tempo') {\n throw new Error(`Unsupported payment method: ${method}`);\n }\n\n if (!requestB64) {\n throw new Error('Missing request in WWW-Authenticate');\n }\n\n // Decode payment request\n const requestJson = Buffer.from(requestB64, 'base64').toString('utf-8');\n const paymentRequest = JSON.parse(requestJson);\n \n console.log(`[MoltsPay] Payment request:`, paymentRequest);\n\n const { amount, currency, recipient, methodDetails } = paymentRequest;\n const chainId = methodDetails?.chainId || 42431;\n\n // Step 3: Execute transfer on Tempo\n console.log(`[MoltsPay] Executing transfer on Tempo (chainId: ${chainId})...`);\n console.log(`[MoltsPay] Amount: ${amount}, To: ${recipient}`);\n\n // Create viem client for Tempo (with feeToken for gas-free transactions)\n const tempoChain = { ...tempoModerato, feeToken: currency as `0x${string}` };\n \n const publicClient = createPublicClient({\n chain: tempoChain,\n transport: http('https://rpc.moderato.tempo.xyz'),\n });\n\n const walletClient = createWalletClient({\n account,\n chain: tempoChain,\n transport: http('https://rpc.moderato.tempo.xyz'),\n });\n\n // Use viem's Tempo Actions for TIP-20 transfer\n const txHash = await Actions.token.transfer(walletClient, {\n to: recipient as `0x${string}`,\n amount: BigInt(amount),\n token: currency as `0x${string}`,\n });\n\n console.log(`[MoltsPay] Transaction sent: ${txHash}`);\n\n // Wait for confirmation\n console.log(`[MoltsPay] Waiting for confirmation...`);\n await publicClient.waitForTransactionReceipt({ hash: txHash });\n console.log(`[MoltsPay] Transaction confirmed!`);\n\n // Step 4: Build credential and retry\n const challenge = {\n id: challengeId,\n realm,\n method: 'tempo',\n intent: 'charge',\n request: paymentRequest,\n };\n\n const credential = {\n challenge,\n payload: { hash: txHash, type: 'hash' },\n source: `did:pkh:eip155:${chainId}:${account.address}`,\n };\n\n const credentialB64 = Buffer.from(JSON.stringify(credential))\n .toString('base64')\n .replace(/\\+/g, '-')\n .replace(/\\//g, '_')\n .replace(/=+$/, ''); // base64url without padding\n\n console.log(`[MoltsPay] Retrying with payment credential...`);\n\n // Retry with credential\n const paidResponse = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Payment ${credentialB64}`,\n ...options.headers,\n },\n body: options.body ? JSON.stringify(options.body) : undefined,\n });\n\n if (!paidResponse.ok) {\n const errorText = await paidResponse.text();\n throw new Error(`Payment verification failed (${paidResponse.status}): ${errorText}`);\n }\n\n console.log(`[MoltsPay] Payment verified! Service completed.`);\n return paidResponse.json();\n }\n}\n","/**\n * Solana Wallet Management\n * \n * Separate from EVM wallets - uses ed25519 keypairs.\n * Stored in ~/.moltspay/wallet-solana.json\n */\n\nimport { Keypair, PublicKey, Connection, LAMPORTS_PER_SOL } from '@solana/web3.js';\nimport { getAssociatedTokenAddress, getAccount } from '@solana/spl-token';\nimport { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';\nimport { join } from 'path';\nimport { homedir } from 'os';\nimport bs58 from 'bs58';\nimport { getSolanaConnection, getUSDCMint, type SolanaChainName } from '../chains/solana.js';\n\nconst DEFAULT_CONFIG_DIR = join(homedir(), '.moltspay');\nconst SOLANA_WALLET_FILE = 'wallet-solana.json';\n\nexport interface SolanaWalletData {\n publicKey: string; // Base58 encoded\n secretKey: string; // Base58 encoded (should be encrypted in production)\n createdAt: string;\n}\n\n/**\n * Get the path to the Solana wallet file\n */\nexport function getSolanaWalletPath(configDir: string = DEFAULT_CONFIG_DIR): string {\n return join(configDir, SOLANA_WALLET_FILE);\n}\n\n/**\n * Check if Solana wallet exists\n */\nexport function solanaWalletExists(configDir: string = DEFAULT_CONFIG_DIR): boolean {\n return existsSync(getSolanaWalletPath(configDir));\n}\n\n/**\n * Load existing Solana wallet\n */\nexport function loadSolanaWallet(configDir: string = DEFAULT_CONFIG_DIR): Keypair | null {\n const walletPath = getSolanaWalletPath(configDir);\n \n if (!existsSync(walletPath)) {\n return null;\n }\n \n try {\n const data: SolanaWalletData = JSON.parse(readFileSync(walletPath, 'utf-8'));\n const secretKey = bs58.decode(data.secretKey);\n return Keypair.fromSecretKey(secretKey);\n } catch (error) {\n console.error('Failed to load Solana wallet:', error);\n return null;\n }\n}\n\n/**\n * Create new Solana wallet\n */\nexport function createSolanaWallet(configDir: string = DEFAULT_CONFIG_DIR): Keypair {\n // Ensure config directory exists\n if (!existsSync(configDir)) {\n mkdirSync(configDir, { recursive: true });\n }\n \n const keypair = Keypair.generate();\n const data: SolanaWalletData = {\n publicKey: keypair.publicKey.toBase58(),\n secretKey: bs58.encode(keypair.secretKey),\n createdAt: new Date().toISOString(),\n };\n \n const walletPath = getSolanaWalletPath(configDir);\n writeFileSync(walletPath, JSON.stringify(data, null, 2));\n \n return keypair;\n}\n\n/**\n * Get Solana wallet address (public key as Base58)\n */\nexport function getSolanaAddress(configDir: string = DEFAULT_CONFIG_DIR): string | null {\n const wallet = loadSolanaWallet(configDir);\n return wallet?.publicKey.toBase58() || null;\n}\n\n/**\n * Get SOL balance (native token for gas)\n */\nexport async function getSolanaBalance(\n address: string,\n chain: SolanaChainName\n): Promise<number> {\n const connection = getSolanaConnection(chain);\n const pubkey = new PublicKey(address);\n \n const balance = await connection.getBalance(pubkey);\n return balance / LAMPORTS_PER_SOL;\n}\n\n/**\n * Get USDC balance on Solana\n */\nexport async function getSolanaUSDCBalance(\n address: string,\n chain: SolanaChainName\n): Promise<number> {\n const connection = getSolanaConnection(chain);\n const owner = new PublicKey(address);\n const mint = getUSDCMint(chain);\n \n try {\n const ata = await getAssociatedTokenAddress(mint, owner);\n const account = await getAccount(connection, ata);\n // USDC has 6 decimals on Solana\n return Number(account.amount) / 1e6;\n } catch (error: any) {\n // Account doesn't exist = 0 balance\n if (error.name === 'TokenAccountNotFoundError' || \n error.message?.includes('could not find account')) {\n return 0;\n }\n throw error;\n }\n}\n\n/**\n * Get all Solana balances (SOL + USDC)\n */\nexport async function getSolanaBalances(\n address: string,\n chain: SolanaChainName\n): Promise<{ sol: number; usdc: number }> {\n const [sol, usdc] = await Promise.all([\n getSolanaBalance(address, chain),\n getSolanaUSDCBalance(address, chain),\n ]);\n \n return { sol, usdc };\n}\n\n/**\n * Request SOL airdrop (devnet only)\n */\nexport async function requestSolanaAirdrop(\n address: string,\n chain: SolanaChainName,\n amount: number = 1\n): Promise<string> {\n if (chain !== 'solana_devnet') {\n throw new Error('Airdrop only available on devnet');\n }\n \n const connection = getSolanaConnection(chain);\n const pubkey = new PublicKey(address);\n \n const signature = await connection.requestAirdrop(\n pubkey,\n amount * LAMPORTS_PER_SOL\n );\n \n // Wait for confirmation\n await connection.confirmTransaction(signature, 'confirmed');\n \n return signature;\n}\n\n/**\n * Validate Solana address format\n */\nexport function isValidSolanaAddress(address: string): boolean {\n try {\n new PublicKey(address);\n return true;\n } catch {\n return false;\n }\n}\n","/**\n * Wallet - Basic Custody Wallet\n * \n * Features:\n * - Query balance (USDC, USDT, ETH)\n * - Send token transfers (USDC or USDT)\n */\n\nimport { ethers } from 'ethers';\nimport { getChain, ERC20_ABI } from '../chains/index.js';\nimport type {\n EvmChainName,\n ChainConfig,\n WalletBalance,\n TransferResult,\n TokenSymbol,\n} from '../types/index.js';\n\nexport interface WalletConfig {\n chain?: EvmChainName;\n privateKey?: string;\n rpcUrl?: string;\n}\n\nexport class Wallet {\n readonly chain: EvmChainName;\n readonly chainConfig: ChainConfig;\n readonly address: string;\n \n private wallet: ethers.Wallet;\n private provider: ethers.JsonRpcProvider;\n private tokenContracts: Record<TokenSymbol, ethers.Contract>;\n\n constructor(config: WalletConfig = {}) {\n this.chain = config.chain || 'base_sepolia';\n this.chainConfig = getChain(this.chain);\n \n const privateKey = config.privateKey || process.env.PAYMENT_AGENT_PRIVATE_KEY;\n if (!privateKey) {\n throw new Error('privateKey is required. Set via config or PAYMENT_AGENT_PRIVATE_KEY env var.');\n }\n\n const rpcUrl = config.rpcUrl || this.chainConfig.rpc;\n this.provider = new ethers.JsonRpcProvider(rpcUrl);\n this.wallet = new ethers.Wallet(privateKey, this.provider);\n this.address = this.wallet.address;\n \n // Initialize token contracts\n this.tokenContracts = {\n USDC: new ethers.Contract(\n this.chainConfig.tokens.USDC.address,\n ERC20_ABI,\n this.wallet\n ),\n USDT: new ethers.Contract(\n this.chainConfig.tokens.USDT.address,\n ERC20_ABI,\n this.wallet\n ),\n };\n }\n\n /**\n * Get wallet balance for all tokens\n */\n async getBalance(): Promise<WalletBalance> {\n const [ethBalance, usdcBalance, usdtBalance] = await Promise.all([\n this.provider.getBalance(this.address),\n this.tokenContracts.USDC.balanceOf(this.address),\n this.tokenContracts.USDT.balanceOf(this.address),\n ]);\n\n return {\n address: this.address,\n eth: ethers.formatEther(ethBalance),\n usdc: (Number(usdcBalance) / 1e6).toFixed(2),\n usdt: (Number(usdtBalance) / 1e6).toFixed(2),\n chain: this.chain,\n };\n }\n\n /**\n * Send token transfer (USDC or USDT)\n * @param to - recipient address\n * @param amount - amount to send\n * @param token - token to send (default: USDC)\n */\n async transfer(to: string, amount: number, token: TokenSymbol = 'USDC'): Promise<TransferResult> {\n try {\n // Validate address\n to = ethers.getAddress(to);\n \n // Get token contract and config\n const tokenContract = this.tokenContracts[token];\n const tokenConfig = this.chainConfig.tokens[token];\n \n if (!tokenContract || !tokenConfig) {\n return {\n success: false,\n error: `Token ${token} not supported on ${this.chain}`,\n };\n }\n \n // Convert amount (both USDC and USDT have 6 decimals)\n const decimals = tokenConfig.decimals;\n const amountWei = BigInt(Math.floor(amount * (10 ** decimals)));\n\n // Check balance\n const balance = await tokenContract.balanceOf(this.address);\n if (BigInt(balance) < amountWei) {\n return {\n success: false,\n error: `Insufficient ${token} balance: ${Number(balance) / (10 ** decimals)} < ${amount}`,\n };\n }\n\n // Send transaction\n const tx = await tokenContract.transfer(to, amountWei);\n const receipt = await tx.wait();\n\n if (receipt.status === 1) {\n return {\n success: true,\n tx_hash: tx.hash,\n from: this.address,\n to,\n amount,\n token,\n gas_used: Number(receipt.gasUsed),\n block_number: receipt.blockNumber,\n explorer_url: `${this.chainConfig.explorerTx}${tx.hash}`,\n };\n } else {\n return {\n success: false,\n tx_hash: tx.hash,\n token,\n error: 'Transaction reverted',\n };\n }\n } catch (error) {\n return {\n success: false,\n token,\n error: (error as Error).message,\n };\n }\n }\n\n /**\n * Get ETH balance\n */\n async getEthBalance(): Promise<string> {\n const balance = await this.provider.getBalance(this.address);\n return ethers.formatEther(balance);\n }\n\n /**\n * Get token balance\n * @param token - token symbol (default: USDC)\n */\n async getTokenBalance(token: TokenSymbol = 'USDC'): Promise<string> {\n const tokenContract = this.tokenContracts[token];\n const tokenConfig = this.chainConfig.tokens[token];\n const balance = await tokenContract.balanceOf(this.address);\n return (Number(balance) / (10 ** tokenConfig.decimals)).toFixed(2);\n }\n\n /**\n * @deprecated Use getTokenBalance('USDC') instead\n */\n async getUsdcBalance(): Promise<string> {\n return this.getTokenBalance('USDC');\n }\n}\n","/**\n * createWallet - Create a new wallet for Agent\n * \n * Features:\n * - Generate new Ethereum wallet\n * - Securely store private key (encrypted or plaintext, depending on config)\n * - Return wallet address (never return private key)\n */\n\nimport { ethers } from 'ethers';\nimport { writeFileSync, readFileSync, existsSync, mkdirSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { createCipheriv, createDecipheriv, randomBytes, scryptSync } from 'crypto';\n\nexport interface CreateWalletOptions {\n /** Storage path, default ~/.moltspay/wallet.json */\n storagePath?: string;\n /** Encryption password (optional, plaintext if not provided) */\n password?: string;\n /** Wallet label/name */\n label?: string;\n /** Overwrite if wallet exists */\n overwrite?: boolean;\n}\n\nexport interface WalletData {\n address: string;\n label?: string;\n createdAt: string;\n encrypted: boolean;\n /** Encrypted or plaintext private key */\n privateKey: string;\n /** Encryption IV */\n iv?: string;\n /** Encryption salt */\n salt?: string;\n}\n\nexport interface CreateWalletResult {\n success: boolean;\n address?: string;\n storagePath?: string;\n error?: string;\n /** Whether newly created (false means loaded existing) */\n isNew?: boolean;\n}\n\nconst DEFAULT_STORAGE_DIR = join(process.env.HOME || '~', '.moltspay');\nconst DEFAULT_STORAGE_FILE = 'wallet.json';\n\n/**\n * Encrypt private key\n */\nfunction encryptPrivateKey(privateKey: string, password: string): { encrypted: string; iv: string; salt: string } {\n const salt = randomBytes(16);\n const key = scryptSync(password, salt, 32);\n const iv = randomBytes(16);\n \n const cipher = createCipheriv('aes-256-cbc', key, iv);\n let encrypted = cipher.update(privateKey, 'utf8', 'hex');\n encrypted += cipher.final('hex');\n \n return {\n encrypted,\n iv: iv.toString('hex'),\n salt: salt.toString('hex'),\n };\n}\n\n/**\n * Decrypt private key\n */\nfunction decryptPrivateKey(encrypted: string, password: string, iv: string, salt: string): string {\n const key = scryptSync(password, Buffer.from(salt, 'hex'), 32);\n const decipher = createDecipheriv('aes-256-cbc', key, Buffer.from(iv, 'hex'));\n \n let decrypted = decipher.update(encrypted, 'hex', 'utf8');\n decrypted += decipher.final('utf8');\n \n return decrypted;\n}\n\n/**\n * Create new wallet\n * \n * @example\n * ```typescript\n * // Create unencrypted wallet\n * const result = await createWallet();\n * console.log('Wallet address:', result.address);\n * \n * // Create encrypted wallet\n * const result = await createWallet({ password: 'mySecurePassword' });\n * \n * // Specify storage path\n * const result = await createWallet({ storagePath: './my-wallet.json' });\n * ```\n */\nexport function createWallet(options: CreateWalletOptions = {}): CreateWalletResult {\n const storagePath = options.storagePath || join(DEFAULT_STORAGE_DIR, DEFAULT_STORAGE_FILE);\n \n // Check if exists\n if (existsSync(storagePath) && !options.overwrite) {\n // Load existing wallet\n try {\n const existing = JSON.parse(readFileSync(storagePath, 'utf8')) as WalletData;\n return {\n success: true,\n address: existing.address,\n storagePath,\n isNew: false,\n };\n } catch (error) {\n return {\n success: false,\n error: `Failed to load existing wallet: ${(error as Error).message}`,\n };\n }\n }\n\n try {\n // Create new wallet\n const wallet = ethers.Wallet.createRandom();\n \n // Prepare storage data\n const walletData: WalletData = {\n address: wallet.address,\n label: options.label,\n createdAt: new Date().toISOString(),\n encrypted: !!options.password,\n privateKey: '',\n };\n\n if (options.password) {\n // Encrypted storage\n const { encrypted, iv, salt } = encryptPrivateKey(wallet.privateKey, options.password);\n walletData.privateKey = encrypted;\n walletData.iv = iv;\n walletData.salt = salt;\n } else {\n // Plaintext storage (not recommended, but convenient for testing/dev)\n walletData.privateKey = wallet.privateKey;\n }\n\n // Ensure directory exists\n const dir = dirname(storagePath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n\n // Write file\n writeFileSync(storagePath, JSON.stringify(walletData, null, 2), { mode: 0o600 });\n\n return {\n success: true,\n address: wallet.address,\n storagePath,\n isNew: true,\n };\n } catch (error) {\n return {\n success: false,\n error: (error as Error).message,\n };\n }\n}\n\n/**\n * Load existing wallet\n */\nexport function loadWallet(options: { storagePath?: string; password?: string } = {}): {\n success: boolean;\n address?: string;\n privateKey?: string;\n error?: string;\n} {\n const storagePath = options.storagePath || join(DEFAULT_STORAGE_DIR, DEFAULT_STORAGE_FILE);\n\n if (!existsSync(storagePath)) {\n return { success: false, error: 'Wallet not found. Run createWallet() first.' };\n }\n\n try {\n const data = JSON.parse(readFileSync(storagePath, 'utf8')) as WalletData;\n\n if (data.encrypted) {\n if (!options.password) {\n return { success: false, error: 'Wallet is encrypted. Password required.' };\n }\n const privateKey = decryptPrivateKey(data.privateKey, options.password, data.iv!, data.salt!);\n return { success: true, address: data.address, privateKey };\n } else {\n return { success: true, address: data.address, privateKey: data.privateKey };\n }\n } catch (error) {\n return { success: false, error: (error as Error).message };\n }\n}\n\n/**\n * Get wallet address (no password required)\n */\nexport function getWalletAddress(storagePath?: string): string | null {\n const path = storagePath || join(DEFAULT_STORAGE_DIR, DEFAULT_STORAGE_FILE);\n \n if (!existsSync(path)) {\n return null;\n }\n\n try {\n const data = JSON.parse(readFileSync(path, 'utf8')) as WalletData;\n return data.address;\n } catch {\n return null;\n }\n}\n\n/**\n * Check if wallet exists\n */\nexport function walletExists(storagePath?: string): boolean {\n const path = storagePath || join(DEFAULT_STORAGE_DIR, DEFAULT_STORAGE_FILE);\n return existsSync(path);\n}\n","/**\n * On-chain Payment Verification Module\n */\n\nimport { ethers } from 'ethers';\nimport { getChain, getChainById, type ChainConfig, type EvmChainName, type TokenSymbol } from '../chains';\n\n// ERC20 Transfer event signature\nconst TRANSFER_EVENT_TOPIC = ethers.id('Transfer(address,address,uint256)');\n\nexport interface VerifyPaymentParams {\n txHash: string;\n expectedAmount: number;\n expectedTo?: string;\n chain?: string | number;\n /** Expected token (if not specified, accepts both USDC and USDT) */\n expectedToken?: TokenSymbol;\n}\n\nexport interface VerifyPaymentResult {\n verified: boolean;\n amount?: number;\n token?: TokenSymbol;\n from?: string;\n to?: string;\n txHash?: string;\n blockNumber?: number;\n error?: string;\n}\n\n/**\n * Verify on-chain payment\n * Supports both USDC and USDT transfers\n */\nexport async function verifyPayment(params: VerifyPaymentParams): Promise<VerifyPaymentResult> {\n const { txHash, expectedAmount, expectedTo, expectedToken } = params;\n \n // Get chain config\n let chain: ChainConfig | undefined;\n try {\n if (typeof params.chain === 'number') {\n chain = getChainById(params.chain);\n } else {\n chain = getChain((params.chain || 'base') as EvmChainName);\n }\n if (!chain) {\n return { verified: false, error: `Unsupported chain: ${params.chain}` };\n }\n } catch (e) {\n return { verified: false, error: `Unsupported chain: ${params.chain}` };\n }\n\n try {\n const provider = new ethers.JsonRpcProvider(chain.rpc);\n \n // Get transaction receipt\n const receipt = await provider.getTransactionReceipt(txHash);\n \n if (!receipt) {\n return { verified: false, error: 'Transaction not found or not confirmed' };\n }\n\n if (receipt.status !== 1) {\n return { verified: false, error: 'Transaction failed' };\n }\n\n // Build map of accepted token addresses\n const tokenAddresses: Record<string, TokenSymbol> = {};\n \n if (!expectedToken || expectedToken === 'USDC') {\n tokenAddresses[chain.tokens.USDC.address.toLowerCase()] = 'USDC';\n }\n if (!expectedToken || expectedToken === 'USDT') {\n tokenAddresses[chain.tokens.USDT.address.toLowerCase()] = 'USDT';\n }\n\n if (Object.keys(tokenAddresses).length === 0) {\n return { verified: false, error: `No token addresses configured for ${chain.name}` };\n }\n\n for (const log of receipt.logs) {\n const logAddress = log.address.toLowerCase();\n \n // Check if this is one of our accepted tokens\n const detectedToken = tokenAddresses[logAddress];\n if (!detectedToken) {\n continue;\n }\n\n // Check if Transfer event\n if (log.topics.length < 3 || log.topics[0] !== TRANSFER_EVENT_TOPIC) {\n continue;\n }\n\n // Parse Transfer event params\n const from = '0x' + log.topics[1].slice(-40);\n const to = '0x' + log.topics[2].slice(-40);\n const amountRaw = BigInt(log.data);\n const tokenConfig = chain.tokens[detectedToken];\n const amount = Number(amountRaw) / (10 ** tokenConfig.decimals);\n\n // Verify recipient address\n if (expectedTo && to.toLowerCase() !== expectedTo.toLowerCase()) {\n continue;\n }\n\n // Verify amount\n if (amount < expectedAmount) {\n return {\n verified: false,\n error: `Insufficient amount: received ${amount} ${detectedToken}, expected ${expectedAmount}`,\n amount,\n token: detectedToken,\n from,\n to,\n txHash,\n blockNumber: receipt.blockNumber,\n };\n }\n\n // Verification successful\n return {\n verified: true,\n amount,\n token: detectedToken,\n from,\n to,\n txHash,\n blockNumber: receipt.blockNumber,\n };\n }\n\n const tokenList = expectedToken ? expectedToken : 'USDC/USDT';\n return { verified: false, error: `No ${tokenList} transfer found` };\n\n } catch (e: any) {\n return { verified: false, error: e.message || String(e) };\n }\n}\n\n/**\n * Get transaction status\n */\nexport async function getTransactionStatus(\n txHash: string,\n chain: string | number = 'base'\n): Promise<{\n status: 'pending' | 'confirmed' | 'failed' | 'not_found';\n blockNumber?: number;\n confirmations?: number;\n}> {\n let chainConfig: ChainConfig | undefined;\n try {\n chainConfig = typeof chain === 'number' ? getChainById(chain) : getChain(chain as EvmChainName);\n if (!chainConfig) return { status: 'not_found' };\n } catch {\n return { status: 'not_found' };\n }\n\n try {\n const provider = new ethers.JsonRpcProvider(chainConfig.rpc);\n const receipt = await provider.getTransactionReceipt(txHash);\n\n if (!receipt) {\n // Check if in pending pool\n const tx = await provider.getTransaction(txHash);\n if (tx) {\n return { status: 'pending' };\n }\n return { status: 'not_found' };\n }\n\n const currentBlock = await provider.getBlockNumber();\n const confirmations = currentBlock - receipt.blockNumber;\n\n if (receipt.status === 1) {\n return {\n status: 'confirmed',\n blockNumber: receipt.blockNumber,\n confirmations,\n };\n } else {\n return {\n status: 'failed',\n blockNumber: receipt.blockNumber,\n };\n }\n } catch {\n return { status: 'not_found' };\n }\n}\n\n/**\n * Wait for transaction confirmation\n */\nexport async function waitForTransaction(\n txHash: string,\n chain: string | number = 'base',\n confirmations = 1,\n timeoutMs = 60000\n): Promise<VerifyPaymentResult & { confirmed: boolean }> {\n let chainConfig: ChainConfig | undefined;\n try {\n chainConfig = typeof chain === 'number' ? getChainById(chain) : getChain(chain as EvmChainName);\n if (!chainConfig) {\n return { verified: false, confirmed: false, error: `Unsupported chain: ${chain}` };\n }\n } catch (e) {\n return { verified: false, confirmed: false, error: `Unsupported chain: ${chain}` };\n }\n\n const provider = new ethers.JsonRpcProvider(chainConfig.rpc);\n \n try {\n const receipt = await provider.waitForTransaction(txHash, confirmations, timeoutMs);\n \n if (!receipt) {\n return { verified: false, confirmed: false, error: 'Timeout waiting' };\n }\n\n if (receipt.status !== 1) {\n return { verified: false, confirmed: true, error: 'Transaction failed' };\n }\n\n return {\n verified: true,\n confirmed: true,\n txHash,\n blockNumber: receipt.blockNumber,\n };\n } catch (e: any) {\n return { verified: false, confirmed: false, error: e.message || String(e) };\n }\n}\n","/**\n * CDP (Coinbase Developer Platform) Wallet Integration\n * \n * Creates and manages wallets via Coinbase's CDP SDK.\n * These wallets are hosted by Coinbase, making them easy to use for AI Agents.\n * \n * @see https://docs.cdp.coinbase.com/\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport type { EvmChainName } from '../types/index.js';\nimport { getChain } from '../chains/index.js';\n\n// CDP config file location\nconst DEFAULT_STORAGE_DIR = path.join(process.env.HOME || '.', '.moltspay');\nconst CDP_CONFIG_FILE = 'cdp-wallet.json';\n\nexport interface CDPWalletConfig {\n /** Storage directory (default: ~/.moltspay) */\n storageDir?: string;\n /** Chain name */\n chain?: EvmChainName;\n /** CDP API credentials (or use env vars) */\n apiKeyId?: string;\n apiKeySecret?: string;\n walletSecret?: string;\n}\n\nexport interface CDPWalletData {\n /** Wallet address */\n address: string;\n /** CDP wallet ID */\n walletId: string;\n /** Chain */\n chain: EvmChainName;\n /** Created timestamp */\n createdAt: string;\n /** CDP account data (for restoration) */\n accountData?: string;\n}\n\nexport interface CDPInitResult {\n success: boolean;\n address?: string;\n walletId?: string;\n isNew?: boolean;\n error?: string;\n storagePath?: string;\n}\n\n/**\n * Check if CDP SDK is available\n */\nexport function isCDPAvailable(): boolean {\n try {\n require.resolve('@coinbase/cdp-sdk');\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Get CDP credentials from environment\n */\nfunction getCDPCredentials(config: CDPWalletConfig): {\n apiKeyId: string;\n apiKeySecret: string;\n walletSecret?: string;\n} | null {\n const apiKeyId = config.apiKeyId || process.env.CDP_API_KEY_ID;\n const apiKeySecret = config.apiKeySecret || process.env.CDP_API_KEY_SECRET;\n const walletSecret = config.walletSecret || process.env.CDP_WALLET_SECRET;\n\n if (!apiKeyId || !apiKeySecret) {\n return null;\n }\n\n return { apiKeyId, apiKeySecret, walletSecret };\n}\n\n/**\n * Initialize CDP wallet\n * \n * Creates a new CDP wallet or loads existing one.\n * \n * @example\n * ```bash\n * # Set credentials\n * export CDP_API_KEY_ID=your-key-id\n * export CDP_API_KEY_SECRET=your-key-secret\n * \n * # Initialize\n * npx moltspay init --cdp --chain base\n * ```\n */\nexport async function initCDPWallet(config: CDPWalletConfig = {}): Promise<CDPInitResult> {\n const storageDir = config.storageDir || DEFAULT_STORAGE_DIR;\n const chain = config.chain || 'base';\n const storagePath = path.join(storageDir, CDP_CONFIG_FILE);\n\n // Check for existing wallet\n if (fs.existsSync(storagePath)) {\n try {\n const data = JSON.parse(fs.readFileSync(storagePath, 'utf-8')) as CDPWalletData;\n return {\n success: true,\n address: data.address,\n walletId: data.walletId,\n isNew: false,\n storagePath,\n };\n } catch (error) {\n // Continue to create new\n }\n }\n\n // Check CDP availability\n if (!isCDPAvailable()) {\n return {\n success: false,\n error: 'CDP SDK not installed. Run: npm install @coinbase/cdp-sdk',\n };\n }\n\n // Get credentials\n const creds = getCDPCredentials(config);\n if (!creds) {\n return {\n success: false,\n error: 'CDP credentials not found. Set CDP_API_KEY_ID and CDP_API_KEY_SECRET environment variables.',\n };\n }\n\n try {\n // Dynamic import to avoid errors when CDP SDK is not installed\n const { CdpClient } = await import('@coinbase/cdp-sdk');\n\n // Initialize CDP client\n const cdp = new CdpClient({\n apiKeyId: creds.apiKeyId,\n apiKeySecret: creds.apiKeySecret,\n walletSecret: creds.walletSecret,\n });\n\n // Create EVM account\n const account = await cdp.evm.createAccount();\n\n // Ensure storage directory exists\n if (!fs.existsSync(storageDir)) {\n fs.mkdirSync(storageDir, { recursive: true });\n }\n\n // Save wallet data\n const walletData: CDPWalletData = {\n address: account.address,\n walletId: account.address, // CDP uses address as ID for EVM\n chain,\n createdAt: new Date().toISOString(),\n };\n\n fs.writeFileSync(storagePath, JSON.stringify(walletData, null, 2), { mode: 0o600 });\n\n return {\n success: true,\n address: account.address,\n walletId: account.address,\n isNew: true,\n storagePath,\n };\n } catch (error) {\n return {\n success: false,\n error: (error as Error).message,\n };\n }\n}\n\n/**\n * Load existing CDP wallet\n */\nexport function loadCDPWallet(config: CDPWalletConfig = {}): CDPWalletData | null {\n const storageDir = config.storageDir || DEFAULT_STORAGE_DIR;\n const storagePath = path.join(storageDir, CDP_CONFIG_FILE);\n\n if (!fs.existsSync(storagePath)) {\n return null;\n }\n\n try {\n return JSON.parse(fs.readFileSync(storagePath, 'utf-8')) as CDPWalletData;\n } catch {\n return null;\n }\n}\n\n/**\n * Get CDP wallet address (quick check without full init)\n */\nexport function getCDPWalletAddress(storageDir?: string): string | null {\n const data = loadCDPWallet({ storageDir });\n return data?.address || null;\n}\n\n/**\n * CDP Wallet class for making payments\n * \n * Uses CDP SDK for wallet operations with x402 support.\n */\nexport class CDPWallet {\n readonly address: string;\n readonly chain: EvmChainName;\n readonly chainConfig: ReturnType<typeof getChain>;\n private storageDir: string;\n\n constructor(config: CDPWalletConfig = {}) {\n this.storageDir = config.storageDir || DEFAULT_STORAGE_DIR;\n this.chain = config.chain || 'base';\n this.chainConfig = getChain(this.chain);\n\n // Load existing wallet\n const data = loadCDPWallet(config);\n if (!data) {\n throw new Error('CDP wallet not initialized. Run: npx moltspay init --cdp');\n }\n this.address = data.address;\n }\n\n /**\n * Get USDC balance\n */\n async getBalance(): Promise<{ usdc: string; eth: string }> {\n // Use ethers to check balance (read-only, no CDP needed)\n const { ethers } = await import('ethers');\n const provider = new ethers.JsonRpcProvider(this.chainConfig.rpc);\n \n const usdcContract = new ethers.Contract(\n this.chainConfig.usdc,\n ['function balanceOf(address) view returns (uint256)'],\n provider\n );\n\n const [usdcBalance, ethBalance] = await Promise.all([\n usdcContract.balanceOf(this.address),\n provider.getBalance(this.address),\n ]);\n\n return {\n usdc: (Number(usdcBalance) / 1e6).toFixed(2),\n eth: ethers.formatEther(ethBalance),\n };\n }\n\n /**\n * Transfer USDC to a recipient\n * \n * Requires CDP SDK and credentials to sign transactions.\n */\n async transfer(params: { to: string; amount: number }): Promise<{\n success: boolean;\n txHash?: string;\n error?: string;\n explorerUrl?: string;\n }> {\n if (!isCDPAvailable()) {\n return { success: false, error: 'CDP SDK not installed' };\n }\n\n const creds = getCDPCredentials({});\n if (!creds) {\n return { success: false, error: 'CDP credentials not found' };\n }\n\n try {\n const { CdpClient } = await import('@coinbase/cdp-sdk');\n const { ethers } = await import('ethers');\n\n const cdp = new CdpClient({\n apiKeyId: creds.apiKeyId,\n apiKeySecret: creds.apiKeySecret,\n walletSecret: creds.walletSecret,\n });\n\n // Get the account\n const account = await cdp.evm.getAccount({ address: this.address as `0x${string}` });\n\n // Build transfer transaction\n const amountWei = BigInt(Math.floor(params.amount * 1e6));\n const iface = new ethers.Interface([\n 'function transfer(address to, uint256 amount) returns (bool)',\n ]);\n const callData = iface.encodeFunctionData('transfer', [params.to, amountWei]);\n\n // Send transaction (use any to avoid type issues with CDP SDK versions)\n const txOptions: any = {\n to: this.chainConfig.usdc,\n data: callData,\n };\n const tx = await account.sendTransaction(txOptions);\n\n return {\n success: true,\n txHash: tx.transactionHash,\n explorerUrl: `${this.chainConfig.explorerTx}${tx.transactionHash}`,\n };\n } catch (error) {\n return {\n success: false,\n error: (error as Error).message,\n };\n }\n }\n\n /**\n * Create viem-compatible signer for x402\n * \n * This allows using CDP wallet with x402 protocol.\n */\n async getViemAccount(): Promise<unknown> {\n if (!isCDPAvailable()) {\n throw new Error('CDP SDK not installed');\n }\n\n const creds = getCDPCredentials({});\n if (!creds) {\n throw new Error('CDP credentials not found');\n }\n\n const { CdpClient } = await import('@coinbase/cdp-sdk');\n const { toAccount } = await import('viem/accounts');\n\n const cdp = new CdpClient({\n apiKeyId: creds.apiKeyId,\n apiKeySecret: creds.apiKeySecret,\n walletSecret: creds.walletSecret,\n });\n\n const account = await cdp.evm.getAccount({ address: this.address as `0x${string}` });\n return toAccount(account);\n }\n}\n"],"mappings":"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","names":["import_fs","path","TRANSFER_EVENT_TOPIC","TRANSFER_EVENT_TOPIC","ethers","import_web3","config","import_web3","bs58","X402_VERSION","loadEnvFile","settlement","import_fs","import_os","import_path","import_web3","import_spl_token","import_fs","import_bs58","bs58","import_web3","X402_VERSION","PAYMENT_REQUIRED_HEADER","PAYMENT_HEADER","network","req","payTo","privateKeyToAccount","import_ethers","import_ethers","import_fs","import_path","path","import_ethers","TRANSFER_EVENT_TOPIC","path","DEFAULT_STORAGE_DIR","ethers"]}