moltspay 0.7.0 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -936,5 +936,55 @@ program.command("stop").description("Stop the running MoltsPay server").action(a
936
936
  process.exit(1);
937
937
  }
938
938
  });
939
+ program.command("pay <server> <service> [params]").description("Pay for a service and get the result").option("--prompt <text>", "Prompt for the service").option("--image <url>", "Image URL (for image-to-video)").option("--json", "Output raw JSON only").action(async (server, service, paramsJson, options) => {
940
+ const client = new MoltsPayClient();
941
+ if (!client.isInitialized) {
942
+ console.error("\u274C Wallet not initialized. Run: npx moltspay init");
943
+ process.exit(1);
944
+ }
945
+ let params = {};
946
+ if (paramsJson) {
947
+ try {
948
+ params = JSON.parse(paramsJson);
949
+ } catch {
950
+ console.error("\u274C Invalid JSON params");
951
+ process.exit(1);
952
+ }
953
+ }
954
+ if (options.prompt) params.prompt = options.prompt;
955
+ if (options.image) params.image_url = options.image;
956
+ if (!params.prompt) {
957
+ console.error("\u274C Missing prompt. Use --prompt or pass JSON params");
958
+ process.exit(1);
959
+ }
960
+ if (!options.json) {
961
+ console.log(`
962
+ \u{1F4B3} MoltsPay - Paying for service
963
+ `);
964
+ console.log(` Server: ${server}`);
965
+ console.log(` Service: ${service}`);
966
+ console.log(` Prompt: ${params.prompt}`);
967
+ if (params.image_url) console.log(` Image: ${params.image_url}`);
968
+ console.log(` Wallet: ${client.address}`);
969
+ console.log("");
970
+ }
971
+ try {
972
+ const result = await client.pay(server, service, params);
973
+ if (options.json) {
974
+ console.log(JSON.stringify(result));
975
+ } else {
976
+ console.log("\u2705 Success!\n");
977
+ console.log(JSON.stringify(result, null, 2));
978
+ console.log("");
979
+ }
980
+ } catch (err) {
981
+ if (options.json) {
982
+ console.log(JSON.stringify({ error: err.message }));
983
+ } else {
984
+ console.error(`\u274C Error: ${err.message}`);
985
+ }
986
+ process.exit(1);
987
+ }
988
+ });
939
989
  program.parse();
940
990
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/cli/index.ts","../../src/client/index.ts","../../src/chains/index.ts","../../src/server/index.ts","../../src/verify/index.ts"],"sourcesContent":["#!/usr/bin/env node\n\n/**\n * MoltsPay CLI\n * \n * Commands:\n * npx moltspay init - Create wallet, set limits\n * npx moltspay config - Update settings\n * npx moltspay status - Show wallet and balance\n * npx moltspay services <url> - List services from provider\n * npx moltspay start <manifest> - Start server from services.json\n */\n\nimport { Command } from 'commander';\nimport { homedir } from 'os';\nimport { join, dirname, resolve } from 'path';\nimport { existsSync, writeFileSync, readFileSync, unlinkSync, mkdirSync } from 'fs';\nimport { spawn } from 'child_process';\nimport { MoltsPayClient } from '../client/index.js';\nimport { MoltsPayServer } from '../server/index.js';\nimport * as readline from 'readline';\n\nconst program = new Command();\nconst DEFAULT_CONFIG_DIR = join(homedir(), '.moltspay');\nconst PID_FILE = join(DEFAULT_CONFIG_DIR, 'server.pid');\n\n// Ensure config dir exists\nif (!existsSync(DEFAULT_CONFIG_DIR)) {\n mkdirSync(DEFAULT_CONFIG_DIR, { recursive: true });\n}\n\nfunction prompt(question: string): Promise<string> {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n return new Promise(resolve => {\n rl.question(question, answer => {\n rl.close();\n resolve(answer.trim());\n });\n });\n}\n\nprogram\n .name('moltspay')\n .description('MoltsPay - Payment infrastructure for AI Agents')\n .version('1.0.0');\n\n/**\n * npx moltspay init\n */\nprogram\n .command('init')\n .description('Initialize MoltsPay client (create wallet, set limits)')\n .option('--chain <chain>', 'Blockchain to use', 'base')\n .option('--max-per-tx <amount>', 'Max amount per transaction')\n .option('--max-per-day <amount>', 'Max amount per day')\n .option('--config-dir <dir>', 'Config directory', DEFAULT_CONFIG_DIR)\n .action(async (options) => {\n console.log('\\nšŸ” MoltsPay Client Setup\\n');\n\n // Check if already initialized\n if (existsSync(join(options.configDir, 'wallet.json'))) {\n console.log('āš ļø Already initialized. Use \"moltspay config\" to update settings.');\n console.log(` Config dir: ${options.configDir}`);\n return;\n }\n\n // Get options interactively if not provided\n let chain = options.chain;\n let maxPerTx = options.maxPerTx ? parseFloat(options.maxPerTx) : null;\n let maxPerDay = options.maxPerDay ? parseFloat(options.maxPerDay) : null;\n\n if (!maxPerTx) {\n const answer = await prompt('Max per transaction (USD) [100]: ');\n maxPerTx = answer ? parseFloat(answer) : 100;\n }\n\n if (!maxPerDay) {\n const answer = await prompt('Max per day (USD) [1000]: ');\n maxPerDay = answer ? parseFloat(answer) : 1000;\n }\n\n console.log('\\nCreating wallet...');\n\n const result = MoltsPayClient.init(options.configDir, {\n chain,\n maxPerTx,\n maxPerDay,\n });\n\n console.log(`\\nāœ… Wallet created: ${result.address}`);\n console.log(`\\nšŸ“ Config saved to: ${result.configDir}`);\n console.log(`\\nāš ļø IMPORTANT: Back up ${join(result.configDir, 'wallet.json')}`);\n console.log(` This file contains your private key!\\n`);\n console.log(`šŸ’° Fund your wallet with USDC on ${chain} to start using services.\\n`);\n });\n\n/**\n * npx moltspay config\n */\nprogram\n .command('config')\n .description('Update MoltsPay settings')\n .option('--max-per-tx <amount>', 'Max amount per transaction')\n .option('--max-per-day <amount>', 'Max amount per day')\n .option('--config-dir <dir>', 'Config directory', DEFAULT_CONFIG_DIR)\n .action(async (options) => {\n const client = new MoltsPayClient({ configDir: options.configDir });\n\n if (!client.isInitialized) {\n console.log('āŒ Not initialized. Run: npx moltspay init');\n return;\n }\n\n const currentConfig = client.getConfig();\n\n // If no options provided, show interactive mode\n if (!options.maxPerTx && !options.maxPerDay) {\n console.log('\\nšŸ“‹ Current Settings:\\n');\n console.log(` Wallet: ${client.address}`);\n console.log(` Chain: ${currentConfig.chain}`);\n console.log(` Max per tx: $${currentConfig.limits.maxPerTx}`);\n console.log(` Max per day: $${currentConfig.limits.maxPerDay}`);\n console.log('');\n\n const maxPerTxAnswer = await prompt(`New max per tx (USD) [${currentConfig.limits.maxPerTx}]: `);\n const maxPerDayAnswer = await prompt(`New max per day (USD) [${currentConfig.limits.maxPerDay}]: `);\n\n if (maxPerTxAnswer) {\n client.updateConfig({ maxPerTx: parseFloat(maxPerTxAnswer) });\n console.log(`āœ… Updated max per tx to $${maxPerTxAnswer}`);\n }\n\n if (maxPerDayAnswer) {\n client.updateConfig({ maxPerDay: parseFloat(maxPerDayAnswer) });\n console.log(`āœ… Updated max per day to $${maxPerDayAnswer}`);\n }\n } else {\n // Non-interactive mode\n if (options.maxPerTx) {\n client.updateConfig({ maxPerTx: parseFloat(options.maxPerTx) });\n console.log(`āœ… Updated max per tx to $${options.maxPerTx}`);\n }\n if (options.maxPerDay) {\n client.updateConfig({ maxPerDay: parseFloat(options.maxPerDay) });\n console.log(`āœ… Updated max per day to $${options.maxPerDay}`);\n }\n }\n });\n\n/**\n * npx moltspay status\n */\nprogram\n .command('status')\n .description('Show wallet status and balance')\n .option('--config-dir <dir>', 'Config directory', DEFAULT_CONFIG_DIR)\n .option('--json', 'Output as JSON')\n .action(async (options) => {\n const client = new MoltsPayClient({ configDir: options.configDir });\n\n if (!client.isInitialized) {\n if (options.json) {\n console.log(JSON.stringify({ error: 'Not initialized' }));\n } else {\n console.log('āŒ Not initialized. Run: npx moltspay init');\n }\n return;\n }\n\n const config = client.getConfig();\n \n let balance = { usdc: 0, native: 0 };\n try {\n balance = await client.getBalance();\n } catch (err: any) {\n console.error('Warning: Could not fetch balance:', err.message);\n }\n\n if (options.json) {\n console.log(JSON.stringify({\n address: client.address,\n chain: config.chain,\n balance,\n limits: config.limits,\n }, null, 2));\n } else {\n console.log('\\nšŸ“Š MoltsPay Status\\n');\n console.log(` Wallet: ${client.address}`);\n console.log(` Chain: ${config.chain}`);\n console.log(` Balance: ${balance.usdc.toFixed(2)} USDC`);\n console.log(` Native: ${balance.native.toFixed(6)} ETH`);\n console.log('');\n console.log(' Limits:');\n console.log(` Max per tx: $${config.limits.maxPerTx}`);\n console.log(` Max per day: $${config.limits.maxPerDay}`);\n console.log('');\n }\n });\n\n/**\n * npx moltspay services <url>\n */\nprogram\n .command('services <url>')\n .description('List services from a provider')\n .option('--json', 'Output as JSON')\n .action(async (url, options) => {\n try {\n const client = new MoltsPayClient();\n const services = await client.getServices(url);\n\n if (options.json) {\n console.log(JSON.stringify(services, null, 2));\n } else {\n console.log(`\\nšŸŖ ${services.provider.name}\\n`);\n console.log(` ${services.provider.description || ''}`);\n console.log(` Wallet: ${services.provider.wallet}`);\n console.log(` Chain: ${services.provider.chain}`);\n console.log('\\nšŸ“¦ Services:\\n');\n \n for (const svc of services.services) {\n const status = svc.available ? 'āœ…' : 'āŒ';\n console.log(` ${status} ${svc.id}`);\n console.log(` ${svc.name} - $${svc.price} ${svc.currency}`);\n if (svc.description) {\n console.log(` ${svc.description}`);\n }\n console.log('');\n }\n }\n } catch (err: any) {\n console.error('āŒ Error:', err.message);\n }\n });\n\n/**\n * npx moltspay start <manifest>\n * \n * Start server from moltspay.services.json\n * Services with \"command\" field are auto-registered as skills.\n */\nprogram\n .command('start <manifest>')\n .description('Start MoltsPay server from services manifest')\n .option('-p, --port <port>', 'Port to listen on', '3000')\n .option('--host <host>', 'Host to bind', '0.0.0.0')\n .action(async (manifest, options) => {\n const manifestPath = resolve(manifest);\n \n if (!existsSync(manifestPath)) {\n console.error(`āŒ Manifest not found: ${manifestPath}`);\n process.exit(1);\n }\n\n const port = parseInt(options.port, 10);\n const host = options.host;\n\n console.log(`\\nšŸš€ Starting MoltsPay Server\\n`);\n console.log(` Manifest: ${manifestPath}`);\n console.log(` Port: ${port}`);\n console.log('');\n\n try {\n const server = new MoltsPayServer(manifestPath, { port, host });\n\n // Get manifest to check for command-based skills\n const manifestContent = await import('fs').then(fs => \n JSON.parse(fs.readFileSync(manifestPath, 'utf-8'))\n );\n\n // Auto-register skills that have a \"command\" field\n for (const service of manifestContent.services) {\n if (service.command) {\n const workdir = dirname(manifestPath);\n \n server.skill(service.id, async (params) => {\n return new Promise((resolve, reject) => {\n const proc = spawn('sh', ['-c', service.command], {\n cwd: workdir,\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n\n let stdout = '';\n let stderr = '';\n\n proc.stdout.on('data', (data) => {\n stdout += data.toString();\n });\n\n proc.stderr.on('data', (data) => {\n stderr += data.toString();\n // Log stderr in real-time for debugging\n process.stderr.write(data);\n });\n\n // Send params as JSON to stdin\n proc.stdin.write(JSON.stringify(params));\n proc.stdin.end();\n\n proc.on('close', (code) => {\n if (code !== 0) {\n reject(new Error(`Command failed (exit ${code}): ${stderr || 'Unknown error'}`));\n return;\n }\n\n // Try to parse output as JSON\n try {\n const result = JSON.parse(stdout.trim());\n resolve(result);\n } catch {\n // If not JSON, return as raw output\n resolve({ output: stdout.trim() });\n }\n });\n\n proc.on('error', (err) => {\n reject(new Error(`Failed to spawn command: ${err.message}`));\n });\n });\n });\n }\n }\n\n // Write PID file\n const pidData = { pid: process.pid, port, manifest: manifestPath };\n writeFileSync(PID_FILE, JSON.stringify(pidData, null, 2));\n console.log(` PID file: ${PID_FILE}`);\n console.log('');\n\n // Start listening\n server.listen(port);\n\n // Cleanup function\n const cleanup = () => {\n try {\n if (existsSync(PID_FILE)) {\n unlinkSync(PID_FILE);\n }\n } catch {}\n };\n\n // Handle graceful shutdown\n process.on('SIGINT', () => {\n console.log('\\n\\nšŸ‘‹ Shutting down...');\n cleanup();\n process.exit(0);\n });\n\n process.on('SIGTERM', () => {\n console.log('\\n\\nšŸ‘‹ Shutting down...');\n cleanup();\n process.exit(0);\n });\n\n process.on('exit', cleanup);\n\n } catch (err: any) {\n console.error(`āŒ Failed to start server: ${err.message}`);\n process.exit(1);\n }\n });\n\n/**\n * npx moltspay stop\n * \n * Stop the running MoltsPay server gracefully\n */\nprogram\n .command('stop')\n .description('Stop the running MoltsPay server')\n .action(async () => {\n if (!existsSync(PID_FILE)) {\n console.log('āŒ No running server found (no PID file)');\n process.exit(1);\n }\n\n try {\n const pidData = JSON.parse(readFileSync(PID_FILE, 'utf-8'));\n const { pid, port, manifest } = pidData;\n\n console.log(`\\nšŸ›‘ Stopping MoltsPay Server\\n`);\n console.log(` PID: ${pid}`);\n console.log(` Port: ${port}`);\n console.log(` Manifest: ${manifest}`);\n console.log('');\n\n // Check if process is running\n try {\n process.kill(pid, 0); // Test if process exists\n } catch {\n console.log('āš ļø Process not running, cleaning up PID file...');\n unlinkSync(PID_FILE);\n process.exit(0);\n }\n\n // Send SIGTERM for graceful shutdown\n process.kill(pid, 'SIGTERM');\n console.log('āœ… Sent SIGTERM to server');\n\n // Wait a bit and check if it stopped\n await new Promise(resolve => setTimeout(resolve, 1000));\n\n try {\n process.kill(pid, 0);\n console.log('āš ļø Server still running, sending SIGKILL...');\n process.kill(pid, 'SIGKILL');\n } catch {\n // Process is gone, good\n }\n\n // Clean up PID file if still exists\n if (existsSync(PID_FILE)) {\n unlinkSync(PID_FILE);\n }\n\n console.log('āœ… Server stopped\\n');\n\n } catch (err: any) {\n console.error(`āŒ Failed to stop server: ${err.message}`);\n process.exit(1);\n }\n });\n\nprogram.parse();\n","/**\n * MoltsPay Client - Pay for AI Agent services\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 } from 'fs';\nimport { homedir } from 'os';\nimport { join } from 'path';\nimport { Wallet } from 'ethers';\nimport { getChain, type ChainName } from '../chains/index.js';\nimport {\n ClientConfig,\n WalletData,\n PaymentRequired,\n ServicesResponse,\n VerifyResponse,\n MoltsPayClientOptions,\n} from './types.js';\n\nexport * from './types.js';\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 \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 const res = await fetch(`${serverUrl}/services`);\n if (!res.ok) {\n throw new Error(`Failed to get services: ${res.statusText}`);\n }\n return res.json() as Promise<ServicesResponse>;\n }\n\n /**\n * Pay for a service and get the result\n */\n async pay(\n serverUrl: string,\n service: string,\n params: Record<string, any>\n ): Promise<Record<string, any>> {\n if (!this.wallet) {\n throw new Error('Client not initialized. Run: npx moltspay init');\n }\n\n // Step 1: Request payment info\n const payRes = await fetch(`${serverUrl}/pay`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ service, params }),\n });\n\n if (payRes.status !== 402) {\n const err = await payRes.json() as { error?: string };\n throw new Error(err.error || 'Unexpected response');\n }\n\n const paymentReq = await payRes.json() as PaymentRequired;\n const { payment } = paymentReq;\n\n // Step 2: Check limits\n this.checkLimits(payment.amount);\n\n // Step 3: Execute payment on-chain\n console.log(`[MoltsPay] Paying $${payment.amount} ${payment.currency} to ${payment.wallet}`);\n const txHash = await this.executePayment(payment);\n console.log(`[MoltsPay] Payment tx: ${txHash}`);\n\n // Step 4: Verify and get result\n const verifyRes = await fetch(`${serverUrl}/verify`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n chargeId: payment.chargeId,\n txHash,\n }),\n });\n\n if (!verifyRes.ok) {\n const err = await verifyRes.json() as { error?: string };\n throw new Error(err.error || 'Verification failed');\n }\n\n const result = await verifyRes.json() as VerifyResponse;\n \n // Update spending tracking\n this.recordSpending(payment.amount);\n \n return result.result;\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 }\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\n */\n private recordSpending(amount: number): void {\n this.todaySpending += amount;\n }\n\n /**\n * Execute payment on-chain\n */\n private async executePayment(payment: PaymentRequired['payment']): Promise<string> {\n let chain;\n try {\n chain = getChain(payment.chain as ChainName);\n } catch {\n throw new Error(`Unknown chain: ${payment.chain}`);\n }\n\n // For now, we'll use a simple USDC transfer\n // In production, this would connect to the actual chain\n const { ethers } = await import('ethers');\n \n const provider = new ethers.JsonRpcProvider(chain.rpc);\n const signer = new ethers.Wallet(this.walletData!.privateKey, provider);\n\n // USDC contract (Base mainnet)\n const usdcAddress = chain.usdc;\n const usdcAbi = [\n 'function transfer(address to, uint256 amount) returns (bool)',\n 'function balanceOf(address account) view returns (uint256)',\n ];\n \n const usdc = new ethers.Contract(usdcAddress, usdcAbi, signer);\n\n // Convert amount to USDC decimals (6)\n const amountInUnits = ethers.parseUnits(payment.amount.toString(), 6);\n\n // Check balance\n const balance = await usdc.balanceOf(this.wallet!.address);\n if (balance < amountInUnits) {\n throw new Error(\n `Insufficient USDC balance: ${ethers.formatUnits(balance, 6)} < ${payment.amount}`\n );\n }\n\n // Send transaction\n const tx = await usdc.transfer(payment.wallet, amountInUnits);\n const receipt = await tx.wait();\n\n return receipt.hash;\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 private loadWallet(): WalletData | null {\n const walletPath = join(this.configDir, 'wallet.json');\n if (existsSync(walletPath)) {\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\n const walletPath = join(configDir, 'wallet.json');\n writeFileSync(walletPath, JSON.stringify(walletData, null, 2));\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\n */\n async getBalance(): Promise<{ usdc: 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 { ethers } = await import('ethers');\n const provider = new ethers.JsonRpcProvider(chain.rpc);\n\n // Get native balance\n const nativeBalance = await provider.getBalance(this.wallet.address);\n\n // Get USDC balance\n const usdcAbi = ['function balanceOf(address) view returns (uint256)'];\n const usdc = new ethers.Contract(chain.usdc, usdcAbi, provider);\n const usdcBalance = await usdc.balanceOf(this.wallet.address);\n\n return {\n usdc: parseFloat(ethers.formatUnits(usdcBalance, 6)),\n native: parseFloat(ethers.formatEther(nativeBalance)),\n };\n }\n}\n","/**\n * Blockchain Configuration\n */\n\nimport type { ChainConfig, ChainName } 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 usdc: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\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-rpc.com',\n usdc: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',\n explorer: 'https://polygonscan.com/address/',\n explorerTx: 'https://polygonscan.com/tx/',\n avgBlockTime: 2,\n },\n ethereum: {\n name: 'Ethereum',\n chainId: 1,\n rpc: 'https://eth.llamarpc.com',\n usdc: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',\n explorer: 'https://etherscan.io/address/',\n explorerTx: 'https://etherscan.io/tx/',\n avgBlockTime: 12,\n },\n\n // ============ Testnet ============\n base_sepolia: {\n name: 'Base Sepolia',\n chainId: 84532,\n rpc: 'https://sepolia.base.org',\n usdc: '0x036CbD53842c5426634e7929541eC2318f3dCF7e',\n explorer: 'https://sepolia.basescan.org/address/',\n explorerTx: 'https://sepolia.basescan.org/tx/',\n avgBlockTime: 2,\n },\n sepolia: {\n name: 'Sepolia',\n chainId: 11155111,\n rpc: 'https://rpc.sepolia.org',\n usdc: '0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238',\n explorer: 'https://sepolia.etherscan.io/address/',\n explorerTx: 'https://sepolia.etherscan.io/tx/',\n avgBlockTime: 12,\n },\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 };\n","/**\n * MoltsPay Server - Payment infrastructure for AI Agents\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 } from 'fs';\nimport { createServer, IncomingMessage, ServerResponse } from 'http';\nimport { verifyPayment } from '../verify/index.js';\nimport {\n ServicesManifest,\n ServiceConfig,\n SkillFunction,\n RegisteredSkill,\n Charge,\n ChargeStatus,\n PaymentRequest,\n MoltsPayServerOptions,\n} from './types.js';\n\nexport * from './types.js';\n\nfunction generateChargeId(): string {\n return 'ch_' + Math.random().toString(36).substring(2, 15);\n}\n\nexport class MoltsPayServer {\n private manifest: ServicesManifest;\n private skills: Map<string, RegisteredSkill> = new Map();\n private charges: Map<string, Charge> = new Map();\n private options: MoltsPayServerOptions;\n\n constructor(servicesPath: string, options: MoltsPayServerOptions = {}) {\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 chargeExpirySecs: options.chargeExpirySecs || 300, // 5 minutes\n };\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] Wallet: ${this.manifest.provider.wallet}`);\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\n this.skills.set(serviceId, {\n id: serviceId,\n config,\n handler,\n });\n\n console.log(`[MoltsPay] Registered skill: ${serviceId} ($${config.price} ${config.currency})`);\n return this;\n }\n\n /**\n * Start the server\n */\n listen(port?: number): void {\n const p = port || this.options.port!;\n \n const server = createServer((req, res) => this.handleRequest(req, res));\n \n server.listen(p, this.options.host, () => {\n console.log(`[MoltsPay] Server listening on http://${this.options.host}:${p}`);\n console.log(`[MoltsPay] Endpoints:`);\n console.log(` GET /services - List available services`);\n console.log(` POST /pay - Create payment & execute service`);\n console.log(` POST /verify - Verify payment & get result`);\n console.log(` GET /status/:id - Check charge status`);\n });\n }\n\n private async handleRequest(req: IncomingMessage, res: ServerResponse): Promise<void> {\n const url = new URL(req.url || '/', `http://${req.headers.host}`);\n const path = url.pathname;\n const method = req.method || 'GET';\n\n // CORS headers\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');\n\n if (method === 'OPTIONS') {\n res.writeHead(204);\n res.end();\n return;\n }\n\n try {\n if (method === 'GET' && path === '/services') {\n return this.handleGetServices(res);\n }\n\n if (method === 'POST' && path === '/pay') {\n const body = await this.readBody(req);\n return this.handlePay(body, res);\n }\n\n if (method === 'POST' && path === '/verify') {\n const body = await this.readBody(req);\n return this.handleVerify(body, res);\n }\n\n if (method === 'GET' && path.startsWith('/status/')) {\n const chargeId = path.replace('/status/', '');\n return this.handleStatus(chargeId, 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 /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 input: s.input,\n output: s.output,\n available: this.skills.has(s.id),\n }));\n\n this.sendJson(res, 200, {\n provider: this.manifest.provider,\n services,\n });\n }\n\n /**\n * POST /pay - Create payment request\n * Body: { service: string, params: object }\n */\n private handlePay(body: any, res: ServerResponse): 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 // Create charge\n const chargeId = generateChargeId();\n const now = Date.now();\n const charge: Charge = {\n id: chargeId,\n service,\n params: params || {},\n amount: skill.config.price,\n currency: skill.config.currency,\n status: 'pending',\n createdAt: now,\n expiresAt: now + (this.options.chargeExpirySecs! * 1000),\n };\n\n this.charges.set(chargeId, charge);\n\n // Return payment request\n const paymentRequest: PaymentRequest = {\n chargeId,\n service,\n amount: charge.amount,\n currency: charge.currency,\n wallet: this.manifest.provider.wallet,\n chain: this.manifest.provider.chain,\n expiresAt: charge.expiresAt,\n };\n\n this.sendJson(res, 402, {\n message: 'Payment required',\n payment: paymentRequest,\n });\n }\n\n /**\n * POST /verify - Verify payment and execute skill\n * Body: { chargeId: string, txHash: string }\n */\n private async handleVerify(body: any, res: ServerResponse): Promise<void> {\n const { chargeId, txHash } = body;\n\n if (!chargeId || !txHash) {\n return this.sendJson(res, 400, { error: 'Missing chargeId or txHash' });\n }\n\n const charge = this.charges.get(chargeId);\n if (!charge) {\n return this.sendJson(res, 404, { error: 'Charge not found' });\n }\n\n // Check expiry\n if (Date.now() > charge.expiresAt) {\n charge.status = 'expired';\n return this.sendJson(res, 400, { error: 'Charge expired' });\n }\n\n // Check if already paid\n if (charge.status === 'completed') {\n return this.sendJson(res, 200, {\n status: 'completed',\n result: charge.result,\n });\n }\n\n try {\n const verification = await verifyPayment({\n txHash,\n expectedTo: this.manifest.provider.wallet,\n expectedAmount: charge.amount,\n chain: this.manifest.provider.chain,\n });\n\n if (!verification.verified) {\n charge.status = 'failed';\n return this.sendJson(res, 400, {\n error: 'Payment verification failed',\n reason: verification.error,\n });\n }\n\n // Payment verified - update charge\n charge.status = 'paid';\n charge.txHash = txHash;\n charge.paidAt = Date.now();\n\n // Execute skill\n const skill = this.skills.get(charge.service)!;\n console.log(`[MoltsPay] Executing skill: ${charge.service}`);\n \n const result = await skill.handler(charge.params);\n \n charge.status = 'completed';\n charge.result = result;\n charge.completedAt = Date.now();\n\n this.sendJson(res, 200, {\n status: 'completed',\n chargeId,\n txHash,\n result,\n });\n } catch (err: any) {\n console.error('[MoltsPay] Skill execution error:', err);\n charge.status = 'failed';\n this.sendJson(res, 500, {\n error: 'Skill execution failed',\n message: err.message,\n });\n }\n }\n\n /**\n * GET /status/:chargeId - Check charge status\n */\n private handleStatus(chargeId: string, res: ServerResponse): void {\n const charge = this.charges.get(chargeId);\n if (!charge) {\n return this.sendJson(res, 404, { error: 'Charge not found' });\n }\n\n this.sendJson(res, 200, {\n chargeId: charge.id,\n service: charge.service,\n amount: charge.amount,\n currency: charge.currency,\n status: charge.status,\n txHash: charge.txHash,\n result: charge.status === 'completed' ? charge.result : undefined,\n createdAt: charge.createdAt,\n expiresAt: charge.expiresAt,\n });\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(res: ServerResponse, status: number, data: any): void {\n res.writeHead(status, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify(data, null, 2));\n }\n}\n","/**\n * On-chain Payment Verification Module\n */\n\nimport { ethers } from 'ethers';\nimport { getChain, getChainById, type ChainConfig, type ChainName } 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}\n\nexport interface VerifyPaymentResult {\n verified: boolean;\n amount?: number;\n from?: string;\n to?: string;\n txHash?: string;\n blockNumber?: number;\n error?: string;\n}\n\n/**\n * Verify on-chain payment\n */\nexport async function verifyPayment(params: VerifyPaymentParams): Promise<VerifyPaymentResult> {\n const { txHash, expectedAmount, expectedTo } = 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 // Parse Transfer event\n const usdcAddress = chain.usdc?.toLowerCase();\n if (!usdcAddress) {\n return { verified: false, error: `Chain ${chain.name} USDC address not configured` };\n }\n\n for (const log of receipt.logs) {\n // Check if USDC contract\n if (log.address.toLowerCase() !== usdcAddress) {\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 amount = Number(amountRaw) / 1e6; // USDC 6 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} USDC, expected ${expectedAmount} USDC`,\n amount,\n from,\n to,\n txHash,\n blockNumber: receipt.blockNumber,\n };\n }\n\n // Verification successful\n return {\n verified: true,\n amount,\n from,\n to,\n txHash,\n blockNumber: receipt.blockNumber,\n };\n }\n\n return { verified: false, error: 'No USDC 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"],"mappings":"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","names":["import_os","import_path","import_fs","ethers","import_fs","import_ethers","resolve","resolve"]}
1
+ {"version":3,"sources":["../../src/cli/index.ts","../../src/client/index.ts","../../src/chains/index.ts","../../src/server/index.ts","../../src/verify/index.ts"],"sourcesContent":["#!/usr/bin/env node\n\n/**\n * MoltsPay CLI\n * \n * Commands:\n * npx moltspay init - Create wallet, set limits\n * npx moltspay config - Update settings\n * npx moltspay status - Show wallet and balance\n * npx moltspay services <url> - List services from provider\n * npx moltspay start <manifest> - Start server from services.json\n */\n\nimport { Command } from 'commander';\nimport { homedir } from 'os';\nimport { join, dirname, resolve } from 'path';\nimport { existsSync, writeFileSync, readFileSync, unlinkSync, mkdirSync } from 'fs';\nimport { spawn } from 'child_process';\nimport { MoltsPayClient } from '../client/index.js';\nimport { MoltsPayServer } from '../server/index.js';\nimport * as readline from 'readline';\n\nconst program = new Command();\nconst DEFAULT_CONFIG_DIR = join(homedir(), '.moltspay');\nconst PID_FILE = join(DEFAULT_CONFIG_DIR, 'server.pid');\n\n// Ensure config dir exists\nif (!existsSync(DEFAULT_CONFIG_DIR)) {\n mkdirSync(DEFAULT_CONFIG_DIR, { recursive: true });\n}\n\nfunction prompt(question: string): Promise<string> {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n return new Promise(resolve => {\n rl.question(question, answer => {\n rl.close();\n resolve(answer.trim());\n });\n });\n}\n\nprogram\n .name('moltspay')\n .description('MoltsPay - Payment infrastructure for AI Agents')\n .version('1.0.0');\n\n/**\n * npx moltspay init\n */\nprogram\n .command('init')\n .description('Initialize MoltsPay client (create wallet, set limits)')\n .option('--chain <chain>', 'Blockchain to use', 'base')\n .option('--max-per-tx <amount>', 'Max amount per transaction')\n .option('--max-per-day <amount>', 'Max amount per day')\n .option('--config-dir <dir>', 'Config directory', DEFAULT_CONFIG_DIR)\n .action(async (options) => {\n console.log('\\nšŸ” MoltsPay Client Setup\\n');\n\n // Check if already initialized\n if (existsSync(join(options.configDir, 'wallet.json'))) {\n console.log('āš ļø Already initialized. Use \"moltspay config\" to update settings.');\n console.log(` Config dir: ${options.configDir}`);\n return;\n }\n\n // Get options interactively if not provided\n let chain = options.chain;\n let maxPerTx = options.maxPerTx ? parseFloat(options.maxPerTx) : null;\n let maxPerDay = options.maxPerDay ? parseFloat(options.maxPerDay) : null;\n\n if (!maxPerTx) {\n const answer = await prompt('Max per transaction (USD) [100]: ');\n maxPerTx = answer ? parseFloat(answer) : 100;\n }\n\n if (!maxPerDay) {\n const answer = await prompt('Max per day (USD) [1000]: ');\n maxPerDay = answer ? parseFloat(answer) : 1000;\n }\n\n console.log('\\nCreating wallet...');\n\n const result = MoltsPayClient.init(options.configDir, {\n chain,\n maxPerTx,\n maxPerDay,\n });\n\n console.log(`\\nāœ… Wallet created: ${result.address}`);\n console.log(`\\nšŸ“ Config saved to: ${result.configDir}`);\n console.log(`\\nāš ļø IMPORTANT: Back up ${join(result.configDir, 'wallet.json')}`);\n console.log(` This file contains your private key!\\n`);\n console.log(`šŸ’° Fund your wallet with USDC on ${chain} to start using services.\\n`);\n });\n\n/**\n * npx moltspay config\n */\nprogram\n .command('config')\n .description('Update MoltsPay settings')\n .option('--max-per-tx <amount>', 'Max amount per transaction')\n .option('--max-per-day <amount>', 'Max amount per day')\n .option('--config-dir <dir>', 'Config directory', DEFAULT_CONFIG_DIR)\n .action(async (options) => {\n const client = new MoltsPayClient({ configDir: options.configDir });\n\n if (!client.isInitialized) {\n console.log('āŒ Not initialized. Run: npx moltspay init');\n return;\n }\n\n const currentConfig = client.getConfig();\n\n // If no options provided, show interactive mode\n if (!options.maxPerTx && !options.maxPerDay) {\n console.log('\\nšŸ“‹ Current Settings:\\n');\n console.log(` Wallet: ${client.address}`);\n console.log(` Chain: ${currentConfig.chain}`);\n console.log(` Max per tx: $${currentConfig.limits.maxPerTx}`);\n console.log(` Max per day: $${currentConfig.limits.maxPerDay}`);\n console.log('');\n\n const maxPerTxAnswer = await prompt(`New max per tx (USD) [${currentConfig.limits.maxPerTx}]: `);\n const maxPerDayAnswer = await prompt(`New max per day (USD) [${currentConfig.limits.maxPerDay}]: `);\n\n if (maxPerTxAnswer) {\n client.updateConfig({ maxPerTx: parseFloat(maxPerTxAnswer) });\n console.log(`āœ… Updated max per tx to $${maxPerTxAnswer}`);\n }\n\n if (maxPerDayAnswer) {\n client.updateConfig({ maxPerDay: parseFloat(maxPerDayAnswer) });\n console.log(`āœ… Updated max per day to $${maxPerDayAnswer}`);\n }\n } else {\n // Non-interactive mode\n if (options.maxPerTx) {\n client.updateConfig({ maxPerTx: parseFloat(options.maxPerTx) });\n console.log(`āœ… Updated max per tx to $${options.maxPerTx}`);\n }\n if (options.maxPerDay) {\n client.updateConfig({ maxPerDay: parseFloat(options.maxPerDay) });\n console.log(`āœ… Updated max per day to $${options.maxPerDay}`);\n }\n }\n });\n\n/**\n * npx moltspay status\n */\nprogram\n .command('status')\n .description('Show wallet status and balance')\n .option('--config-dir <dir>', 'Config directory', DEFAULT_CONFIG_DIR)\n .option('--json', 'Output as JSON')\n .action(async (options) => {\n const client = new MoltsPayClient({ configDir: options.configDir });\n\n if (!client.isInitialized) {\n if (options.json) {\n console.log(JSON.stringify({ error: 'Not initialized' }));\n } else {\n console.log('āŒ Not initialized. Run: npx moltspay init');\n }\n return;\n }\n\n const config = client.getConfig();\n \n let balance = { usdc: 0, native: 0 };\n try {\n balance = await client.getBalance();\n } catch (err: any) {\n console.error('Warning: Could not fetch balance:', err.message);\n }\n\n if (options.json) {\n console.log(JSON.stringify({\n address: client.address,\n chain: config.chain,\n balance,\n limits: config.limits,\n }, null, 2));\n } else {\n console.log('\\nšŸ“Š MoltsPay Status\\n');\n console.log(` Wallet: ${client.address}`);\n console.log(` Chain: ${config.chain}`);\n console.log(` Balance: ${balance.usdc.toFixed(2)} USDC`);\n console.log(` Native: ${balance.native.toFixed(6)} ETH`);\n console.log('');\n console.log(' Limits:');\n console.log(` Max per tx: $${config.limits.maxPerTx}`);\n console.log(` Max per day: $${config.limits.maxPerDay}`);\n console.log('');\n }\n });\n\n/**\n * npx moltspay services <url>\n */\nprogram\n .command('services <url>')\n .description('List services from a provider')\n .option('--json', 'Output as JSON')\n .action(async (url, options) => {\n try {\n const client = new MoltsPayClient();\n const services = await client.getServices(url);\n\n if (options.json) {\n console.log(JSON.stringify(services, null, 2));\n } else {\n console.log(`\\nšŸŖ ${services.provider.name}\\n`);\n console.log(` ${services.provider.description || ''}`);\n console.log(` Wallet: ${services.provider.wallet}`);\n console.log(` Chain: ${services.provider.chain}`);\n console.log('\\nšŸ“¦ Services:\\n');\n \n for (const svc of services.services) {\n const status = svc.available ? 'āœ…' : 'āŒ';\n console.log(` ${status} ${svc.id}`);\n console.log(` ${svc.name} - $${svc.price} ${svc.currency}`);\n if (svc.description) {\n console.log(` ${svc.description}`);\n }\n console.log('');\n }\n }\n } catch (err: any) {\n console.error('āŒ Error:', err.message);\n }\n });\n\n/**\n * npx moltspay start <manifest>\n * \n * Start server from moltspay.services.json\n * Services with \"command\" field are auto-registered as skills.\n */\nprogram\n .command('start <manifest>')\n .description('Start MoltsPay server from services manifest')\n .option('-p, --port <port>', 'Port to listen on', '3000')\n .option('--host <host>', 'Host to bind', '0.0.0.0')\n .action(async (manifest, options) => {\n const manifestPath = resolve(manifest);\n \n if (!existsSync(manifestPath)) {\n console.error(`āŒ Manifest not found: ${manifestPath}`);\n process.exit(1);\n }\n\n const port = parseInt(options.port, 10);\n const host = options.host;\n\n console.log(`\\nšŸš€ Starting MoltsPay Server\\n`);\n console.log(` Manifest: ${manifestPath}`);\n console.log(` Port: ${port}`);\n console.log('');\n\n try {\n const server = new MoltsPayServer(manifestPath, { port, host });\n\n // Get manifest to check for command-based skills\n const manifestContent = await import('fs').then(fs => \n JSON.parse(fs.readFileSync(manifestPath, 'utf-8'))\n );\n\n // Auto-register skills that have a \"command\" field\n for (const service of manifestContent.services) {\n if (service.command) {\n const workdir = dirname(manifestPath);\n \n server.skill(service.id, async (params) => {\n return new Promise((resolve, reject) => {\n const proc = spawn('sh', ['-c', service.command], {\n cwd: workdir,\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n\n let stdout = '';\n let stderr = '';\n\n proc.stdout.on('data', (data) => {\n stdout += data.toString();\n });\n\n proc.stderr.on('data', (data) => {\n stderr += data.toString();\n // Log stderr in real-time for debugging\n process.stderr.write(data);\n });\n\n // Send params as JSON to stdin\n proc.stdin.write(JSON.stringify(params));\n proc.stdin.end();\n\n proc.on('close', (code) => {\n if (code !== 0) {\n reject(new Error(`Command failed (exit ${code}): ${stderr || 'Unknown error'}`));\n return;\n }\n\n // Try to parse output as JSON\n try {\n const result = JSON.parse(stdout.trim());\n resolve(result);\n } catch {\n // If not JSON, return as raw output\n resolve({ output: stdout.trim() });\n }\n });\n\n proc.on('error', (err) => {\n reject(new Error(`Failed to spawn command: ${err.message}`));\n });\n });\n });\n }\n }\n\n // Write PID file\n const pidData = { pid: process.pid, port, manifest: manifestPath };\n writeFileSync(PID_FILE, JSON.stringify(pidData, null, 2));\n console.log(` PID file: ${PID_FILE}`);\n console.log('');\n\n // Start listening\n server.listen(port);\n\n // Cleanup function\n const cleanup = () => {\n try {\n if (existsSync(PID_FILE)) {\n unlinkSync(PID_FILE);\n }\n } catch {}\n };\n\n // Handle graceful shutdown\n process.on('SIGINT', () => {\n console.log('\\n\\nšŸ‘‹ Shutting down...');\n cleanup();\n process.exit(0);\n });\n\n process.on('SIGTERM', () => {\n console.log('\\n\\nšŸ‘‹ Shutting down...');\n cleanup();\n process.exit(0);\n });\n\n process.on('exit', cleanup);\n\n } catch (err: any) {\n console.error(`āŒ Failed to start server: ${err.message}`);\n process.exit(1);\n }\n });\n\n/**\n * npx moltspay stop\n * \n * Stop the running MoltsPay server gracefully\n */\nprogram\n .command('stop')\n .description('Stop the running MoltsPay server')\n .action(async () => {\n if (!existsSync(PID_FILE)) {\n console.log('āŒ No running server found (no PID file)');\n process.exit(1);\n }\n\n try {\n const pidData = JSON.parse(readFileSync(PID_FILE, 'utf-8'));\n const { pid, port, manifest } = pidData;\n\n console.log(`\\nšŸ›‘ Stopping MoltsPay Server\\n`);\n console.log(` PID: ${pid}`);\n console.log(` Port: ${port}`);\n console.log(` Manifest: ${manifest}`);\n console.log('');\n\n // Check if process is running\n try {\n process.kill(pid, 0); // Test if process exists\n } catch {\n console.log('āš ļø Process not running, cleaning up PID file...');\n unlinkSync(PID_FILE);\n process.exit(0);\n }\n\n // Send SIGTERM for graceful shutdown\n process.kill(pid, 'SIGTERM');\n console.log('āœ… Sent SIGTERM to server');\n\n // Wait a bit and check if it stopped\n await new Promise(resolve => setTimeout(resolve, 1000));\n\n try {\n process.kill(pid, 0);\n console.log('āš ļø Server still running, sending SIGKILL...');\n process.kill(pid, 'SIGKILL');\n } catch {\n // Process is gone, good\n }\n\n // Clean up PID file if still exists\n if (existsSync(PID_FILE)) {\n unlinkSync(PID_FILE);\n }\n\n console.log('āœ… Server stopped\\n');\n\n } catch (err: any) {\n console.error(`āŒ Failed to stop server: ${err.message}`);\n process.exit(1);\n }\n });\n\n/**\n * npx moltspay pay <server> <service> <params>\n * \n * Pay for a service and get the result\n */\nprogram\n .command('pay <server> <service> [params]')\n .description('Pay for a service and get the result')\n .option('--prompt <text>', 'Prompt for the service')\n .option('--image <url>', 'Image URL (for image-to-video)')\n .option('--json', 'Output raw JSON only')\n .action(async (server, service, paramsJson, options) => {\n const client = new MoltsPayClient();\n\n if (!client.isInitialized) {\n console.error('āŒ Wallet not initialized. Run: npx moltspay init');\n process.exit(1);\n }\n\n // Build params from JSON string or options\n let params: Record<string, any> = {};\n \n if (paramsJson) {\n try {\n params = JSON.parse(paramsJson);\n } catch {\n console.error('āŒ Invalid JSON params');\n process.exit(1);\n }\n }\n \n // Override with CLI options\n if (options.prompt) params.prompt = options.prompt;\n if (options.image) params.image_url = options.image;\n\n if (!params.prompt) {\n console.error('āŒ Missing prompt. Use --prompt or pass JSON params');\n process.exit(1);\n }\n\n if (!options.json) {\n console.log(`\\nšŸ’³ MoltsPay - Paying for service\\n`);\n console.log(` Server: ${server}`);\n console.log(` Service: ${service}`);\n console.log(` Prompt: ${params.prompt}`);\n if (params.image_url) console.log(` Image: ${params.image_url}`);\n console.log(` Wallet: ${client.address}`);\n console.log('');\n }\n\n try {\n const result = await client.pay(server, service, params);\n \n if (options.json) {\n console.log(JSON.stringify(result));\n } else {\n console.log('āœ… Success!\\n');\n console.log(JSON.stringify(result, null, 2));\n console.log('');\n }\n } catch (err: any) {\n if (options.json) {\n console.log(JSON.stringify({ error: err.message }));\n } else {\n console.error(`āŒ Error: ${err.message}`);\n }\n process.exit(1);\n }\n });\n\nprogram.parse();\n","/**\n * MoltsPay Client - Pay for AI Agent services\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 } from 'fs';\nimport { homedir } from 'os';\nimport { join } from 'path';\nimport { Wallet } from 'ethers';\nimport { getChain, type ChainName } from '../chains/index.js';\nimport {\n ClientConfig,\n WalletData,\n PaymentRequired,\n ServicesResponse,\n VerifyResponse,\n MoltsPayClientOptions,\n} from './types.js';\n\nexport * from './types.js';\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 \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 const res = await fetch(`${serverUrl}/services`);\n if (!res.ok) {\n throw new Error(`Failed to get services: ${res.statusText}`);\n }\n return res.json() as Promise<ServicesResponse>;\n }\n\n /**\n * Pay for a service and get the result\n */\n async pay(\n serverUrl: string,\n service: string,\n params: Record<string, any>\n ): Promise<Record<string, any>> {\n if (!this.wallet) {\n throw new Error('Client not initialized. Run: npx moltspay init');\n }\n\n // Step 1: Request payment info\n const payRes = await fetch(`${serverUrl}/pay`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ service, params }),\n });\n\n if (payRes.status !== 402) {\n const err = await payRes.json() as { error?: string };\n throw new Error(err.error || 'Unexpected response');\n }\n\n const paymentReq = await payRes.json() as PaymentRequired;\n const { payment } = paymentReq;\n\n // Step 2: Check limits\n this.checkLimits(payment.amount);\n\n // Step 3: Execute payment on-chain\n console.log(`[MoltsPay] Paying $${payment.amount} ${payment.currency} to ${payment.wallet}`);\n const txHash = await this.executePayment(payment);\n console.log(`[MoltsPay] Payment tx: ${txHash}`);\n\n // Step 4: Verify and get result\n const verifyRes = await fetch(`${serverUrl}/verify`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n chargeId: payment.chargeId,\n txHash,\n }),\n });\n\n if (!verifyRes.ok) {\n const err = await verifyRes.json() as { error?: string };\n throw new Error(err.error || 'Verification failed');\n }\n\n const result = await verifyRes.json() as VerifyResponse;\n \n // Update spending tracking\n this.recordSpending(payment.amount);\n \n return result.result;\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 }\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\n */\n private recordSpending(amount: number): void {\n this.todaySpending += amount;\n }\n\n /**\n * Execute payment on-chain\n */\n private async executePayment(payment: PaymentRequired['payment']): Promise<string> {\n let chain;\n try {\n chain = getChain(payment.chain as ChainName);\n } catch {\n throw new Error(`Unknown chain: ${payment.chain}`);\n }\n\n // For now, we'll use a simple USDC transfer\n // In production, this would connect to the actual chain\n const { ethers } = await import('ethers');\n \n const provider = new ethers.JsonRpcProvider(chain.rpc);\n const signer = new ethers.Wallet(this.walletData!.privateKey, provider);\n\n // USDC contract (Base mainnet)\n const usdcAddress = chain.usdc;\n const usdcAbi = [\n 'function transfer(address to, uint256 amount) returns (bool)',\n 'function balanceOf(address account) view returns (uint256)',\n ];\n \n const usdc = new ethers.Contract(usdcAddress, usdcAbi, signer);\n\n // Convert amount to USDC decimals (6)\n const amountInUnits = ethers.parseUnits(payment.amount.toString(), 6);\n\n // Check balance\n const balance = await usdc.balanceOf(this.wallet!.address);\n if (balance < amountInUnits) {\n throw new Error(\n `Insufficient USDC balance: ${ethers.formatUnits(balance, 6)} < ${payment.amount}`\n );\n }\n\n // Send transaction\n const tx = await usdc.transfer(payment.wallet, amountInUnits);\n const receipt = await tx.wait();\n\n return receipt.hash;\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 private loadWallet(): WalletData | null {\n const walletPath = join(this.configDir, 'wallet.json');\n if (existsSync(walletPath)) {\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\n const walletPath = join(configDir, 'wallet.json');\n writeFileSync(walletPath, JSON.stringify(walletData, null, 2));\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\n */\n async getBalance(): Promise<{ usdc: 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 { ethers } = await import('ethers');\n const provider = new ethers.JsonRpcProvider(chain.rpc);\n\n // Get native balance\n const nativeBalance = await provider.getBalance(this.wallet.address);\n\n // Get USDC balance\n const usdcAbi = ['function balanceOf(address) view returns (uint256)'];\n const usdc = new ethers.Contract(chain.usdc, usdcAbi, provider);\n const usdcBalance = await usdc.balanceOf(this.wallet.address);\n\n return {\n usdc: parseFloat(ethers.formatUnits(usdcBalance, 6)),\n native: parseFloat(ethers.formatEther(nativeBalance)),\n };\n }\n}\n","/**\n * Blockchain Configuration\n */\n\nimport type { ChainConfig, ChainName } 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 usdc: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\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-rpc.com',\n usdc: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',\n explorer: 'https://polygonscan.com/address/',\n explorerTx: 'https://polygonscan.com/tx/',\n avgBlockTime: 2,\n },\n ethereum: {\n name: 'Ethereum',\n chainId: 1,\n rpc: 'https://eth.llamarpc.com',\n usdc: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',\n explorer: 'https://etherscan.io/address/',\n explorerTx: 'https://etherscan.io/tx/',\n avgBlockTime: 12,\n },\n\n // ============ Testnet ============\n base_sepolia: {\n name: 'Base Sepolia',\n chainId: 84532,\n rpc: 'https://sepolia.base.org',\n usdc: '0x036CbD53842c5426634e7929541eC2318f3dCF7e',\n explorer: 'https://sepolia.basescan.org/address/',\n explorerTx: 'https://sepolia.basescan.org/tx/',\n avgBlockTime: 2,\n },\n sepolia: {\n name: 'Sepolia',\n chainId: 11155111,\n rpc: 'https://rpc.sepolia.org',\n usdc: '0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238',\n explorer: 'https://sepolia.etherscan.io/address/',\n explorerTx: 'https://sepolia.etherscan.io/tx/',\n avgBlockTime: 12,\n },\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 };\n","/**\n * MoltsPay Server - Payment infrastructure for AI Agents\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 } from 'fs';\nimport { createServer, IncomingMessage, ServerResponse } from 'http';\nimport { verifyPayment } from '../verify/index.js';\nimport {\n ServicesManifest,\n ServiceConfig,\n SkillFunction,\n RegisteredSkill,\n Charge,\n ChargeStatus,\n PaymentRequest,\n MoltsPayServerOptions,\n} from './types.js';\n\nexport * from './types.js';\n\nfunction generateChargeId(): string {\n return 'ch_' + Math.random().toString(36).substring(2, 15);\n}\n\nexport class MoltsPayServer {\n private manifest: ServicesManifest;\n private skills: Map<string, RegisteredSkill> = new Map();\n private charges: Map<string, Charge> = new Map();\n private options: MoltsPayServerOptions;\n\n constructor(servicesPath: string, options: MoltsPayServerOptions = {}) {\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 chargeExpirySecs: options.chargeExpirySecs || 300, // 5 minutes\n };\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] Wallet: ${this.manifest.provider.wallet}`);\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\n this.skills.set(serviceId, {\n id: serviceId,\n config,\n handler,\n });\n\n console.log(`[MoltsPay] Registered skill: ${serviceId} ($${config.price} ${config.currency})`);\n return this;\n }\n\n /**\n * Start the server\n */\n listen(port?: number): void {\n const p = port || this.options.port!;\n \n const server = createServer((req, res) => this.handleRequest(req, res));\n \n server.listen(p, this.options.host, () => {\n console.log(`[MoltsPay] Server listening on http://${this.options.host}:${p}`);\n console.log(`[MoltsPay] Endpoints:`);\n console.log(` GET /services - List available services`);\n console.log(` POST /pay - Create payment & execute service`);\n console.log(` POST /verify - Verify payment & get result`);\n console.log(` GET /status/:id - Check charge status`);\n });\n }\n\n private async handleRequest(req: IncomingMessage, res: ServerResponse): Promise<void> {\n const url = new URL(req.url || '/', `http://${req.headers.host}`);\n const path = url.pathname;\n const method = req.method || 'GET';\n\n // CORS headers\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');\n\n if (method === 'OPTIONS') {\n res.writeHead(204);\n res.end();\n return;\n }\n\n try {\n if (method === 'GET' && path === '/services') {\n return this.handleGetServices(res);\n }\n\n if (method === 'POST' && path === '/pay') {\n const body = await this.readBody(req);\n return this.handlePay(body, res);\n }\n\n if (method === 'POST' && path === '/verify') {\n const body = await this.readBody(req);\n return this.handleVerify(body, res);\n }\n\n if (method === 'GET' && path.startsWith('/status/')) {\n const chargeId = path.replace('/status/', '');\n return this.handleStatus(chargeId, 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 /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 input: s.input,\n output: s.output,\n available: this.skills.has(s.id),\n }));\n\n this.sendJson(res, 200, {\n provider: this.manifest.provider,\n services,\n });\n }\n\n /**\n * POST /pay - Create payment request\n * Body: { service: string, params: object }\n */\n private handlePay(body: any, res: ServerResponse): 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 // Create charge\n const chargeId = generateChargeId();\n const now = Date.now();\n const charge: Charge = {\n id: chargeId,\n service,\n params: params || {},\n amount: skill.config.price,\n currency: skill.config.currency,\n status: 'pending',\n createdAt: now,\n expiresAt: now + (this.options.chargeExpirySecs! * 1000),\n };\n\n this.charges.set(chargeId, charge);\n\n // Return payment request\n const paymentRequest: PaymentRequest = {\n chargeId,\n service,\n amount: charge.amount,\n currency: charge.currency,\n wallet: this.manifest.provider.wallet,\n chain: this.manifest.provider.chain,\n expiresAt: charge.expiresAt,\n };\n\n this.sendJson(res, 402, {\n message: 'Payment required',\n payment: paymentRequest,\n });\n }\n\n /**\n * POST /verify - Verify payment and execute skill\n * Body: { chargeId: string, txHash: string }\n */\n private async handleVerify(body: any, res: ServerResponse): Promise<void> {\n const { chargeId, txHash } = body;\n\n if (!chargeId || !txHash) {\n return this.sendJson(res, 400, { error: 'Missing chargeId or txHash' });\n }\n\n const charge = this.charges.get(chargeId);\n if (!charge) {\n return this.sendJson(res, 404, { error: 'Charge not found' });\n }\n\n // Check expiry\n if (Date.now() > charge.expiresAt) {\n charge.status = 'expired';\n return this.sendJson(res, 400, { error: 'Charge expired' });\n }\n\n // Check if already paid\n if (charge.status === 'completed') {\n return this.sendJson(res, 200, {\n status: 'completed',\n result: charge.result,\n });\n }\n\n try {\n const verification = await verifyPayment({\n txHash,\n expectedTo: this.manifest.provider.wallet,\n expectedAmount: charge.amount,\n chain: this.manifest.provider.chain,\n });\n\n if (!verification.verified) {\n charge.status = 'failed';\n return this.sendJson(res, 400, {\n error: 'Payment verification failed',\n reason: verification.error,\n });\n }\n\n // Payment verified - update charge\n charge.status = 'paid';\n charge.txHash = txHash;\n charge.paidAt = Date.now();\n\n // Execute skill\n const skill = this.skills.get(charge.service)!;\n console.log(`[MoltsPay] Executing skill: ${charge.service}`);\n \n const result = await skill.handler(charge.params);\n \n charge.status = 'completed';\n charge.result = result;\n charge.completedAt = Date.now();\n\n this.sendJson(res, 200, {\n status: 'completed',\n chargeId,\n txHash,\n result,\n });\n } catch (err: any) {\n console.error('[MoltsPay] Skill execution error:', err);\n charge.status = 'failed';\n this.sendJson(res, 500, {\n error: 'Skill execution failed',\n message: err.message,\n });\n }\n }\n\n /**\n * GET /status/:chargeId - Check charge status\n */\n private handleStatus(chargeId: string, res: ServerResponse): void {\n const charge = this.charges.get(chargeId);\n if (!charge) {\n return this.sendJson(res, 404, { error: 'Charge not found' });\n }\n\n this.sendJson(res, 200, {\n chargeId: charge.id,\n service: charge.service,\n amount: charge.amount,\n currency: charge.currency,\n status: charge.status,\n txHash: charge.txHash,\n result: charge.status === 'completed' ? charge.result : undefined,\n createdAt: charge.createdAt,\n expiresAt: charge.expiresAt,\n });\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(res: ServerResponse, status: number, data: any): void {\n res.writeHead(status, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify(data, null, 2));\n }\n}\n","/**\n * On-chain Payment Verification Module\n */\n\nimport { ethers } from 'ethers';\nimport { getChain, getChainById, type ChainConfig, type ChainName } 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}\n\nexport interface VerifyPaymentResult {\n verified: boolean;\n amount?: number;\n from?: string;\n to?: string;\n txHash?: string;\n blockNumber?: number;\n error?: string;\n}\n\n/**\n * Verify on-chain payment\n */\nexport async function verifyPayment(params: VerifyPaymentParams): Promise<VerifyPaymentResult> {\n const { txHash, expectedAmount, expectedTo } = 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 // Parse Transfer event\n const usdcAddress = chain.usdc?.toLowerCase();\n if (!usdcAddress) {\n return { verified: false, error: `Chain ${chain.name} USDC address not configured` };\n }\n\n for (const log of receipt.logs) {\n // Check if USDC contract\n if (log.address.toLowerCase() !== usdcAddress) {\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 amount = Number(amountRaw) / 1e6; // USDC 6 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} USDC, expected ${expectedAmount} USDC`,\n amount,\n from,\n to,\n txHash,\n blockNumber: receipt.blockNumber,\n };\n }\n\n // Verification successful\n return {\n verified: true,\n amount,\n from,\n to,\n txHash,\n blockNumber: receipt.blockNumber,\n };\n }\n\n return { verified: false, error: 'No USDC 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"],"mappings":"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","names":["import_os","import_path","import_fs","ethers","import_fs","import_ethers","resolve","resolve"]}
@@ -913,5 +913,55 @@ program.command("stop").description("Stop the running MoltsPay server").action(a
913
913
  process.exit(1);
914
914
  }
915
915
  });
916
+ program.command("pay <server> <service> [params]").description("Pay for a service and get the result").option("--prompt <text>", "Prompt for the service").option("--image <url>", "Image URL (for image-to-video)").option("--json", "Output raw JSON only").action(async (server, service, paramsJson, options) => {
917
+ const client = new MoltsPayClient();
918
+ if (!client.isInitialized) {
919
+ console.error("\u274C Wallet not initialized. Run: npx moltspay init");
920
+ process.exit(1);
921
+ }
922
+ let params = {};
923
+ if (paramsJson) {
924
+ try {
925
+ params = JSON.parse(paramsJson);
926
+ } catch {
927
+ console.error("\u274C Invalid JSON params");
928
+ process.exit(1);
929
+ }
930
+ }
931
+ if (options.prompt) params.prompt = options.prompt;
932
+ if (options.image) params.image_url = options.image;
933
+ if (!params.prompt) {
934
+ console.error("\u274C Missing prompt. Use --prompt or pass JSON params");
935
+ process.exit(1);
936
+ }
937
+ if (!options.json) {
938
+ console.log(`
939
+ \u{1F4B3} MoltsPay - Paying for service
940
+ `);
941
+ console.log(` Server: ${server}`);
942
+ console.log(` Service: ${service}`);
943
+ console.log(` Prompt: ${params.prompt}`);
944
+ if (params.image_url) console.log(` Image: ${params.image_url}`);
945
+ console.log(` Wallet: ${client.address}`);
946
+ console.log("");
947
+ }
948
+ try {
949
+ const result = await client.pay(server, service, params);
950
+ if (options.json) {
951
+ console.log(JSON.stringify(result));
952
+ } else {
953
+ console.log("\u2705 Success!\n");
954
+ console.log(JSON.stringify(result, null, 2));
955
+ console.log("");
956
+ }
957
+ } catch (err) {
958
+ if (options.json) {
959
+ console.log(JSON.stringify({ error: err.message }));
960
+ } else {
961
+ console.error(`\u274C Error: ${err.message}`);
962
+ }
963
+ process.exit(1);
964
+ }
965
+ });
916
966
  program.parse();
917
967
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/cli/index.ts","../../src/client/index.ts","../../src/chains/index.ts","../../src/server/index.ts","../../src/verify/index.ts"],"sourcesContent":["#!/usr/bin/env node\n\n/**\n * MoltsPay CLI\n * \n * Commands:\n * npx moltspay init - Create wallet, set limits\n * npx moltspay config - Update settings\n * npx moltspay status - Show wallet and balance\n * npx moltspay services <url> - List services from provider\n * npx moltspay start <manifest> - Start server from services.json\n */\n\nimport { Command } from 'commander';\nimport { homedir } from 'os';\nimport { join, dirname, resolve } from 'path';\nimport { existsSync, writeFileSync, readFileSync, unlinkSync, mkdirSync } from 'fs';\nimport { spawn } from 'child_process';\nimport { MoltsPayClient } from '../client/index.js';\nimport { MoltsPayServer } from '../server/index.js';\nimport * as readline from 'readline';\n\nconst program = new Command();\nconst DEFAULT_CONFIG_DIR = join(homedir(), '.moltspay');\nconst PID_FILE = join(DEFAULT_CONFIG_DIR, 'server.pid');\n\n// Ensure config dir exists\nif (!existsSync(DEFAULT_CONFIG_DIR)) {\n mkdirSync(DEFAULT_CONFIG_DIR, { recursive: true });\n}\n\nfunction prompt(question: string): Promise<string> {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n return new Promise(resolve => {\n rl.question(question, answer => {\n rl.close();\n resolve(answer.trim());\n });\n });\n}\n\nprogram\n .name('moltspay')\n .description('MoltsPay - Payment infrastructure for AI Agents')\n .version('1.0.0');\n\n/**\n * npx moltspay init\n */\nprogram\n .command('init')\n .description('Initialize MoltsPay client (create wallet, set limits)')\n .option('--chain <chain>', 'Blockchain to use', 'base')\n .option('--max-per-tx <amount>', 'Max amount per transaction')\n .option('--max-per-day <amount>', 'Max amount per day')\n .option('--config-dir <dir>', 'Config directory', DEFAULT_CONFIG_DIR)\n .action(async (options) => {\n console.log('\\nšŸ” MoltsPay Client Setup\\n');\n\n // Check if already initialized\n if (existsSync(join(options.configDir, 'wallet.json'))) {\n console.log('āš ļø Already initialized. Use \"moltspay config\" to update settings.');\n console.log(` Config dir: ${options.configDir}`);\n return;\n }\n\n // Get options interactively if not provided\n let chain = options.chain;\n let maxPerTx = options.maxPerTx ? parseFloat(options.maxPerTx) : null;\n let maxPerDay = options.maxPerDay ? parseFloat(options.maxPerDay) : null;\n\n if (!maxPerTx) {\n const answer = await prompt('Max per transaction (USD) [100]: ');\n maxPerTx = answer ? parseFloat(answer) : 100;\n }\n\n if (!maxPerDay) {\n const answer = await prompt('Max per day (USD) [1000]: ');\n maxPerDay = answer ? parseFloat(answer) : 1000;\n }\n\n console.log('\\nCreating wallet...');\n\n const result = MoltsPayClient.init(options.configDir, {\n chain,\n maxPerTx,\n maxPerDay,\n });\n\n console.log(`\\nāœ… Wallet created: ${result.address}`);\n console.log(`\\nšŸ“ Config saved to: ${result.configDir}`);\n console.log(`\\nāš ļø IMPORTANT: Back up ${join(result.configDir, 'wallet.json')}`);\n console.log(` This file contains your private key!\\n`);\n console.log(`šŸ’° Fund your wallet with USDC on ${chain} to start using services.\\n`);\n });\n\n/**\n * npx moltspay config\n */\nprogram\n .command('config')\n .description('Update MoltsPay settings')\n .option('--max-per-tx <amount>', 'Max amount per transaction')\n .option('--max-per-day <amount>', 'Max amount per day')\n .option('--config-dir <dir>', 'Config directory', DEFAULT_CONFIG_DIR)\n .action(async (options) => {\n const client = new MoltsPayClient({ configDir: options.configDir });\n\n if (!client.isInitialized) {\n console.log('āŒ Not initialized. Run: npx moltspay init');\n return;\n }\n\n const currentConfig = client.getConfig();\n\n // If no options provided, show interactive mode\n if (!options.maxPerTx && !options.maxPerDay) {\n console.log('\\nšŸ“‹ Current Settings:\\n');\n console.log(` Wallet: ${client.address}`);\n console.log(` Chain: ${currentConfig.chain}`);\n console.log(` Max per tx: $${currentConfig.limits.maxPerTx}`);\n console.log(` Max per day: $${currentConfig.limits.maxPerDay}`);\n console.log('');\n\n const maxPerTxAnswer = await prompt(`New max per tx (USD) [${currentConfig.limits.maxPerTx}]: `);\n const maxPerDayAnswer = await prompt(`New max per day (USD) [${currentConfig.limits.maxPerDay}]: `);\n\n if (maxPerTxAnswer) {\n client.updateConfig({ maxPerTx: parseFloat(maxPerTxAnswer) });\n console.log(`āœ… Updated max per tx to $${maxPerTxAnswer}`);\n }\n\n if (maxPerDayAnswer) {\n client.updateConfig({ maxPerDay: parseFloat(maxPerDayAnswer) });\n console.log(`āœ… Updated max per day to $${maxPerDayAnswer}`);\n }\n } else {\n // Non-interactive mode\n if (options.maxPerTx) {\n client.updateConfig({ maxPerTx: parseFloat(options.maxPerTx) });\n console.log(`āœ… Updated max per tx to $${options.maxPerTx}`);\n }\n if (options.maxPerDay) {\n client.updateConfig({ maxPerDay: parseFloat(options.maxPerDay) });\n console.log(`āœ… Updated max per day to $${options.maxPerDay}`);\n }\n }\n });\n\n/**\n * npx moltspay status\n */\nprogram\n .command('status')\n .description('Show wallet status and balance')\n .option('--config-dir <dir>', 'Config directory', DEFAULT_CONFIG_DIR)\n .option('--json', 'Output as JSON')\n .action(async (options) => {\n const client = new MoltsPayClient({ configDir: options.configDir });\n\n if (!client.isInitialized) {\n if (options.json) {\n console.log(JSON.stringify({ error: 'Not initialized' }));\n } else {\n console.log('āŒ Not initialized. Run: npx moltspay init');\n }\n return;\n }\n\n const config = client.getConfig();\n \n let balance = { usdc: 0, native: 0 };\n try {\n balance = await client.getBalance();\n } catch (err: any) {\n console.error('Warning: Could not fetch balance:', err.message);\n }\n\n if (options.json) {\n console.log(JSON.stringify({\n address: client.address,\n chain: config.chain,\n balance,\n limits: config.limits,\n }, null, 2));\n } else {\n console.log('\\nšŸ“Š MoltsPay Status\\n');\n console.log(` Wallet: ${client.address}`);\n console.log(` Chain: ${config.chain}`);\n console.log(` Balance: ${balance.usdc.toFixed(2)} USDC`);\n console.log(` Native: ${balance.native.toFixed(6)} ETH`);\n console.log('');\n console.log(' Limits:');\n console.log(` Max per tx: $${config.limits.maxPerTx}`);\n console.log(` Max per day: $${config.limits.maxPerDay}`);\n console.log('');\n }\n });\n\n/**\n * npx moltspay services <url>\n */\nprogram\n .command('services <url>')\n .description('List services from a provider')\n .option('--json', 'Output as JSON')\n .action(async (url, options) => {\n try {\n const client = new MoltsPayClient();\n const services = await client.getServices(url);\n\n if (options.json) {\n console.log(JSON.stringify(services, null, 2));\n } else {\n console.log(`\\nšŸŖ ${services.provider.name}\\n`);\n console.log(` ${services.provider.description || ''}`);\n console.log(` Wallet: ${services.provider.wallet}`);\n console.log(` Chain: ${services.provider.chain}`);\n console.log('\\nšŸ“¦ Services:\\n');\n \n for (const svc of services.services) {\n const status = svc.available ? 'āœ…' : 'āŒ';\n console.log(` ${status} ${svc.id}`);\n console.log(` ${svc.name} - $${svc.price} ${svc.currency}`);\n if (svc.description) {\n console.log(` ${svc.description}`);\n }\n console.log('');\n }\n }\n } catch (err: any) {\n console.error('āŒ Error:', err.message);\n }\n });\n\n/**\n * npx moltspay start <manifest>\n * \n * Start server from moltspay.services.json\n * Services with \"command\" field are auto-registered as skills.\n */\nprogram\n .command('start <manifest>')\n .description('Start MoltsPay server from services manifest')\n .option('-p, --port <port>', 'Port to listen on', '3000')\n .option('--host <host>', 'Host to bind', '0.0.0.0')\n .action(async (manifest, options) => {\n const manifestPath = resolve(manifest);\n \n if (!existsSync(manifestPath)) {\n console.error(`āŒ Manifest not found: ${manifestPath}`);\n process.exit(1);\n }\n\n const port = parseInt(options.port, 10);\n const host = options.host;\n\n console.log(`\\nšŸš€ Starting MoltsPay Server\\n`);\n console.log(` Manifest: ${manifestPath}`);\n console.log(` Port: ${port}`);\n console.log('');\n\n try {\n const server = new MoltsPayServer(manifestPath, { port, host });\n\n // Get manifest to check for command-based skills\n const manifestContent = await import('fs').then(fs => \n JSON.parse(fs.readFileSync(manifestPath, 'utf-8'))\n );\n\n // Auto-register skills that have a \"command\" field\n for (const service of manifestContent.services) {\n if (service.command) {\n const workdir = dirname(manifestPath);\n \n server.skill(service.id, async (params) => {\n return new Promise((resolve, reject) => {\n const proc = spawn('sh', ['-c', service.command], {\n cwd: workdir,\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n\n let stdout = '';\n let stderr = '';\n\n proc.stdout.on('data', (data) => {\n stdout += data.toString();\n });\n\n proc.stderr.on('data', (data) => {\n stderr += data.toString();\n // Log stderr in real-time for debugging\n process.stderr.write(data);\n });\n\n // Send params as JSON to stdin\n proc.stdin.write(JSON.stringify(params));\n proc.stdin.end();\n\n proc.on('close', (code) => {\n if (code !== 0) {\n reject(new Error(`Command failed (exit ${code}): ${stderr || 'Unknown error'}`));\n return;\n }\n\n // Try to parse output as JSON\n try {\n const result = JSON.parse(stdout.trim());\n resolve(result);\n } catch {\n // If not JSON, return as raw output\n resolve({ output: stdout.trim() });\n }\n });\n\n proc.on('error', (err) => {\n reject(new Error(`Failed to spawn command: ${err.message}`));\n });\n });\n });\n }\n }\n\n // Write PID file\n const pidData = { pid: process.pid, port, manifest: manifestPath };\n writeFileSync(PID_FILE, JSON.stringify(pidData, null, 2));\n console.log(` PID file: ${PID_FILE}`);\n console.log('');\n\n // Start listening\n server.listen(port);\n\n // Cleanup function\n const cleanup = () => {\n try {\n if (existsSync(PID_FILE)) {\n unlinkSync(PID_FILE);\n }\n } catch {}\n };\n\n // Handle graceful shutdown\n process.on('SIGINT', () => {\n console.log('\\n\\nšŸ‘‹ Shutting down...');\n cleanup();\n process.exit(0);\n });\n\n process.on('SIGTERM', () => {\n console.log('\\n\\nšŸ‘‹ Shutting down...');\n cleanup();\n process.exit(0);\n });\n\n process.on('exit', cleanup);\n\n } catch (err: any) {\n console.error(`āŒ Failed to start server: ${err.message}`);\n process.exit(1);\n }\n });\n\n/**\n * npx moltspay stop\n * \n * Stop the running MoltsPay server gracefully\n */\nprogram\n .command('stop')\n .description('Stop the running MoltsPay server')\n .action(async () => {\n if (!existsSync(PID_FILE)) {\n console.log('āŒ No running server found (no PID file)');\n process.exit(1);\n }\n\n try {\n const pidData = JSON.parse(readFileSync(PID_FILE, 'utf-8'));\n const { pid, port, manifest } = pidData;\n\n console.log(`\\nšŸ›‘ Stopping MoltsPay Server\\n`);\n console.log(` PID: ${pid}`);\n console.log(` Port: ${port}`);\n console.log(` Manifest: ${manifest}`);\n console.log('');\n\n // Check if process is running\n try {\n process.kill(pid, 0); // Test if process exists\n } catch {\n console.log('āš ļø Process not running, cleaning up PID file...');\n unlinkSync(PID_FILE);\n process.exit(0);\n }\n\n // Send SIGTERM for graceful shutdown\n process.kill(pid, 'SIGTERM');\n console.log('āœ… Sent SIGTERM to server');\n\n // Wait a bit and check if it stopped\n await new Promise(resolve => setTimeout(resolve, 1000));\n\n try {\n process.kill(pid, 0);\n console.log('āš ļø Server still running, sending SIGKILL...');\n process.kill(pid, 'SIGKILL');\n } catch {\n // Process is gone, good\n }\n\n // Clean up PID file if still exists\n if (existsSync(PID_FILE)) {\n unlinkSync(PID_FILE);\n }\n\n console.log('āœ… Server stopped\\n');\n\n } catch (err: any) {\n console.error(`āŒ Failed to stop server: ${err.message}`);\n process.exit(1);\n }\n });\n\nprogram.parse();\n","/**\n * MoltsPay Client - Pay for AI Agent services\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 } from 'fs';\nimport { homedir } from 'os';\nimport { join } from 'path';\nimport { Wallet } from 'ethers';\nimport { getChain, type ChainName } from '../chains/index.js';\nimport {\n ClientConfig,\n WalletData,\n PaymentRequired,\n ServicesResponse,\n VerifyResponse,\n MoltsPayClientOptions,\n} from './types.js';\n\nexport * from './types.js';\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 \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 const res = await fetch(`${serverUrl}/services`);\n if (!res.ok) {\n throw new Error(`Failed to get services: ${res.statusText}`);\n }\n return res.json() as Promise<ServicesResponse>;\n }\n\n /**\n * Pay for a service and get the result\n */\n async pay(\n serverUrl: string,\n service: string,\n params: Record<string, any>\n ): Promise<Record<string, any>> {\n if (!this.wallet) {\n throw new Error('Client not initialized. Run: npx moltspay init');\n }\n\n // Step 1: Request payment info\n const payRes = await fetch(`${serverUrl}/pay`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ service, params }),\n });\n\n if (payRes.status !== 402) {\n const err = await payRes.json() as { error?: string };\n throw new Error(err.error || 'Unexpected response');\n }\n\n const paymentReq = await payRes.json() as PaymentRequired;\n const { payment } = paymentReq;\n\n // Step 2: Check limits\n this.checkLimits(payment.amount);\n\n // Step 3: Execute payment on-chain\n console.log(`[MoltsPay] Paying $${payment.amount} ${payment.currency} to ${payment.wallet}`);\n const txHash = await this.executePayment(payment);\n console.log(`[MoltsPay] Payment tx: ${txHash}`);\n\n // Step 4: Verify and get result\n const verifyRes = await fetch(`${serverUrl}/verify`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n chargeId: payment.chargeId,\n txHash,\n }),\n });\n\n if (!verifyRes.ok) {\n const err = await verifyRes.json() as { error?: string };\n throw new Error(err.error || 'Verification failed');\n }\n\n const result = await verifyRes.json() as VerifyResponse;\n \n // Update spending tracking\n this.recordSpending(payment.amount);\n \n return result.result;\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 }\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\n */\n private recordSpending(amount: number): void {\n this.todaySpending += amount;\n }\n\n /**\n * Execute payment on-chain\n */\n private async executePayment(payment: PaymentRequired['payment']): Promise<string> {\n let chain;\n try {\n chain = getChain(payment.chain as ChainName);\n } catch {\n throw new Error(`Unknown chain: ${payment.chain}`);\n }\n\n // For now, we'll use a simple USDC transfer\n // In production, this would connect to the actual chain\n const { ethers } = await import('ethers');\n \n const provider = new ethers.JsonRpcProvider(chain.rpc);\n const signer = new ethers.Wallet(this.walletData!.privateKey, provider);\n\n // USDC contract (Base mainnet)\n const usdcAddress = chain.usdc;\n const usdcAbi = [\n 'function transfer(address to, uint256 amount) returns (bool)',\n 'function balanceOf(address account) view returns (uint256)',\n ];\n \n const usdc = new ethers.Contract(usdcAddress, usdcAbi, signer);\n\n // Convert amount to USDC decimals (6)\n const amountInUnits = ethers.parseUnits(payment.amount.toString(), 6);\n\n // Check balance\n const balance = await usdc.balanceOf(this.wallet!.address);\n if (balance < amountInUnits) {\n throw new Error(\n `Insufficient USDC balance: ${ethers.formatUnits(balance, 6)} < ${payment.amount}`\n );\n }\n\n // Send transaction\n const tx = await usdc.transfer(payment.wallet, amountInUnits);\n const receipt = await tx.wait();\n\n return receipt.hash;\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 private loadWallet(): WalletData | null {\n const walletPath = join(this.configDir, 'wallet.json');\n if (existsSync(walletPath)) {\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\n const walletPath = join(configDir, 'wallet.json');\n writeFileSync(walletPath, JSON.stringify(walletData, null, 2));\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\n */\n async getBalance(): Promise<{ usdc: 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 { ethers } = await import('ethers');\n const provider = new ethers.JsonRpcProvider(chain.rpc);\n\n // Get native balance\n const nativeBalance = await provider.getBalance(this.wallet.address);\n\n // Get USDC balance\n const usdcAbi = ['function balanceOf(address) view returns (uint256)'];\n const usdc = new ethers.Contract(chain.usdc, usdcAbi, provider);\n const usdcBalance = await usdc.balanceOf(this.wallet.address);\n\n return {\n usdc: parseFloat(ethers.formatUnits(usdcBalance, 6)),\n native: parseFloat(ethers.formatEther(nativeBalance)),\n };\n }\n}\n","/**\n * Blockchain Configuration\n */\n\nimport type { ChainConfig, ChainName } 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 usdc: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\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-rpc.com',\n usdc: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',\n explorer: 'https://polygonscan.com/address/',\n explorerTx: 'https://polygonscan.com/tx/',\n avgBlockTime: 2,\n },\n ethereum: {\n name: 'Ethereum',\n chainId: 1,\n rpc: 'https://eth.llamarpc.com',\n usdc: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',\n explorer: 'https://etherscan.io/address/',\n explorerTx: 'https://etherscan.io/tx/',\n avgBlockTime: 12,\n },\n\n // ============ Testnet ============\n base_sepolia: {\n name: 'Base Sepolia',\n chainId: 84532,\n rpc: 'https://sepolia.base.org',\n usdc: '0x036CbD53842c5426634e7929541eC2318f3dCF7e',\n explorer: 'https://sepolia.basescan.org/address/',\n explorerTx: 'https://sepolia.basescan.org/tx/',\n avgBlockTime: 2,\n },\n sepolia: {\n name: 'Sepolia',\n chainId: 11155111,\n rpc: 'https://rpc.sepolia.org',\n usdc: '0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238',\n explorer: 'https://sepolia.etherscan.io/address/',\n explorerTx: 'https://sepolia.etherscan.io/tx/',\n avgBlockTime: 12,\n },\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 };\n","/**\n * MoltsPay Server - Payment infrastructure for AI Agents\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 } from 'fs';\nimport { createServer, IncomingMessage, ServerResponse } from 'http';\nimport { verifyPayment } from '../verify/index.js';\nimport {\n ServicesManifest,\n ServiceConfig,\n SkillFunction,\n RegisteredSkill,\n Charge,\n ChargeStatus,\n PaymentRequest,\n MoltsPayServerOptions,\n} from './types.js';\n\nexport * from './types.js';\n\nfunction generateChargeId(): string {\n return 'ch_' + Math.random().toString(36).substring(2, 15);\n}\n\nexport class MoltsPayServer {\n private manifest: ServicesManifest;\n private skills: Map<string, RegisteredSkill> = new Map();\n private charges: Map<string, Charge> = new Map();\n private options: MoltsPayServerOptions;\n\n constructor(servicesPath: string, options: MoltsPayServerOptions = {}) {\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 chargeExpirySecs: options.chargeExpirySecs || 300, // 5 minutes\n };\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] Wallet: ${this.manifest.provider.wallet}`);\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\n this.skills.set(serviceId, {\n id: serviceId,\n config,\n handler,\n });\n\n console.log(`[MoltsPay] Registered skill: ${serviceId} ($${config.price} ${config.currency})`);\n return this;\n }\n\n /**\n * Start the server\n */\n listen(port?: number): void {\n const p = port || this.options.port!;\n \n const server = createServer((req, res) => this.handleRequest(req, res));\n \n server.listen(p, this.options.host, () => {\n console.log(`[MoltsPay] Server listening on http://${this.options.host}:${p}`);\n console.log(`[MoltsPay] Endpoints:`);\n console.log(` GET /services - List available services`);\n console.log(` POST /pay - Create payment & execute service`);\n console.log(` POST /verify - Verify payment & get result`);\n console.log(` GET /status/:id - Check charge status`);\n });\n }\n\n private async handleRequest(req: IncomingMessage, res: ServerResponse): Promise<void> {\n const url = new URL(req.url || '/', `http://${req.headers.host}`);\n const path = url.pathname;\n const method = req.method || 'GET';\n\n // CORS headers\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');\n\n if (method === 'OPTIONS') {\n res.writeHead(204);\n res.end();\n return;\n }\n\n try {\n if (method === 'GET' && path === '/services') {\n return this.handleGetServices(res);\n }\n\n if (method === 'POST' && path === '/pay') {\n const body = await this.readBody(req);\n return this.handlePay(body, res);\n }\n\n if (method === 'POST' && path === '/verify') {\n const body = await this.readBody(req);\n return this.handleVerify(body, res);\n }\n\n if (method === 'GET' && path.startsWith('/status/')) {\n const chargeId = path.replace('/status/', '');\n return this.handleStatus(chargeId, 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 /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 input: s.input,\n output: s.output,\n available: this.skills.has(s.id),\n }));\n\n this.sendJson(res, 200, {\n provider: this.manifest.provider,\n services,\n });\n }\n\n /**\n * POST /pay - Create payment request\n * Body: { service: string, params: object }\n */\n private handlePay(body: any, res: ServerResponse): 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 // Create charge\n const chargeId = generateChargeId();\n const now = Date.now();\n const charge: Charge = {\n id: chargeId,\n service,\n params: params || {},\n amount: skill.config.price,\n currency: skill.config.currency,\n status: 'pending',\n createdAt: now,\n expiresAt: now + (this.options.chargeExpirySecs! * 1000),\n };\n\n this.charges.set(chargeId, charge);\n\n // Return payment request\n const paymentRequest: PaymentRequest = {\n chargeId,\n service,\n amount: charge.amount,\n currency: charge.currency,\n wallet: this.manifest.provider.wallet,\n chain: this.manifest.provider.chain,\n expiresAt: charge.expiresAt,\n };\n\n this.sendJson(res, 402, {\n message: 'Payment required',\n payment: paymentRequest,\n });\n }\n\n /**\n * POST /verify - Verify payment and execute skill\n * Body: { chargeId: string, txHash: string }\n */\n private async handleVerify(body: any, res: ServerResponse): Promise<void> {\n const { chargeId, txHash } = body;\n\n if (!chargeId || !txHash) {\n return this.sendJson(res, 400, { error: 'Missing chargeId or txHash' });\n }\n\n const charge = this.charges.get(chargeId);\n if (!charge) {\n return this.sendJson(res, 404, { error: 'Charge not found' });\n }\n\n // Check expiry\n if (Date.now() > charge.expiresAt) {\n charge.status = 'expired';\n return this.sendJson(res, 400, { error: 'Charge expired' });\n }\n\n // Check if already paid\n if (charge.status === 'completed') {\n return this.sendJson(res, 200, {\n status: 'completed',\n result: charge.result,\n });\n }\n\n try {\n const verification = await verifyPayment({\n txHash,\n expectedTo: this.manifest.provider.wallet,\n expectedAmount: charge.amount,\n chain: this.manifest.provider.chain,\n });\n\n if (!verification.verified) {\n charge.status = 'failed';\n return this.sendJson(res, 400, {\n error: 'Payment verification failed',\n reason: verification.error,\n });\n }\n\n // Payment verified - update charge\n charge.status = 'paid';\n charge.txHash = txHash;\n charge.paidAt = Date.now();\n\n // Execute skill\n const skill = this.skills.get(charge.service)!;\n console.log(`[MoltsPay] Executing skill: ${charge.service}`);\n \n const result = await skill.handler(charge.params);\n \n charge.status = 'completed';\n charge.result = result;\n charge.completedAt = Date.now();\n\n this.sendJson(res, 200, {\n status: 'completed',\n chargeId,\n txHash,\n result,\n });\n } catch (err: any) {\n console.error('[MoltsPay] Skill execution error:', err);\n charge.status = 'failed';\n this.sendJson(res, 500, {\n error: 'Skill execution failed',\n message: err.message,\n });\n }\n }\n\n /**\n * GET /status/:chargeId - Check charge status\n */\n private handleStatus(chargeId: string, res: ServerResponse): void {\n const charge = this.charges.get(chargeId);\n if (!charge) {\n return this.sendJson(res, 404, { error: 'Charge not found' });\n }\n\n this.sendJson(res, 200, {\n chargeId: charge.id,\n service: charge.service,\n amount: charge.amount,\n currency: charge.currency,\n status: charge.status,\n txHash: charge.txHash,\n result: charge.status === 'completed' ? charge.result : undefined,\n createdAt: charge.createdAt,\n expiresAt: charge.expiresAt,\n });\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(res: ServerResponse, status: number, data: any): void {\n res.writeHead(status, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify(data, null, 2));\n }\n}\n","/**\n * On-chain Payment Verification Module\n */\n\nimport { ethers } from 'ethers';\nimport { getChain, getChainById, type ChainConfig, type ChainName } 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}\n\nexport interface VerifyPaymentResult {\n verified: boolean;\n amount?: number;\n from?: string;\n to?: string;\n txHash?: string;\n blockNumber?: number;\n error?: string;\n}\n\n/**\n * Verify on-chain payment\n */\nexport async function verifyPayment(params: VerifyPaymentParams): Promise<VerifyPaymentResult> {\n const { txHash, expectedAmount, expectedTo } = 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 // Parse Transfer event\n const usdcAddress = chain.usdc?.toLowerCase();\n if (!usdcAddress) {\n return { verified: false, error: `Chain ${chain.name} USDC address not configured` };\n }\n\n for (const log of receipt.logs) {\n // Check if USDC contract\n if (log.address.toLowerCase() !== usdcAddress) {\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 amount = Number(amountRaw) / 1e6; // USDC 6 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} USDC, expected ${expectedAmount} USDC`,\n amount,\n from,\n to,\n txHash,\n blockNumber: receipt.blockNumber,\n };\n }\n\n // Verification successful\n return {\n verified: true,\n amount,\n from,\n to,\n txHash,\n blockNumber: receipt.blockNumber,\n };\n }\n\n return { verified: false, error: 'No USDC 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"],"mappings":"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","names":["homedir","join","existsSync","writeFileSync","readFileSync","mkdirSync","ethers","readFileSync","readFileSync","resolve","join","homedir","existsSync","mkdirSync","resolve","writeFileSync","readFileSync"]}
1
+ {"version":3,"sources":["../../src/cli/index.ts","../../src/client/index.ts","../../src/chains/index.ts","../../src/server/index.ts","../../src/verify/index.ts"],"sourcesContent":["#!/usr/bin/env node\n\n/**\n * MoltsPay CLI\n * \n * Commands:\n * npx moltspay init - Create wallet, set limits\n * npx moltspay config - Update settings\n * npx moltspay status - Show wallet and balance\n * npx moltspay services <url> - List services from provider\n * npx moltspay start <manifest> - Start server from services.json\n */\n\nimport { Command } from 'commander';\nimport { homedir } from 'os';\nimport { join, dirname, resolve } from 'path';\nimport { existsSync, writeFileSync, readFileSync, unlinkSync, mkdirSync } from 'fs';\nimport { spawn } from 'child_process';\nimport { MoltsPayClient } from '../client/index.js';\nimport { MoltsPayServer } from '../server/index.js';\nimport * as readline from 'readline';\n\nconst program = new Command();\nconst DEFAULT_CONFIG_DIR = join(homedir(), '.moltspay');\nconst PID_FILE = join(DEFAULT_CONFIG_DIR, 'server.pid');\n\n// Ensure config dir exists\nif (!existsSync(DEFAULT_CONFIG_DIR)) {\n mkdirSync(DEFAULT_CONFIG_DIR, { recursive: true });\n}\n\nfunction prompt(question: string): Promise<string> {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n return new Promise(resolve => {\n rl.question(question, answer => {\n rl.close();\n resolve(answer.trim());\n });\n });\n}\n\nprogram\n .name('moltspay')\n .description('MoltsPay - Payment infrastructure for AI Agents')\n .version('1.0.0');\n\n/**\n * npx moltspay init\n */\nprogram\n .command('init')\n .description('Initialize MoltsPay client (create wallet, set limits)')\n .option('--chain <chain>', 'Blockchain to use', 'base')\n .option('--max-per-tx <amount>', 'Max amount per transaction')\n .option('--max-per-day <amount>', 'Max amount per day')\n .option('--config-dir <dir>', 'Config directory', DEFAULT_CONFIG_DIR)\n .action(async (options) => {\n console.log('\\nšŸ” MoltsPay Client Setup\\n');\n\n // Check if already initialized\n if (existsSync(join(options.configDir, 'wallet.json'))) {\n console.log('āš ļø Already initialized. Use \"moltspay config\" to update settings.');\n console.log(` Config dir: ${options.configDir}`);\n return;\n }\n\n // Get options interactively if not provided\n let chain = options.chain;\n let maxPerTx = options.maxPerTx ? parseFloat(options.maxPerTx) : null;\n let maxPerDay = options.maxPerDay ? parseFloat(options.maxPerDay) : null;\n\n if (!maxPerTx) {\n const answer = await prompt('Max per transaction (USD) [100]: ');\n maxPerTx = answer ? parseFloat(answer) : 100;\n }\n\n if (!maxPerDay) {\n const answer = await prompt('Max per day (USD) [1000]: ');\n maxPerDay = answer ? parseFloat(answer) : 1000;\n }\n\n console.log('\\nCreating wallet...');\n\n const result = MoltsPayClient.init(options.configDir, {\n chain,\n maxPerTx,\n maxPerDay,\n });\n\n console.log(`\\nāœ… Wallet created: ${result.address}`);\n console.log(`\\nšŸ“ Config saved to: ${result.configDir}`);\n console.log(`\\nāš ļø IMPORTANT: Back up ${join(result.configDir, 'wallet.json')}`);\n console.log(` This file contains your private key!\\n`);\n console.log(`šŸ’° Fund your wallet with USDC on ${chain} to start using services.\\n`);\n });\n\n/**\n * npx moltspay config\n */\nprogram\n .command('config')\n .description('Update MoltsPay settings')\n .option('--max-per-tx <amount>', 'Max amount per transaction')\n .option('--max-per-day <amount>', 'Max amount per day')\n .option('--config-dir <dir>', 'Config directory', DEFAULT_CONFIG_DIR)\n .action(async (options) => {\n const client = new MoltsPayClient({ configDir: options.configDir });\n\n if (!client.isInitialized) {\n console.log('āŒ Not initialized. Run: npx moltspay init');\n return;\n }\n\n const currentConfig = client.getConfig();\n\n // If no options provided, show interactive mode\n if (!options.maxPerTx && !options.maxPerDay) {\n console.log('\\nšŸ“‹ Current Settings:\\n');\n console.log(` Wallet: ${client.address}`);\n console.log(` Chain: ${currentConfig.chain}`);\n console.log(` Max per tx: $${currentConfig.limits.maxPerTx}`);\n console.log(` Max per day: $${currentConfig.limits.maxPerDay}`);\n console.log('');\n\n const maxPerTxAnswer = await prompt(`New max per tx (USD) [${currentConfig.limits.maxPerTx}]: `);\n const maxPerDayAnswer = await prompt(`New max per day (USD) [${currentConfig.limits.maxPerDay}]: `);\n\n if (maxPerTxAnswer) {\n client.updateConfig({ maxPerTx: parseFloat(maxPerTxAnswer) });\n console.log(`āœ… Updated max per tx to $${maxPerTxAnswer}`);\n }\n\n if (maxPerDayAnswer) {\n client.updateConfig({ maxPerDay: parseFloat(maxPerDayAnswer) });\n console.log(`āœ… Updated max per day to $${maxPerDayAnswer}`);\n }\n } else {\n // Non-interactive mode\n if (options.maxPerTx) {\n client.updateConfig({ maxPerTx: parseFloat(options.maxPerTx) });\n console.log(`āœ… Updated max per tx to $${options.maxPerTx}`);\n }\n if (options.maxPerDay) {\n client.updateConfig({ maxPerDay: parseFloat(options.maxPerDay) });\n console.log(`āœ… Updated max per day to $${options.maxPerDay}`);\n }\n }\n });\n\n/**\n * npx moltspay status\n */\nprogram\n .command('status')\n .description('Show wallet status and balance')\n .option('--config-dir <dir>', 'Config directory', DEFAULT_CONFIG_DIR)\n .option('--json', 'Output as JSON')\n .action(async (options) => {\n const client = new MoltsPayClient({ configDir: options.configDir });\n\n if (!client.isInitialized) {\n if (options.json) {\n console.log(JSON.stringify({ error: 'Not initialized' }));\n } else {\n console.log('āŒ Not initialized. Run: npx moltspay init');\n }\n return;\n }\n\n const config = client.getConfig();\n \n let balance = { usdc: 0, native: 0 };\n try {\n balance = await client.getBalance();\n } catch (err: any) {\n console.error('Warning: Could not fetch balance:', err.message);\n }\n\n if (options.json) {\n console.log(JSON.stringify({\n address: client.address,\n chain: config.chain,\n balance,\n limits: config.limits,\n }, null, 2));\n } else {\n console.log('\\nšŸ“Š MoltsPay Status\\n');\n console.log(` Wallet: ${client.address}`);\n console.log(` Chain: ${config.chain}`);\n console.log(` Balance: ${balance.usdc.toFixed(2)} USDC`);\n console.log(` Native: ${balance.native.toFixed(6)} ETH`);\n console.log('');\n console.log(' Limits:');\n console.log(` Max per tx: $${config.limits.maxPerTx}`);\n console.log(` Max per day: $${config.limits.maxPerDay}`);\n console.log('');\n }\n });\n\n/**\n * npx moltspay services <url>\n */\nprogram\n .command('services <url>')\n .description('List services from a provider')\n .option('--json', 'Output as JSON')\n .action(async (url, options) => {\n try {\n const client = new MoltsPayClient();\n const services = await client.getServices(url);\n\n if (options.json) {\n console.log(JSON.stringify(services, null, 2));\n } else {\n console.log(`\\nšŸŖ ${services.provider.name}\\n`);\n console.log(` ${services.provider.description || ''}`);\n console.log(` Wallet: ${services.provider.wallet}`);\n console.log(` Chain: ${services.provider.chain}`);\n console.log('\\nšŸ“¦ Services:\\n');\n \n for (const svc of services.services) {\n const status = svc.available ? 'āœ…' : 'āŒ';\n console.log(` ${status} ${svc.id}`);\n console.log(` ${svc.name} - $${svc.price} ${svc.currency}`);\n if (svc.description) {\n console.log(` ${svc.description}`);\n }\n console.log('');\n }\n }\n } catch (err: any) {\n console.error('āŒ Error:', err.message);\n }\n });\n\n/**\n * npx moltspay start <manifest>\n * \n * Start server from moltspay.services.json\n * Services with \"command\" field are auto-registered as skills.\n */\nprogram\n .command('start <manifest>')\n .description('Start MoltsPay server from services manifest')\n .option('-p, --port <port>', 'Port to listen on', '3000')\n .option('--host <host>', 'Host to bind', '0.0.0.0')\n .action(async (manifest, options) => {\n const manifestPath = resolve(manifest);\n \n if (!existsSync(manifestPath)) {\n console.error(`āŒ Manifest not found: ${manifestPath}`);\n process.exit(1);\n }\n\n const port = parseInt(options.port, 10);\n const host = options.host;\n\n console.log(`\\nšŸš€ Starting MoltsPay Server\\n`);\n console.log(` Manifest: ${manifestPath}`);\n console.log(` Port: ${port}`);\n console.log('');\n\n try {\n const server = new MoltsPayServer(manifestPath, { port, host });\n\n // Get manifest to check for command-based skills\n const manifestContent = await import('fs').then(fs => \n JSON.parse(fs.readFileSync(manifestPath, 'utf-8'))\n );\n\n // Auto-register skills that have a \"command\" field\n for (const service of manifestContent.services) {\n if (service.command) {\n const workdir = dirname(manifestPath);\n \n server.skill(service.id, async (params) => {\n return new Promise((resolve, reject) => {\n const proc = spawn('sh', ['-c', service.command], {\n cwd: workdir,\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n\n let stdout = '';\n let stderr = '';\n\n proc.stdout.on('data', (data) => {\n stdout += data.toString();\n });\n\n proc.stderr.on('data', (data) => {\n stderr += data.toString();\n // Log stderr in real-time for debugging\n process.stderr.write(data);\n });\n\n // Send params as JSON to stdin\n proc.stdin.write(JSON.stringify(params));\n proc.stdin.end();\n\n proc.on('close', (code) => {\n if (code !== 0) {\n reject(new Error(`Command failed (exit ${code}): ${stderr || 'Unknown error'}`));\n return;\n }\n\n // Try to parse output as JSON\n try {\n const result = JSON.parse(stdout.trim());\n resolve(result);\n } catch {\n // If not JSON, return as raw output\n resolve({ output: stdout.trim() });\n }\n });\n\n proc.on('error', (err) => {\n reject(new Error(`Failed to spawn command: ${err.message}`));\n });\n });\n });\n }\n }\n\n // Write PID file\n const pidData = { pid: process.pid, port, manifest: manifestPath };\n writeFileSync(PID_FILE, JSON.stringify(pidData, null, 2));\n console.log(` PID file: ${PID_FILE}`);\n console.log('');\n\n // Start listening\n server.listen(port);\n\n // Cleanup function\n const cleanup = () => {\n try {\n if (existsSync(PID_FILE)) {\n unlinkSync(PID_FILE);\n }\n } catch {}\n };\n\n // Handle graceful shutdown\n process.on('SIGINT', () => {\n console.log('\\n\\nšŸ‘‹ Shutting down...');\n cleanup();\n process.exit(0);\n });\n\n process.on('SIGTERM', () => {\n console.log('\\n\\nšŸ‘‹ Shutting down...');\n cleanup();\n process.exit(0);\n });\n\n process.on('exit', cleanup);\n\n } catch (err: any) {\n console.error(`āŒ Failed to start server: ${err.message}`);\n process.exit(1);\n }\n });\n\n/**\n * npx moltspay stop\n * \n * Stop the running MoltsPay server gracefully\n */\nprogram\n .command('stop')\n .description('Stop the running MoltsPay server')\n .action(async () => {\n if (!existsSync(PID_FILE)) {\n console.log('āŒ No running server found (no PID file)');\n process.exit(1);\n }\n\n try {\n const pidData = JSON.parse(readFileSync(PID_FILE, 'utf-8'));\n const { pid, port, manifest } = pidData;\n\n console.log(`\\nšŸ›‘ Stopping MoltsPay Server\\n`);\n console.log(` PID: ${pid}`);\n console.log(` Port: ${port}`);\n console.log(` Manifest: ${manifest}`);\n console.log('');\n\n // Check if process is running\n try {\n process.kill(pid, 0); // Test if process exists\n } catch {\n console.log('āš ļø Process not running, cleaning up PID file...');\n unlinkSync(PID_FILE);\n process.exit(0);\n }\n\n // Send SIGTERM for graceful shutdown\n process.kill(pid, 'SIGTERM');\n console.log('āœ… Sent SIGTERM to server');\n\n // Wait a bit and check if it stopped\n await new Promise(resolve => setTimeout(resolve, 1000));\n\n try {\n process.kill(pid, 0);\n console.log('āš ļø Server still running, sending SIGKILL...');\n process.kill(pid, 'SIGKILL');\n } catch {\n // Process is gone, good\n }\n\n // Clean up PID file if still exists\n if (existsSync(PID_FILE)) {\n unlinkSync(PID_FILE);\n }\n\n console.log('āœ… Server stopped\\n');\n\n } catch (err: any) {\n console.error(`āŒ Failed to stop server: ${err.message}`);\n process.exit(1);\n }\n });\n\n/**\n * npx moltspay pay <server> <service> <params>\n * \n * Pay for a service and get the result\n */\nprogram\n .command('pay <server> <service> [params]')\n .description('Pay for a service and get the result')\n .option('--prompt <text>', 'Prompt for the service')\n .option('--image <url>', 'Image URL (for image-to-video)')\n .option('--json', 'Output raw JSON only')\n .action(async (server, service, paramsJson, options) => {\n const client = new MoltsPayClient();\n\n if (!client.isInitialized) {\n console.error('āŒ Wallet not initialized. Run: npx moltspay init');\n process.exit(1);\n }\n\n // Build params from JSON string or options\n let params: Record<string, any> = {};\n \n if (paramsJson) {\n try {\n params = JSON.parse(paramsJson);\n } catch {\n console.error('āŒ Invalid JSON params');\n process.exit(1);\n }\n }\n \n // Override with CLI options\n if (options.prompt) params.prompt = options.prompt;\n if (options.image) params.image_url = options.image;\n\n if (!params.prompt) {\n console.error('āŒ Missing prompt. Use --prompt or pass JSON params');\n process.exit(1);\n }\n\n if (!options.json) {\n console.log(`\\nšŸ’³ MoltsPay - Paying for service\\n`);\n console.log(` Server: ${server}`);\n console.log(` Service: ${service}`);\n console.log(` Prompt: ${params.prompt}`);\n if (params.image_url) console.log(` Image: ${params.image_url}`);\n console.log(` Wallet: ${client.address}`);\n console.log('');\n }\n\n try {\n const result = await client.pay(server, service, params);\n \n if (options.json) {\n console.log(JSON.stringify(result));\n } else {\n console.log('āœ… Success!\\n');\n console.log(JSON.stringify(result, null, 2));\n console.log('');\n }\n } catch (err: any) {\n if (options.json) {\n console.log(JSON.stringify({ error: err.message }));\n } else {\n console.error(`āŒ Error: ${err.message}`);\n }\n process.exit(1);\n }\n });\n\nprogram.parse();\n","/**\n * MoltsPay Client - Pay for AI Agent services\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 } from 'fs';\nimport { homedir } from 'os';\nimport { join } from 'path';\nimport { Wallet } from 'ethers';\nimport { getChain, type ChainName } from '../chains/index.js';\nimport {\n ClientConfig,\n WalletData,\n PaymentRequired,\n ServicesResponse,\n VerifyResponse,\n MoltsPayClientOptions,\n} from './types.js';\n\nexport * from './types.js';\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 \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 const res = await fetch(`${serverUrl}/services`);\n if (!res.ok) {\n throw new Error(`Failed to get services: ${res.statusText}`);\n }\n return res.json() as Promise<ServicesResponse>;\n }\n\n /**\n * Pay for a service and get the result\n */\n async pay(\n serverUrl: string,\n service: string,\n params: Record<string, any>\n ): Promise<Record<string, any>> {\n if (!this.wallet) {\n throw new Error('Client not initialized. Run: npx moltspay init');\n }\n\n // Step 1: Request payment info\n const payRes = await fetch(`${serverUrl}/pay`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ service, params }),\n });\n\n if (payRes.status !== 402) {\n const err = await payRes.json() as { error?: string };\n throw new Error(err.error || 'Unexpected response');\n }\n\n const paymentReq = await payRes.json() as PaymentRequired;\n const { payment } = paymentReq;\n\n // Step 2: Check limits\n this.checkLimits(payment.amount);\n\n // Step 3: Execute payment on-chain\n console.log(`[MoltsPay] Paying $${payment.amount} ${payment.currency} to ${payment.wallet}`);\n const txHash = await this.executePayment(payment);\n console.log(`[MoltsPay] Payment tx: ${txHash}`);\n\n // Step 4: Verify and get result\n const verifyRes = await fetch(`${serverUrl}/verify`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n chargeId: payment.chargeId,\n txHash,\n }),\n });\n\n if (!verifyRes.ok) {\n const err = await verifyRes.json() as { error?: string };\n throw new Error(err.error || 'Verification failed');\n }\n\n const result = await verifyRes.json() as VerifyResponse;\n \n // Update spending tracking\n this.recordSpending(payment.amount);\n \n return result.result;\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 }\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\n */\n private recordSpending(amount: number): void {\n this.todaySpending += amount;\n }\n\n /**\n * Execute payment on-chain\n */\n private async executePayment(payment: PaymentRequired['payment']): Promise<string> {\n let chain;\n try {\n chain = getChain(payment.chain as ChainName);\n } catch {\n throw new Error(`Unknown chain: ${payment.chain}`);\n }\n\n // For now, we'll use a simple USDC transfer\n // In production, this would connect to the actual chain\n const { ethers } = await import('ethers');\n \n const provider = new ethers.JsonRpcProvider(chain.rpc);\n const signer = new ethers.Wallet(this.walletData!.privateKey, provider);\n\n // USDC contract (Base mainnet)\n const usdcAddress = chain.usdc;\n const usdcAbi = [\n 'function transfer(address to, uint256 amount) returns (bool)',\n 'function balanceOf(address account) view returns (uint256)',\n ];\n \n const usdc = new ethers.Contract(usdcAddress, usdcAbi, signer);\n\n // Convert amount to USDC decimals (6)\n const amountInUnits = ethers.parseUnits(payment.amount.toString(), 6);\n\n // Check balance\n const balance = await usdc.balanceOf(this.wallet!.address);\n if (balance < amountInUnits) {\n throw new Error(\n `Insufficient USDC balance: ${ethers.formatUnits(balance, 6)} < ${payment.amount}`\n );\n }\n\n // Send transaction\n const tx = await usdc.transfer(payment.wallet, amountInUnits);\n const receipt = await tx.wait();\n\n return receipt.hash;\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 private loadWallet(): WalletData | null {\n const walletPath = join(this.configDir, 'wallet.json');\n if (existsSync(walletPath)) {\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\n const walletPath = join(configDir, 'wallet.json');\n writeFileSync(walletPath, JSON.stringify(walletData, null, 2));\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\n */\n async getBalance(): Promise<{ usdc: 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 { ethers } = await import('ethers');\n const provider = new ethers.JsonRpcProvider(chain.rpc);\n\n // Get native balance\n const nativeBalance = await provider.getBalance(this.wallet.address);\n\n // Get USDC balance\n const usdcAbi = ['function balanceOf(address) view returns (uint256)'];\n const usdc = new ethers.Contract(chain.usdc, usdcAbi, provider);\n const usdcBalance = await usdc.balanceOf(this.wallet.address);\n\n return {\n usdc: parseFloat(ethers.formatUnits(usdcBalance, 6)),\n native: parseFloat(ethers.formatEther(nativeBalance)),\n };\n }\n}\n","/**\n * Blockchain Configuration\n */\n\nimport type { ChainConfig, ChainName } 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 usdc: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\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-rpc.com',\n usdc: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',\n explorer: 'https://polygonscan.com/address/',\n explorerTx: 'https://polygonscan.com/tx/',\n avgBlockTime: 2,\n },\n ethereum: {\n name: 'Ethereum',\n chainId: 1,\n rpc: 'https://eth.llamarpc.com',\n usdc: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',\n explorer: 'https://etherscan.io/address/',\n explorerTx: 'https://etherscan.io/tx/',\n avgBlockTime: 12,\n },\n\n // ============ Testnet ============\n base_sepolia: {\n name: 'Base Sepolia',\n chainId: 84532,\n rpc: 'https://sepolia.base.org',\n usdc: '0x036CbD53842c5426634e7929541eC2318f3dCF7e',\n explorer: 'https://sepolia.basescan.org/address/',\n explorerTx: 'https://sepolia.basescan.org/tx/',\n avgBlockTime: 2,\n },\n sepolia: {\n name: 'Sepolia',\n chainId: 11155111,\n rpc: 'https://rpc.sepolia.org',\n usdc: '0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238',\n explorer: 'https://sepolia.etherscan.io/address/',\n explorerTx: 'https://sepolia.etherscan.io/tx/',\n avgBlockTime: 12,\n },\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 };\n","/**\n * MoltsPay Server - Payment infrastructure for AI Agents\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 } from 'fs';\nimport { createServer, IncomingMessage, ServerResponse } from 'http';\nimport { verifyPayment } from '../verify/index.js';\nimport {\n ServicesManifest,\n ServiceConfig,\n SkillFunction,\n RegisteredSkill,\n Charge,\n ChargeStatus,\n PaymentRequest,\n MoltsPayServerOptions,\n} from './types.js';\n\nexport * from './types.js';\n\nfunction generateChargeId(): string {\n return 'ch_' + Math.random().toString(36).substring(2, 15);\n}\n\nexport class MoltsPayServer {\n private manifest: ServicesManifest;\n private skills: Map<string, RegisteredSkill> = new Map();\n private charges: Map<string, Charge> = new Map();\n private options: MoltsPayServerOptions;\n\n constructor(servicesPath: string, options: MoltsPayServerOptions = {}) {\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 chargeExpirySecs: options.chargeExpirySecs || 300, // 5 minutes\n };\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] Wallet: ${this.manifest.provider.wallet}`);\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\n this.skills.set(serviceId, {\n id: serviceId,\n config,\n handler,\n });\n\n console.log(`[MoltsPay] Registered skill: ${serviceId} ($${config.price} ${config.currency})`);\n return this;\n }\n\n /**\n * Start the server\n */\n listen(port?: number): void {\n const p = port || this.options.port!;\n \n const server = createServer((req, res) => this.handleRequest(req, res));\n \n server.listen(p, this.options.host, () => {\n console.log(`[MoltsPay] Server listening on http://${this.options.host}:${p}`);\n console.log(`[MoltsPay] Endpoints:`);\n console.log(` GET /services - List available services`);\n console.log(` POST /pay - Create payment & execute service`);\n console.log(` POST /verify - Verify payment & get result`);\n console.log(` GET /status/:id - Check charge status`);\n });\n }\n\n private async handleRequest(req: IncomingMessage, res: ServerResponse): Promise<void> {\n const url = new URL(req.url || '/', `http://${req.headers.host}`);\n const path = url.pathname;\n const method = req.method || 'GET';\n\n // CORS headers\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');\n\n if (method === 'OPTIONS') {\n res.writeHead(204);\n res.end();\n return;\n }\n\n try {\n if (method === 'GET' && path === '/services') {\n return this.handleGetServices(res);\n }\n\n if (method === 'POST' && path === '/pay') {\n const body = await this.readBody(req);\n return this.handlePay(body, res);\n }\n\n if (method === 'POST' && path === '/verify') {\n const body = await this.readBody(req);\n return this.handleVerify(body, res);\n }\n\n if (method === 'GET' && path.startsWith('/status/')) {\n const chargeId = path.replace('/status/', '');\n return this.handleStatus(chargeId, 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 /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 input: s.input,\n output: s.output,\n available: this.skills.has(s.id),\n }));\n\n this.sendJson(res, 200, {\n provider: this.manifest.provider,\n services,\n });\n }\n\n /**\n * POST /pay - Create payment request\n * Body: { service: string, params: object }\n */\n private handlePay(body: any, res: ServerResponse): 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 // Create charge\n const chargeId = generateChargeId();\n const now = Date.now();\n const charge: Charge = {\n id: chargeId,\n service,\n params: params || {},\n amount: skill.config.price,\n currency: skill.config.currency,\n status: 'pending',\n createdAt: now,\n expiresAt: now + (this.options.chargeExpirySecs! * 1000),\n };\n\n this.charges.set(chargeId, charge);\n\n // Return payment request\n const paymentRequest: PaymentRequest = {\n chargeId,\n service,\n amount: charge.amount,\n currency: charge.currency,\n wallet: this.manifest.provider.wallet,\n chain: this.manifest.provider.chain,\n expiresAt: charge.expiresAt,\n };\n\n this.sendJson(res, 402, {\n message: 'Payment required',\n payment: paymentRequest,\n });\n }\n\n /**\n * POST /verify - Verify payment and execute skill\n * Body: { chargeId: string, txHash: string }\n */\n private async handleVerify(body: any, res: ServerResponse): Promise<void> {\n const { chargeId, txHash } = body;\n\n if (!chargeId || !txHash) {\n return this.sendJson(res, 400, { error: 'Missing chargeId or txHash' });\n }\n\n const charge = this.charges.get(chargeId);\n if (!charge) {\n return this.sendJson(res, 404, { error: 'Charge not found' });\n }\n\n // Check expiry\n if (Date.now() > charge.expiresAt) {\n charge.status = 'expired';\n return this.sendJson(res, 400, { error: 'Charge expired' });\n }\n\n // Check if already paid\n if (charge.status === 'completed') {\n return this.sendJson(res, 200, {\n status: 'completed',\n result: charge.result,\n });\n }\n\n try {\n const verification = await verifyPayment({\n txHash,\n expectedTo: this.manifest.provider.wallet,\n expectedAmount: charge.amount,\n chain: this.manifest.provider.chain,\n });\n\n if (!verification.verified) {\n charge.status = 'failed';\n return this.sendJson(res, 400, {\n error: 'Payment verification failed',\n reason: verification.error,\n });\n }\n\n // Payment verified - update charge\n charge.status = 'paid';\n charge.txHash = txHash;\n charge.paidAt = Date.now();\n\n // Execute skill\n const skill = this.skills.get(charge.service)!;\n console.log(`[MoltsPay] Executing skill: ${charge.service}`);\n \n const result = await skill.handler(charge.params);\n \n charge.status = 'completed';\n charge.result = result;\n charge.completedAt = Date.now();\n\n this.sendJson(res, 200, {\n status: 'completed',\n chargeId,\n txHash,\n result,\n });\n } catch (err: any) {\n console.error('[MoltsPay] Skill execution error:', err);\n charge.status = 'failed';\n this.sendJson(res, 500, {\n error: 'Skill execution failed',\n message: err.message,\n });\n }\n }\n\n /**\n * GET /status/:chargeId - Check charge status\n */\n private handleStatus(chargeId: string, res: ServerResponse): void {\n const charge = this.charges.get(chargeId);\n if (!charge) {\n return this.sendJson(res, 404, { error: 'Charge not found' });\n }\n\n this.sendJson(res, 200, {\n chargeId: charge.id,\n service: charge.service,\n amount: charge.amount,\n currency: charge.currency,\n status: charge.status,\n txHash: charge.txHash,\n result: charge.status === 'completed' ? charge.result : undefined,\n createdAt: charge.createdAt,\n expiresAt: charge.expiresAt,\n });\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(res: ServerResponse, status: number, data: any): void {\n res.writeHead(status, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify(data, null, 2));\n }\n}\n","/**\n * On-chain Payment Verification Module\n */\n\nimport { ethers } from 'ethers';\nimport { getChain, getChainById, type ChainConfig, type ChainName } 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}\n\nexport interface VerifyPaymentResult {\n verified: boolean;\n amount?: number;\n from?: string;\n to?: string;\n txHash?: string;\n blockNumber?: number;\n error?: string;\n}\n\n/**\n * Verify on-chain payment\n */\nexport async function verifyPayment(params: VerifyPaymentParams): Promise<VerifyPaymentResult> {\n const { txHash, expectedAmount, expectedTo } = 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 // Parse Transfer event\n const usdcAddress = chain.usdc?.toLowerCase();\n if (!usdcAddress) {\n return { verified: false, error: `Chain ${chain.name} USDC address not configured` };\n }\n\n for (const log of receipt.logs) {\n // Check if USDC contract\n if (log.address.toLowerCase() !== usdcAddress) {\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 amount = Number(amountRaw) / 1e6; // USDC 6 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} USDC, expected ${expectedAmount} USDC`,\n amount,\n from,\n to,\n txHash,\n blockNumber: receipt.blockNumber,\n };\n }\n\n // Verification successful\n return {\n verified: true,\n amount,\n from,\n to,\n txHash,\n blockNumber: receipt.blockNumber,\n };\n }\n\n return { verified: false, error: 'No USDC 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"],"mappings":"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","names":["homedir","join","existsSync","writeFileSync","readFileSync","mkdirSync","ethers","readFileSync","readFileSync","resolve","join","homedir","existsSync","mkdirSync","resolve","writeFileSync","readFileSync"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "moltspay",
3
- "version": "0.7.0",
3
+ "version": "0.7.1",
4
4
  "description": "Payment infrastructure for AI Agents - Server & Client SDK",
5
5
  "keywords": [
6
6
  "ai-agent",