moltspay 0.8.1 → 0.8.2

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/.env.example ADDED
@@ -0,0 +1,10 @@
1
+ # MoltsPay Server Configuration
2
+ # Copy to ~/.moltspay/.env or ./.env and fill in values
3
+
4
+ # Network: true = Base mainnet, false = Base Sepolia testnet
5
+ USE_MAINNET=true
6
+
7
+ # CDP API Credentials (required for mainnet)
8
+ # Get from: https://portal.cdp.coinbase.com/
9
+ CDP_API_KEY_ID=
10
+ CDP_API_KEY_SECRET=
package/dist/cli/index.js CHANGED
@@ -367,28 +367,95 @@ var MoltsPayClient = class {
367
367
  // src/server/index.ts
368
368
  var import_fs2 = require("fs");
369
369
  var import_http = require("http");
370
+ var path = __toESM(require("path"));
370
371
  var X402_VERSION2 = 2;
371
372
  var PAYMENT_REQUIRED_HEADER2 = "x-payment-required";
372
373
  var PAYMENT_HEADER2 = "x-payment";
373
374
  var PAYMENT_RESPONSE_HEADER = "x-payment-response";
374
- var DEFAULT_FACILITATOR_URL = "https://x402.org/facilitator";
375
+ var FACILITATOR_TESTNET = "https://www.x402.org/facilitator";
376
+ var FACILITATOR_MAINNET = "https://api.cdp.coinbase.com/platform/v2/x402";
377
+ function loadEnvFiles() {
378
+ try {
379
+ const dotenv = require("dotenv");
380
+ const envPaths = [
381
+ path.join(process.cwd(), ".env"),
382
+ path.join(process.env.HOME || "", ".moltspay", ".env")
383
+ ];
384
+ for (const envPath of envPaths) {
385
+ if ((0, import_fs2.existsSync)(envPath)) {
386
+ dotenv.config({ path: envPath });
387
+ console.log(`[MoltsPay] Loaded config from ${envPath}`);
388
+ break;
389
+ }
390
+ }
391
+ } catch {
392
+ }
393
+ }
394
+ function getCDPConfig() {
395
+ loadEnvFiles();
396
+ return {
397
+ useMainnet: process.env.USE_MAINNET?.toLowerCase() === "true",
398
+ apiKeyId: process.env.CDP_API_KEY_ID,
399
+ apiKeySecret: process.env.CDP_API_KEY_SECRET
400
+ };
401
+ }
402
+ async function getCDPAuthHeaders(method, urlPath, body) {
403
+ const config = getCDPConfig();
404
+ if (!config.apiKeyId || !config.apiKeySecret) {
405
+ throw new Error("CDP_API_KEY_ID and CDP_API_KEY_SECRET required for mainnet");
406
+ }
407
+ try {
408
+ const { getAuthHeaders } = await import("@coinbase/cdp-sdk/auth");
409
+ const headers = await getAuthHeaders({
410
+ apiKeyId: config.apiKeyId,
411
+ apiKeySecret: config.apiKeySecret,
412
+ requestMethod: method,
413
+ requestHost: "api.cdp.coinbase.com",
414
+ requestPath: urlPath,
415
+ requestBody: body
416
+ });
417
+ return headers;
418
+ } catch (err) {
419
+ console.error("[MoltsPay] Failed to generate CDP auth headers:", err.message);
420
+ throw err;
421
+ }
422
+ }
375
423
  var MoltsPayServer = class {
376
424
  manifest;
377
425
  skills = /* @__PURE__ */ new Map();
378
426
  options;
427
+ cdpConfig;
379
428
  facilitatorUrl;
429
+ networkId;
380
430
  constructor(servicesPath, options = {}) {
431
+ this.cdpConfig = getCDPConfig();
381
432
  const content = (0, import_fs2.readFileSync)(servicesPath, "utf-8");
382
433
  this.manifest = JSON.parse(content);
383
434
  this.options = {
384
435
  port: options.port || 3e3,
385
436
  host: options.host || "0.0.0.0"
386
437
  };
387
- this.facilitatorUrl = options.facilitatorUrl || DEFAULT_FACILITATOR_URL;
438
+ if (this.cdpConfig.useMainnet) {
439
+ if (!this.cdpConfig.apiKeyId || !this.cdpConfig.apiKeySecret) {
440
+ console.warn("[MoltsPay] WARNING: USE_MAINNET=true but CDP keys not set!");
441
+ console.warn("[MoltsPay] Set CDP_API_KEY_ID and CDP_API_KEY_SECRET in ~/.moltspay/.env");
442
+ }
443
+ this.facilitatorUrl = FACILITATOR_MAINNET;
444
+ this.networkId = "eip155:8453";
445
+ } else {
446
+ this.facilitatorUrl = options.facilitatorUrl || FACILITATOR_TESTNET;
447
+ this.networkId = "eip155:84532";
448
+ }
449
+ const networkName = this.cdpConfig.useMainnet ? "Base mainnet" : "Base Sepolia (testnet)";
450
+ const facilitatorName = this.cdpConfig.useMainnet ? "CDP" : "x402.org";
388
451
  console.log(`[MoltsPay] Loaded ${this.manifest.services.length} services from ${servicesPath}`);
389
452
  console.log(`[MoltsPay] Provider: ${this.manifest.provider.name}`);
390
453
  console.log(`[MoltsPay] Receive wallet: ${this.manifest.provider.wallet}`);
391
- console.log(`[MoltsPay] Facilitator: ${this.facilitatorUrl}`);
454
+ console.log(`[MoltsPay] Network: ${this.networkId} (${networkName})`);
455
+ console.log(`[MoltsPay] Facilitator: ${facilitatorName} (${this.facilitatorUrl})`);
456
+ if (this.cdpConfig.useMainnet && this.cdpConfig.apiKeyId) {
457
+ console.log(`[MoltsPay] CDP API Key: ${this.cdpConfig.apiKeyId.slice(0, 8)}...`);
458
+ }
392
459
  console.log(`[MoltsPay] Protocol: x402 (gasless for both client AND server)`);
393
460
  }
394
461
  /**
@@ -449,7 +516,6 @@ var MoltsPayServer = class {
449
516
  * GET /services - List available services
450
517
  */
451
518
  handleGetServices(res) {
452
- const chain = getChain(this.manifest.provider.chain);
453
519
  const services = this.manifest.services.map((s) => ({
454
520
  id: s.id,
455
521
  name: s.name,
@@ -465,16 +531,15 @@ var MoltsPayServer = class {
465
531
  services,
466
532
  x402: {
467
533
  version: X402_VERSION2,
468
- network: `eip155:${chain.chainId}`,
534
+ network: this.networkId,
469
535
  schemes: ["exact"],
470
- facilitator: this.facilitatorUrl
536
+ facilitator: this.cdpConfig.useMainnet ? "cdp" : "x402.org",
537
+ mainnet: this.cdpConfig.useMainnet
471
538
  }
472
539
  });
473
540
  }
474
541
  /**
475
542
  * POST /execute - Execute service with x402 payment
476
- * Body: { service: string, params: object }
477
- * Header: X-Payment (optional - if missing, returns 402)
478
543
  */
479
544
  async handleExecute(body, paymentHeader, res) {
480
545
  const { service, params } = body;
@@ -549,16 +614,17 @@ var MoltsPayServer = class {
549
614
  * Return 402 with x402 payment requirements
550
615
  */
551
616
  sendPaymentRequired(config, res) {
552
- const chain = getChain(this.manifest.provider.chain);
553
617
  const amountInUnits = Math.floor(config.price * 1e6).toString();
554
618
  const requirements = [{
555
619
  scheme: "exact",
556
- network: `eip155:${chain.chainId}`,
620
+ network: this.networkId,
557
621
  maxAmountRequired: amountInUnits,
558
622
  resource: this.manifest.provider.wallet,
559
623
  description: `${config.name} - $${config.price} ${config.currency}`,
560
- // Include facilitator info for client
561
- extra: JSON.stringify({ facilitator: this.facilitatorUrl })
624
+ extra: JSON.stringify({
625
+ facilitator: this.cdpConfig.useMainnet ? "cdp" : "x402.org",
626
+ mainnet: this.cdpConfig.useMainnet
627
+ })
562
628
  }];
563
629
  const encoded = Buffer.from(JSON.stringify(requirements)).toString("base64");
564
630
  res.writeHead(402, {
@@ -572,7 +638,7 @@ var MoltsPayServer = class {
572
638
  }, null, 2));
573
639
  }
574
640
  /**
575
- * Basic payment validation (before calling facilitator)
641
+ * Basic payment validation
576
642
  */
577
643
  validatePayment(payment, config) {
578
644
  if (payment.x402Version !== X402_VERSION2) {
@@ -581,37 +647,45 @@ var MoltsPayServer = class {
581
647
  if (payment.scheme !== "exact") {
582
648
  return { valid: false, error: `Unsupported scheme: ${payment.scheme}` };
583
649
  }
584
- const chain = getChain(this.manifest.provider.chain);
585
- const expectedNetwork = `eip155:${chain.chainId}`;
586
- if (payment.network !== expectedNetwork) {
587
- return { valid: false, error: `Network mismatch: expected ${expectedNetwork}` };
650
+ if (payment.network !== this.networkId) {
651
+ return { valid: false, error: `Network mismatch: expected ${this.networkId}, got ${payment.network}` };
588
652
  }
589
653
  return { valid: true };
590
654
  }
591
655
  /**
592
- * Verify payment with facilitator
656
+ * Verify payment with facilitator (testnet or CDP)
593
657
  */
594
658
  async verifyWithFacilitator(payment, config) {
595
659
  try {
596
- const chain = getChain(this.manifest.provider.chain);
597
660
  const amountInUnits = Math.floor(config.price * 1e6).toString();
598
661
  const requirements = {
599
662
  scheme: "exact",
600
- network: `eip155:${chain.chainId}`,
663
+ network: this.networkId,
601
664
  maxAmountRequired: amountInUnits,
602
- resource: this.manifest.provider.wallet
665
+ resource: this.manifest.provider.wallet,
666
+ payTo: this.manifest.provider.wallet
603
667
  };
668
+ const requestBody = {
669
+ paymentPayload: payment,
670
+ paymentRequirements: requirements
671
+ };
672
+ let headers = { "Content-Type": "application/json" };
673
+ if (this.cdpConfig.useMainnet) {
674
+ const authHeaders = await getCDPAuthHeaders(
675
+ "POST",
676
+ "/platform/v2/x402/verify",
677
+ requestBody
678
+ );
679
+ headers = { ...headers, ...authHeaders };
680
+ }
604
681
  const response = await fetch(`${this.facilitatorUrl}/verify`, {
605
682
  method: "POST",
606
- headers: { "Content-Type": "application/json" },
607
- body: JSON.stringify({
608
- paymentPayload: payment,
609
- paymentRequirements: requirements
610
- })
683
+ headers,
684
+ body: JSON.stringify(requestBody)
611
685
  });
612
686
  const result = await response.json();
613
687
  if (!response.ok || !result.isValid) {
614
- return { valid: false, error: result.invalidReason || "Verification failed" };
688
+ return { valid: false, error: result.invalidReason || result.error || "Verification failed" };
615
689
  }
616
690
  return { valid: true };
617
691
  } catch (err) {
@@ -622,25 +696,35 @@ var MoltsPayServer = class {
622
696
  * Settle payment with facilitator (execute on-chain transfer)
623
697
  */
624
698
  async settleWithFacilitator(payment, config) {
625
- const chain = getChain(this.manifest.provider.chain);
626
699
  const amountInUnits = Math.floor(config.price * 1e6).toString();
627
700
  const requirements = {
628
701
  scheme: "exact",
629
- network: `eip155:${chain.chainId}`,
702
+ network: this.networkId,
630
703
  maxAmountRequired: amountInUnits,
631
- resource: this.manifest.provider.wallet
704
+ resource: this.manifest.provider.wallet,
705
+ payTo: this.manifest.provider.wallet
632
706
  };
707
+ const requestBody = {
708
+ paymentPayload: payment,
709
+ paymentRequirements: requirements
710
+ };
711
+ let headers = { "Content-Type": "application/json" };
712
+ if (this.cdpConfig.useMainnet) {
713
+ const authHeaders = await getCDPAuthHeaders(
714
+ "POST",
715
+ "/platform/v2/x402/settle",
716
+ requestBody
717
+ );
718
+ headers = { ...headers, ...authHeaders };
719
+ }
633
720
  const response = await fetch(`${this.facilitatorUrl}/settle`, {
634
721
  method: "POST",
635
- headers: { "Content-Type": "application/json" },
636
- body: JSON.stringify({
637
- paymentPayload: payment,
638
- paymentRequirements: requirements
639
- })
722
+ headers,
723
+ body: JSON.stringify(requestBody)
640
724
  });
641
725
  const result = await response.json();
642
- if (!response.ok) {
643
- throw new Error(result.error || "Settlement failed");
726
+ if (!response.ok || !result.success) {
727
+ throw new Error(result.error || result.errorReason || "Settlement failed");
644
728
  }
645
729
  return {
646
730
  transaction: result.transaction,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/cli/index.ts","../../src/client/index.ts","../../src/chains/index.ts","../../src/server/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 .option('--facilitator <url>', 'x402 facilitator URL (default: https://x402.org/facilitator)')\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 const facilitatorUrl = options.facilitator;\n\n console.log(`\\n🚀 Starting MoltsPay Server (x402 protocol)\\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, facilitatorUrl });\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 * \n * --image can be a URL or local file path:\n * URL: https://example.com/image.jpg -> sends as image_url\n * File: ./image.jpg or /path/to/image.jpg -> sends as image_base64\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 <path>', 'Image URL or local file path')\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 \n // Handle --image: URL or local file\n if (options.image) {\n const imagePath = options.image;\n \n if (imagePath.startsWith('http://') || imagePath.startsWith('https://')) {\n // It's a URL\n params.image_url = imagePath;\n } else {\n // It's a local file - read and convert to base64\n const filePath = resolve(imagePath);\n \n if (!existsSync(filePath)) {\n console.error(`❌ Image file not found: ${filePath}`);\n process.exit(1);\n }\n \n const imageData = readFileSync(filePath);\n params.image_base64 = imageData.toString('base64');\n }\n }\n\n if (!params.prompt) {\n console.error('❌ Missing prompt. Use --prompt or pass JSON params');\n process.exit(1);\n }\n\n const imageDisplay = params.image_url || (params.image_base64 ? `[local file: ${options.image}]` : null);\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 (imageDisplay) console.log(` Image: ${imageDisplay}`);\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 * Uses x402 protocol for gasless, pay-for-success payments.\n * \n * Usage:\n * const client = new MoltsPayClient(); // Loads from ~/.moltspay/\n * const services = await client.getServices('http://provider:3000');\n * const result = await client.pay('http://provider:3000', 'text-to-video', { prompt: '...' });\n */\n\nimport { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';\nimport { homedir } from 'os';\nimport { join } from 'path';\nimport { Wallet, ethers } from 'ethers';\nimport { getChain, type ChainName } from '../chains/index.js';\nimport {\n ClientConfig,\n WalletData,\n ServicesResponse,\n MoltsPayClientOptions,\n} from './types.js';\n\nexport * from './types.js';\n\n// x402 constants\nconst X402_VERSION = 2;\nconst PAYMENT_REQUIRED_HEADER = 'x-payment-required';\nconst PAYMENT_HEADER = 'x-payment';\n\ninterface X402PaymentRequirements {\n scheme: string;\n network: string;\n maxAmountRequired: string;\n resource: string;\n description?: string;\n}\n\ninterface EIP3009Authorization {\n from: string;\n to: string;\n value: string;\n validAfter: string;\n validBefore: string;\n nonce: string;\n}\n\nconst DEFAULT_CONFIG: ClientConfig = {\n chain: 'base',\n limits: {\n maxPerTx: 100,\n maxPerDay: 1000,\n },\n};\n\nexport class MoltsPayClient {\n private configDir: string;\n private config: ClientConfig;\n private walletData: WalletData | null = null;\n private wallet: Wallet | null = null;\n private todaySpending: number = 0;\n private lastSpendingReset: number = 0;\n\n constructor(options: MoltsPayClientOptions = {}) {\n this.configDir = options.configDir || join(homedir(), '.moltspay');\n this.config = this.loadConfig();\n this.walletData = this.loadWallet();\n \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 (x402 protocol)\n * \n * This is GASLESS for the client - server pays gas to claim payment.\n * This is PAY-FOR-SUCCESS - payment only claimed if service succeeds.\n */\n async pay(\n serverUrl: string,\n service: string,\n params: Record<string, any>\n ): Promise<Record<string, any>> {\n if (!this.wallet || !this.walletData) {\n throw new Error('Client not initialized. Run: npx moltspay init');\n }\n\n // Step 1: Make initial request without payment\n console.log(`[MoltsPay] Requesting service: ${service}`);\n const initialRes = await fetch(`${serverUrl}/execute`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ service, params }),\n });\n\n // If not 402, check for success or error\n if (initialRes.status !== 402) {\n const data = await initialRes.json() as any;\n if (initialRes.ok && data.result) {\n return data.result;\n }\n throw new Error(data.error || 'Unexpected response');\n }\n\n // Step 2: Parse payment requirements from 402 response\n const paymentRequiredHeader = initialRes.headers.get(PAYMENT_REQUIRED_HEADER);\n if (!paymentRequiredHeader) {\n throw new Error('Missing x-payment-required header');\n }\n\n let requirements: X402PaymentRequirements[];\n try {\n const decoded = Buffer.from(paymentRequiredHeader, 'base64').toString('utf-8');\n requirements = JSON.parse(decoded);\n if (!Array.isArray(requirements)) {\n requirements = [requirements];\n }\n } catch {\n throw new Error('Invalid x-payment-required header');\n }\n\n // Find matching requirement for our chain\n const chain = getChain(this.config.chain as ChainName);\n const network = `eip155:${chain.chainId}`;\n const req = requirements.find(r => r.scheme === 'exact' && r.network === network);\n \n if (!req) {\n throw new Error(`No matching payment option for ${network}`);\n }\n\n // Step 3: Check limits\n const amount = Number(req.maxAmountRequired) / 1e6;\n this.checkLimits(amount);\n\n console.log(`[MoltsPay] Signing payment: $${amount} USDC (gasless)`);\n\n // Step 4: Sign EIP-3009 authorization (GASLESS - just signing)\n const authorization = await this.signEIP3009(req.resource, amount, chain);\n\n // Step 5: Create x402 payment payload\n const payload = {\n x402Version: X402_VERSION,\n scheme: 'exact',\n network,\n payload: authorization,\n };\n const paymentHeader = Buffer.from(JSON.stringify(payload)).toString('base64');\n\n // Step 6: Retry with payment header\n console.log(`[MoltsPay] Sending request with payment...`);\n const paidRes = await fetch(`${serverUrl}/execute`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n [PAYMENT_HEADER]: paymentHeader,\n },\n body: JSON.stringify({ service, params }),\n });\n\n const result = await paidRes.json() as any;\n\n if (!paidRes.ok) {\n throw new Error(result.error || 'Service execution failed');\n }\n\n // Update spending tracking\n this.recordSpending(amount);\n\n console.log(`[MoltsPay] Success! Payment: ${result.payment?.status || 'claimed'}`);\n \n return result.result;\n }\n\n /**\n * Sign EIP-3009 transferWithAuthorization (GASLESS)\n * This only signs - no on-chain transaction, no gas needed.\n */\n private async signEIP3009(\n to: string,\n amount: number,\n chain: { chainId: number; usdc: string }\n ): Promise<{ authorization: EIP3009Authorization; signature: string }> {\n const validAfter = 0;\n const validBefore = Math.floor(Date.now() / 1000) + 3600; // 1 hour\n const nonce = ethers.hexlify(ethers.randomBytes(32));\n const value = BigInt(Math.floor(amount * 1e6)).toString();\n\n const authorization: EIP3009Authorization = {\n from: this.wallet!.address,\n to,\n value,\n validAfter: validAfter.toString(),\n validBefore: validBefore.toString(),\n nonce,\n };\n\n // EIP-712 domain for USDC\n const domain = {\n name: 'USD Coin',\n version: '2',\n chainId: chain.chainId,\n verifyingContract: chain.usdc,\n };\n\n // EIP-3009 types\n const types = {\n TransferWithAuthorization: [\n { name: 'from', type: 'address' },\n { name: 'to', type: 'address' },\n { name: 'value', type: 'uint256' },\n { name: 'validAfter', type: 'uint256' },\n { name: 'validBefore', type: 'uint256' },\n { name: 'nonce', type: 'bytes32' },\n ],\n };\n\n const signature = await this.wallet!.signTypedData(domain, types, authorization);\n\n return { authorization, signature };\n }\n\n /**\n * Check spending limits\n */\n private checkLimits(amount: number): void {\n // Check per-tx limit\n if (amount > this.config.limits.maxPerTx) {\n throw new Error(\n `Amount $${amount} exceeds max per transaction ($${this.config.limits.maxPerTx})`\n );\n }\n\n // Reset daily spending if new day\n const today = new Date().setHours(0, 0, 0, 0);\n if (today > this.lastSpendingReset) {\n this.todaySpending = 0;\n this.lastSpendingReset = today;\n }\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 // --- 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 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 * Uses x402 protocol with public facilitator (https://x402.org/facilitator).\n * Server does NOT need private key - facilitator handles on-chain settlement.\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 { getChain } from '../chains/index.js';\nimport type { ChainName } from '../chains/index.js';\nimport {\n ServicesManifest,\n ServiceConfig,\n SkillFunction,\n RegisteredSkill,\n MoltsPayServerOptions,\n} from './types.js';\n\nexport * from './types.js';\n\n// x402 constants\nconst X402_VERSION = 2;\nconst PAYMENT_REQUIRED_HEADER = 'x-payment-required';\nconst PAYMENT_HEADER = 'x-payment';\nconst PAYMENT_RESPONSE_HEADER = 'x-payment-response';\n\n// Default facilitator URL\nconst DEFAULT_FACILITATOR_URL = 'https://x402.org/facilitator';\n\ninterface X402PaymentPayload {\n x402Version: number;\n scheme: string;\n network: string;\n payload: any;\n}\n\nexport class MoltsPayServer {\n private manifest: ServicesManifest;\n private skills: Map<string, RegisteredSkill> = new Map();\n private options: MoltsPayServerOptions;\n private facilitatorUrl: string;\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 };\n\n this.facilitatorUrl = options.facilitatorUrl || DEFAULT_FACILITATOR_URL;\n\n console.log(`[MoltsPay] Loaded ${this.manifest.services.length} services from ${servicesPath}`);\n console.log(`[MoltsPay] Provider: ${this.manifest.provider.name}`);\n console.log(`[MoltsPay] Receive wallet: ${this.manifest.provider.wallet}`);\n console.log(`[MoltsPay] Facilitator: ${this.facilitatorUrl}`);\n console.log(`[MoltsPay] Protocol: x402 (gasless for both client AND server)`);\n }\n\n /**\n * Register a skill handler for a service\n */\n skill(serviceId: string, handler: SkillFunction): this {\n const config = this.manifest.services.find(s => s.id === serviceId);\n if (!config) {\n throw new Error(`Service '${serviceId}' not found in manifest`);\n }\n this.skills.set(serviceId, { id: serviceId, config, handler });\n return this;\n }\n\n /**\n * Start HTTP server\n */\n listen(port?: number): void {\n const p = port || this.options.port || 3000;\n const host = this.options.host || '0.0.0.0';\n\n const server = createServer((req, res) => this.handleRequest(req, res));\n server.listen(p, host, () => {\n console.log(`[MoltsPay] Server listening on http://${host}:${p}`);\n console.log(`[MoltsPay] Endpoints:`);\n console.log(` GET /services - List available services`);\n console.log(` POST /execute - Execute service (x402 payment)`);\n });\n }\n\n /**\n * Handle incoming request\n */\n private async handleRequest(req: IncomingMessage, res: ServerResponse): Promise<void> {\n // CORS\n res.setHeader('Access-Control-Allow-Origin', '*');\n res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');\n res.setHeader('Access-Control-Allow-Headers', 'Content-Type, X-Payment');\n res.setHeader('Access-Control-Expose-Headers', 'X-Payment-Required, X-Payment-Response');\n\n if (req.method === 'OPTIONS') {\n res.writeHead(204);\n res.end();\n return;\n }\n\n try {\n const url = new URL(req.url || '/', `http://${req.headers.host}`);\n \n if (url.pathname === '/services' && req.method === 'GET') {\n return this.handleGetServices(res);\n }\n\n if (url.pathname === '/execute' && req.method === 'POST') {\n const body = await this.readBody(req);\n const paymentHeader = req.headers[PAYMENT_HEADER] as string | undefined;\n return await this.handleExecute(body, paymentHeader, res);\n }\n\n // 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 chain = getChain(this.manifest.provider.chain as ChainName);\n \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 x402: {\n version: X402_VERSION,\n network: `eip155:${chain.chainId}`,\n schemes: ['exact'],\n facilitator: this.facilitatorUrl,\n },\n });\n }\n\n /**\n * POST /execute - Execute service with x402 payment\n * Body: { service: string, params: object }\n * Header: X-Payment (optional - if missing, returns 402)\n */\n private async handleExecute(\n body: any,\n paymentHeader: string | undefined,\n res: ServerResponse\n ): Promise<void> {\n const { service, params } = body;\n\n if (!service) {\n return this.sendJson(res, 400, { error: 'Missing service' });\n }\n\n const skill = this.skills.get(service);\n if (!skill) {\n return this.sendJson(res, 404, { error: `Service '${service}' not found or not registered` });\n }\n\n // Validate required params\n for (const [key, field] of Object.entries(skill.config.input)) {\n if (field.required && (!params || params[key] === undefined)) {\n return this.sendJson(res, 400, { error: `Missing required param: ${key}` });\n }\n }\n\n // If no payment header, return 402 with payment requirements\n if (!paymentHeader) {\n return this.sendPaymentRequired(skill.config, res);\n }\n\n // Parse payment payload\n let payment: X402PaymentPayload;\n try {\n const decoded = Buffer.from(paymentHeader, 'base64').toString('utf-8');\n payment = JSON.parse(decoded);\n } catch {\n return this.sendJson(res, 400, { error: 'Invalid X-Payment header' });\n }\n\n // Validate basic payment fields\n const validation = this.validatePayment(payment, skill.config);\n if (!validation.valid) {\n return this.sendJson(res, 402, { error: validation.error });\n }\n\n // Verify payment with facilitator\n console.log(`[MoltsPay] Verifying payment with facilitator...`);\n const verifyResult = await this.verifyWithFacilitator(payment, skill.config);\n if (!verifyResult.valid) {\n return this.sendJson(res, 402, { error: `Payment verification failed: ${verifyResult.error}` });\n }\n\n // Execute skill FIRST (pay-for-success)\n console.log(`[MoltsPay] Executing skill: ${service}`);\n let result: any;\n try {\n result = await skill.handler(params || {});\n } catch (err: any) {\n console.error('[MoltsPay] Skill execution failed:', err.message);\n // Don't settle payment if skill fails\n return this.sendJson(res, 500, {\n error: 'Service execution failed',\n message: err.message,\n });\n }\n\n // Skill succeeded - now settle payment with facilitator\n console.log(`[MoltsPay] Skill succeeded, settling payment...`);\n let settlement: any = null;\n try {\n settlement = await this.settleWithFacilitator(payment, skill.config);\n console.log(`[MoltsPay] Payment settled: ${settlement.transaction || 'pending'}`);\n } catch (err: any) {\n console.error('[MoltsPay] Settlement failed:', err.message);\n // Still return result - facilitator may settle later\n }\n\n // Build response with settlement info\n const responseHeaders: Record<string, string> = {};\n if (settlement) {\n const responsePayload = {\n success: true,\n transaction: settlement.transaction,\n network: payment.network,\n };\n responseHeaders[PAYMENT_RESPONSE_HEADER] = Buffer.from(\n JSON.stringify(responsePayload)\n ).toString('base64');\n }\n\n this.sendJson(res, 200, {\n success: true,\n result,\n payment: settlement \n ? { transaction: settlement.transaction, status: 'settled' }\n : { status: 'pending' },\n }, responseHeaders);\n }\n\n /**\n * Return 402 with x402 payment requirements\n */\n private sendPaymentRequired(config: ServiceConfig, res: ServerResponse): void {\n const chain = getChain(this.manifest.provider.chain as ChainName);\n const amountInUnits = Math.floor(config.price * 1e6).toString();\n\n const requirements = [{\n scheme: 'exact',\n network: `eip155:${chain.chainId}`,\n maxAmountRequired: amountInUnits,\n resource: this.manifest.provider.wallet,\n description: `${config.name} - $${config.price} ${config.currency}`,\n // Include facilitator info for client\n extra: JSON.stringify({ facilitator: this.facilitatorUrl }),\n }];\n\n const encoded = Buffer.from(JSON.stringify(requirements)).toString('base64');\n\n res.writeHead(402, {\n 'Content-Type': 'application/json',\n [PAYMENT_REQUIRED_HEADER]: encoded,\n });\n res.end(JSON.stringify({\n error: 'Payment required',\n message: `Service requires $${config.price} ${config.currency}`,\n x402: requirements[0],\n }, null, 2));\n }\n\n /**\n * Basic payment validation (before calling facilitator)\n */\n private validatePayment(\n payment: X402PaymentPayload,\n config: ServiceConfig\n ): { valid: boolean; error?: string } {\n if (payment.x402Version !== X402_VERSION) {\n return { valid: false, error: `Unsupported x402 version: ${payment.x402Version}` };\n }\n\n if (payment.scheme !== 'exact') {\n return { valid: false, error: `Unsupported scheme: ${payment.scheme}` };\n }\n\n const chain = getChain(this.manifest.provider.chain as ChainName);\n const expectedNetwork = `eip155:${chain.chainId}`;\n if (payment.network !== expectedNetwork) {\n return { valid: false, error: `Network mismatch: expected ${expectedNetwork}` };\n }\n\n return { valid: true };\n }\n\n /**\n * Verify payment with facilitator\n */\n private async verifyWithFacilitator(\n payment: X402PaymentPayload,\n config: ServiceConfig\n ): Promise<{ valid: boolean; error?: string }> {\n try {\n const chain = getChain(this.manifest.provider.chain as ChainName);\n const amountInUnits = Math.floor(config.price * 1e6).toString();\n\n const requirements = {\n scheme: 'exact',\n network: `eip155:${chain.chainId}`,\n maxAmountRequired: amountInUnits,\n resource: this.manifest.provider.wallet,\n };\n\n const response = await fetch(`${this.facilitatorUrl}/verify`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n paymentPayload: payment,\n paymentRequirements: requirements,\n }),\n });\n\n const result = await response.json() as any;\n\n if (!response.ok || !result.isValid) {\n return { valid: false, error: result.invalidReason || 'Verification failed' };\n }\n\n return { valid: true };\n } catch (err: any) {\n return { valid: false, error: `Facilitator error: ${err.message}` };\n }\n }\n\n /**\n * Settle payment with facilitator (execute on-chain transfer)\n */\n private async settleWithFacilitator(\n payment: X402PaymentPayload,\n config: ServiceConfig\n ): Promise<{ transaction?: string; status: string }> {\n const chain = getChain(this.manifest.provider.chain as ChainName);\n const amountInUnits = Math.floor(config.price * 1e6).toString();\n\n const requirements = {\n scheme: 'exact',\n network: `eip155:${chain.chainId}`,\n maxAmountRequired: amountInUnits,\n resource: this.manifest.provider.wallet,\n };\n\n const response = await fetch(`${this.facilitatorUrl}/settle`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n paymentPayload: payment,\n paymentRequirements: requirements,\n }),\n });\n\n const result = await response.json() as any;\n\n if (!response.ok) {\n throw new Error(result.error || 'Settlement failed');\n }\n\n return {\n transaction: result.transaction,\n status: result.status || 'settled',\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(\n res: ServerResponse, \n status: number, \n data: any,\n extraHeaders?: Record<string, string>\n ): void {\n const headers: Record<string, string> = { 'Content-Type': 'application/json' };\n if (extraHeaders) {\n Object.assign(headers, extraHeaders);\n }\n res.writeHead(status, headers);\n res.end(JSON.stringify(data, null, 2));\n }\n}\n"],"mappings":"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","names":["import_os","import_path","import_fs","import_fs","X402_VERSION","PAYMENT_REQUIRED_HEADER","PAYMENT_HEADER","resolve","resolve"]}
1
+ {"version":3,"sources":["../../src/cli/index.ts","../../src/client/index.ts","../../src/chains/index.ts","../../src/server/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 .option('--facilitator <url>', 'x402 facilitator URL (default: https://x402.org/facilitator)')\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 const facilitatorUrl = options.facilitator;\n\n console.log(`\\n🚀 Starting MoltsPay Server (x402 protocol)\\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, facilitatorUrl });\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 * \n * --image can be a URL or local file path:\n * URL: https://example.com/image.jpg -> sends as image_url\n * File: ./image.jpg or /path/to/image.jpg -> sends as image_base64\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 <path>', 'Image URL or local file path')\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 \n // Handle --image: URL or local file\n if (options.image) {\n const imagePath = options.image;\n \n if (imagePath.startsWith('http://') || imagePath.startsWith('https://')) {\n // It's a URL\n params.image_url = imagePath;\n } else {\n // It's a local file - read and convert to base64\n const filePath = resolve(imagePath);\n \n if (!existsSync(filePath)) {\n console.error(`❌ Image file not found: ${filePath}`);\n process.exit(1);\n }\n \n const imageData = readFileSync(filePath);\n params.image_base64 = imageData.toString('base64');\n }\n }\n\n if (!params.prompt) {\n console.error('❌ Missing prompt. Use --prompt or pass JSON params');\n process.exit(1);\n }\n\n const imageDisplay = params.image_url || (params.image_base64 ? `[local file: ${options.image}]` : null);\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 (imageDisplay) console.log(` Image: ${imageDisplay}`);\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 * Uses x402 protocol for gasless, pay-for-success payments.\n * \n * Usage:\n * const client = new MoltsPayClient(); // Loads from ~/.moltspay/\n * const services = await client.getServices('http://provider:3000');\n * const result = await client.pay('http://provider:3000', 'text-to-video', { prompt: '...' });\n */\n\nimport { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';\nimport { homedir } from 'os';\nimport { join } from 'path';\nimport { Wallet, ethers } from 'ethers';\nimport { getChain, type ChainName } from '../chains/index.js';\nimport {\n ClientConfig,\n WalletData,\n ServicesResponse,\n MoltsPayClientOptions,\n} from './types.js';\n\nexport * from './types.js';\n\n// x402 constants\nconst X402_VERSION = 2;\nconst PAYMENT_REQUIRED_HEADER = 'x-payment-required';\nconst PAYMENT_HEADER = 'x-payment';\n\ninterface X402PaymentRequirements {\n scheme: string;\n network: string;\n maxAmountRequired: string;\n resource: string;\n description?: string;\n}\n\ninterface EIP3009Authorization {\n from: string;\n to: string;\n value: string;\n validAfter: string;\n validBefore: string;\n nonce: string;\n}\n\nconst DEFAULT_CONFIG: ClientConfig = {\n chain: 'base',\n limits: {\n maxPerTx: 100,\n maxPerDay: 1000,\n },\n};\n\nexport class MoltsPayClient {\n private configDir: string;\n private config: ClientConfig;\n private walletData: WalletData | null = null;\n private wallet: Wallet | null = null;\n private todaySpending: number = 0;\n private lastSpendingReset: number = 0;\n\n constructor(options: MoltsPayClientOptions = {}) {\n this.configDir = options.configDir || join(homedir(), '.moltspay');\n this.config = this.loadConfig();\n this.walletData = this.loadWallet();\n \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 (x402 protocol)\n * \n * This is GASLESS for the client - server pays gas to claim payment.\n * This is PAY-FOR-SUCCESS - payment only claimed if service succeeds.\n */\n async pay(\n serverUrl: string,\n service: string,\n params: Record<string, any>\n ): Promise<Record<string, any>> {\n if (!this.wallet || !this.walletData) {\n throw new Error('Client not initialized. Run: npx moltspay init');\n }\n\n // Step 1: Make initial request without payment\n console.log(`[MoltsPay] Requesting service: ${service}`);\n const initialRes = await fetch(`${serverUrl}/execute`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ service, params }),\n });\n\n // If not 402, check for success or error\n if (initialRes.status !== 402) {\n const data = await initialRes.json() as any;\n if (initialRes.ok && data.result) {\n return data.result;\n }\n throw new Error(data.error || 'Unexpected response');\n }\n\n // Step 2: Parse payment requirements from 402 response\n const paymentRequiredHeader = initialRes.headers.get(PAYMENT_REQUIRED_HEADER);\n if (!paymentRequiredHeader) {\n throw new Error('Missing x-payment-required header');\n }\n\n let requirements: X402PaymentRequirements[];\n try {\n const decoded = Buffer.from(paymentRequiredHeader, 'base64').toString('utf-8');\n requirements = JSON.parse(decoded);\n if (!Array.isArray(requirements)) {\n requirements = [requirements];\n }\n } catch {\n throw new Error('Invalid x-payment-required header');\n }\n\n // Find matching requirement for our chain\n const chain = getChain(this.config.chain as ChainName);\n const network = `eip155:${chain.chainId}`;\n const req = requirements.find(r => r.scheme === 'exact' && r.network === network);\n \n if (!req) {\n throw new Error(`No matching payment option for ${network}`);\n }\n\n // Step 3: Check limits\n const amount = Number(req.maxAmountRequired) / 1e6;\n this.checkLimits(amount);\n\n console.log(`[MoltsPay] Signing payment: $${amount} USDC (gasless)`);\n\n // Step 4: Sign EIP-3009 authorization (GASLESS - just signing)\n const authorization = await this.signEIP3009(req.resource, amount, chain);\n\n // Step 5: Create x402 payment payload\n const payload = {\n x402Version: X402_VERSION,\n scheme: 'exact',\n network,\n payload: authorization,\n };\n const paymentHeader = Buffer.from(JSON.stringify(payload)).toString('base64');\n\n // Step 6: Retry with payment header\n console.log(`[MoltsPay] Sending request with payment...`);\n const paidRes = await fetch(`${serverUrl}/execute`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n [PAYMENT_HEADER]: paymentHeader,\n },\n body: JSON.stringify({ service, params }),\n });\n\n const result = await paidRes.json() as any;\n\n if (!paidRes.ok) {\n throw new Error(result.error || 'Service execution failed');\n }\n\n // Update spending tracking\n this.recordSpending(amount);\n\n console.log(`[MoltsPay] Success! Payment: ${result.payment?.status || 'claimed'}`);\n \n return result.result;\n }\n\n /**\n * Sign EIP-3009 transferWithAuthorization (GASLESS)\n * This only signs - no on-chain transaction, no gas needed.\n */\n private async signEIP3009(\n to: string,\n amount: number,\n chain: { chainId: number; usdc: string }\n ): Promise<{ authorization: EIP3009Authorization; signature: string }> {\n const validAfter = 0;\n const validBefore = Math.floor(Date.now() / 1000) + 3600; // 1 hour\n const nonce = ethers.hexlify(ethers.randomBytes(32));\n const value = BigInt(Math.floor(amount * 1e6)).toString();\n\n const authorization: EIP3009Authorization = {\n from: this.wallet!.address,\n to,\n value,\n validAfter: validAfter.toString(),\n validBefore: validBefore.toString(),\n nonce,\n };\n\n // EIP-712 domain for USDC\n const domain = {\n name: 'USD Coin',\n version: '2',\n chainId: chain.chainId,\n verifyingContract: chain.usdc,\n };\n\n // EIP-3009 types\n const types = {\n TransferWithAuthorization: [\n { name: 'from', type: 'address' },\n { name: 'to', type: 'address' },\n { name: 'value', type: 'uint256' },\n { name: 'validAfter', type: 'uint256' },\n { name: 'validBefore', type: 'uint256' },\n { name: 'nonce', type: 'bytes32' },\n ],\n };\n\n const signature = await this.wallet!.signTypedData(domain, types, authorization);\n\n return { authorization, signature };\n }\n\n /**\n * Check spending limits\n */\n private checkLimits(amount: number): void {\n // Check per-tx limit\n if (amount > this.config.limits.maxPerTx) {\n throw new Error(\n `Amount $${amount} exceeds max per transaction ($${this.config.limits.maxPerTx})`\n );\n }\n\n // Reset daily spending if new day\n const today = new Date().setHours(0, 0, 0, 0);\n if (today > this.lastSpendingReset) {\n this.todaySpending = 0;\n this.lastSpendingReset = today;\n }\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 // --- 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 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 * Supports both testnet (x402.org) and mainnet (CDP) facilitators.\n * Server does NOT need private key - facilitator handles on-chain settlement.\n * \n * Environment variables (from ~/.moltspay/.env or process.env):\n * USE_MAINNET=true - Use Base mainnet (requires CDP keys)\n * CDP_API_KEY_ID=xxx - Coinbase Developer Platform API key ID\n * CDP_API_KEY_SECRET=xxx - CDP API key secret\n * \n * Usage:\n * const server = new MoltsPayServer('./moltspay.services.json');\n * server.skill('text-to-video', async (params) => { ... });\n * server.listen(3000);\n */\n\nimport { readFileSync, existsSync } from 'fs';\nimport { createServer, IncomingMessage, ServerResponse } from 'http';\nimport * as path from 'path';\nimport { getChain } from '../chains/index.js';\nimport type { ChainName } from '../chains/index.js';\nimport {\n ServicesManifest,\n ServiceConfig,\n SkillFunction,\n RegisteredSkill,\n MoltsPayServerOptions,\n} from './types.js';\n\nexport * from './types.js';\n\n// x402 constants\nconst X402_VERSION = 2;\nconst PAYMENT_REQUIRED_HEADER = 'x-payment-required';\nconst PAYMENT_HEADER = 'x-payment';\nconst PAYMENT_RESPONSE_HEADER = 'x-payment-response';\n\n// Facilitator URLs\nconst FACILITATOR_TESTNET = 'https://www.x402.org/facilitator';\nconst FACILITATOR_MAINNET = 'https://api.cdp.coinbase.com/platform/v2/x402';\n\ninterface X402PaymentPayload {\n x402Version: number;\n scheme: string;\n network: string;\n payload: any;\n}\n\ninterface CDPConfig {\n useMainnet: boolean;\n apiKeyId?: string;\n apiKeySecret?: string;\n}\n\n/**\n * Load environment from .env files\n */\nfunction loadEnvFiles(): void {\n // Try to load dotenv\n try {\n const dotenv = require('dotenv');\n \n // Priority: current dir > ~/.moltspay/\n const envPaths = [\n path.join(process.cwd(), '.env'),\n path.join(process.env.HOME || '', '.moltspay', '.env'),\n ];\n \n for (const envPath of envPaths) {\n if (existsSync(envPath)) {\n dotenv.config({ path: envPath });\n console.log(`[MoltsPay] Loaded config from ${envPath}`);\n break;\n }\n }\n } catch {\n // dotenv not installed, use process.env only\n }\n}\n\n/**\n * Get CDP configuration from environment\n */\nfunction getCDPConfig(): CDPConfig {\n loadEnvFiles();\n \n return {\n useMainnet: process.env.USE_MAINNET?.toLowerCase() === 'true',\n apiKeyId: process.env.CDP_API_KEY_ID,\n apiKeySecret: process.env.CDP_API_KEY_SECRET,\n };\n}\n\n/**\n * Generate CDP auth headers for API requests\n */\nasync function getCDPAuthHeaders(\n method: string,\n urlPath: string,\n body?: any\n): Promise<Record<string, string>> {\n const config = getCDPConfig();\n \n if (!config.apiKeyId || !config.apiKeySecret) {\n throw new Error('CDP_API_KEY_ID and CDP_API_KEY_SECRET required for mainnet');\n }\n \n try {\n // Import CDP SDK auth\n const { getAuthHeaders } = await import('@coinbase/cdp-sdk/auth');\n \n const headers = await getAuthHeaders({\n apiKeyId: config.apiKeyId,\n apiKeySecret: config.apiKeySecret,\n requestMethod: method,\n requestHost: 'api.cdp.coinbase.com',\n requestPath: urlPath,\n requestBody: body,\n });\n \n return headers;\n } catch (err: any) {\n console.error('[MoltsPay] Failed to generate CDP auth headers:', err.message);\n throw err;\n }\n}\n\nexport class MoltsPayServer {\n private manifest: ServicesManifest;\n private skills: Map<string, RegisteredSkill> = new Map();\n private options: MoltsPayServerOptions;\n private cdpConfig: CDPConfig;\n private facilitatorUrl: string;\n private networkId: string;\n\n constructor(servicesPath: string, options: MoltsPayServerOptions = {}) {\n // Load CDP config first\n this.cdpConfig = getCDPConfig();\n \n // Load services manifest\n const content = readFileSync(servicesPath, 'utf-8');\n this.manifest = JSON.parse(content) as ServicesManifest;\n \n this.options = {\n port: options.port || 3000,\n host: options.host || '0.0.0.0',\n };\n\n // Determine facilitator and network based on config\n if (this.cdpConfig.useMainnet) {\n if (!this.cdpConfig.apiKeyId || !this.cdpConfig.apiKeySecret) {\n console.warn('[MoltsPay] WARNING: USE_MAINNET=true but CDP keys not set!');\n console.warn('[MoltsPay] Set CDP_API_KEY_ID and CDP_API_KEY_SECRET in ~/.moltspay/.env');\n }\n this.facilitatorUrl = FACILITATOR_MAINNET;\n this.networkId = 'eip155:8453'; // Base mainnet\n } else {\n this.facilitatorUrl = options.facilitatorUrl || FACILITATOR_TESTNET;\n this.networkId = 'eip155:84532'; // Base Sepolia testnet\n }\n\n const networkName = this.cdpConfig.useMainnet ? 'Base mainnet' : 'Base Sepolia (testnet)';\n const facilitatorName = this.cdpConfig.useMainnet ? 'CDP' : 'x402.org';\n \n console.log(`[MoltsPay] Loaded ${this.manifest.services.length} services from ${servicesPath}`);\n console.log(`[MoltsPay] Provider: ${this.manifest.provider.name}`);\n console.log(`[MoltsPay] Receive wallet: ${this.manifest.provider.wallet}`);\n console.log(`[MoltsPay] Network: ${this.networkId} (${networkName})`);\n console.log(`[MoltsPay] Facilitator: ${facilitatorName} (${this.facilitatorUrl})`);\n if (this.cdpConfig.useMainnet && this.cdpConfig.apiKeyId) {\n console.log(`[MoltsPay] CDP API Key: ${this.cdpConfig.apiKeyId.slice(0, 8)}...`);\n }\n console.log(`[MoltsPay] Protocol: x402 (gasless for both client AND server)`);\n }\n\n /**\n * Register a skill handler for a service\n */\n skill(serviceId: string, handler: SkillFunction): this {\n const config = this.manifest.services.find(s => s.id === serviceId);\n if (!config) {\n throw new Error(`Service '${serviceId}' not found in manifest`);\n }\n this.skills.set(serviceId, { id: serviceId, config, handler });\n return this;\n }\n\n /**\n * Start HTTP server\n */\n listen(port?: number): void {\n const p = port || this.options.port || 3000;\n const host = this.options.host || '0.0.0.0';\n\n const server = createServer((req, res) => this.handleRequest(req, res));\n server.listen(p, host, () => {\n console.log(`[MoltsPay] Server listening on http://${host}:${p}`);\n console.log(`[MoltsPay] Endpoints:`);\n console.log(` GET /services - List available services`);\n console.log(` POST /execute - Execute service (x402 payment)`);\n });\n }\n\n /**\n * Handle incoming request\n */\n private async handleRequest(req: IncomingMessage, res: ServerResponse): Promise<void> {\n // CORS\n res.setHeader('Access-Control-Allow-Origin', '*');\n res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');\n res.setHeader('Access-Control-Allow-Headers', 'Content-Type, X-Payment');\n res.setHeader('Access-Control-Expose-Headers', 'X-Payment-Required, X-Payment-Response');\n\n if (req.method === 'OPTIONS') {\n res.writeHead(204);\n res.end();\n return;\n }\n\n try {\n const url = new URL(req.url || '/', `http://${req.headers.host}`);\n \n if (url.pathname === '/services' && req.method === 'GET') {\n return this.handleGetServices(res);\n }\n\n if (url.pathname === '/execute' && req.method === 'POST') {\n const body = await this.readBody(req);\n const paymentHeader = req.headers[PAYMENT_HEADER] as string | undefined;\n return await this.handleExecute(body, paymentHeader, res);\n }\n\n // 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 x402: {\n version: X402_VERSION,\n network: this.networkId,\n schemes: ['exact'],\n facilitator: this.cdpConfig.useMainnet ? 'cdp' : 'x402.org',\n mainnet: this.cdpConfig.useMainnet,\n },\n });\n }\n\n /**\n * POST /execute - Execute service with x402 payment\n */\n private async handleExecute(\n body: any,\n paymentHeader: string | undefined,\n res: ServerResponse\n ): Promise<void> {\n const { service, params } = body;\n\n if (!service) {\n return this.sendJson(res, 400, { error: 'Missing service' });\n }\n\n const skill = this.skills.get(service);\n if (!skill) {\n return this.sendJson(res, 404, { error: `Service '${service}' not found or not registered` });\n }\n\n // Validate required params\n for (const [key, field] of Object.entries(skill.config.input)) {\n if (field.required && (!params || params[key] === undefined)) {\n return this.sendJson(res, 400, { error: `Missing required param: ${key}` });\n }\n }\n\n // If no payment header, return 402 with payment requirements\n if (!paymentHeader) {\n return this.sendPaymentRequired(skill.config, res);\n }\n\n // Parse payment payload\n let payment: X402PaymentPayload;\n try {\n const decoded = Buffer.from(paymentHeader, 'base64').toString('utf-8');\n payment = JSON.parse(decoded);\n } catch {\n return this.sendJson(res, 400, { error: 'Invalid X-Payment header' });\n }\n\n // Validate basic payment fields\n const validation = this.validatePayment(payment, skill.config);\n if (!validation.valid) {\n return this.sendJson(res, 402, { error: validation.error });\n }\n\n // Verify payment with facilitator\n console.log(`[MoltsPay] Verifying payment with facilitator...`);\n const verifyResult = await this.verifyWithFacilitator(payment, skill.config);\n if (!verifyResult.valid) {\n return this.sendJson(res, 402, { error: `Payment verification failed: ${verifyResult.error}` });\n }\n\n // Execute skill FIRST (pay-for-success)\n console.log(`[MoltsPay] Executing skill: ${service}`);\n let result: any;\n try {\n result = await skill.handler(params || {});\n } catch (err: any) {\n console.error('[MoltsPay] Skill execution failed:', err.message);\n return this.sendJson(res, 500, {\n error: 'Service execution failed',\n message: err.message,\n });\n }\n\n // Skill succeeded - now settle payment with facilitator\n console.log(`[MoltsPay] Skill succeeded, settling payment...`);\n let settlement: any = null;\n try {\n settlement = await this.settleWithFacilitator(payment, skill.config);\n console.log(`[MoltsPay] Payment settled: ${settlement.transaction || 'pending'}`);\n } catch (err: any) {\n console.error('[MoltsPay] Settlement failed:', err.message);\n }\n\n // Build response\n const responseHeaders: Record<string, string> = {};\n if (settlement) {\n const responsePayload = {\n success: true,\n transaction: settlement.transaction,\n network: payment.network,\n };\n responseHeaders[PAYMENT_RESPONSE_HEADER] = Buffer.from(\n JSON.stringify(responsePayload)\n ).toString('base64');\n }\n\n this.sendJson(res, 200, {\n success: true,\n result,\n payment: settlement \n ? { transaction: settlement.transaction, status: 'settled' }\n : { status: 'pending' },\n }, responseHeaders);\n }\n\n /**\n * Return 402 with x402 payment requirements\n */\n private sendPaymentRequired(config: ServiceConfig, res: ServerResponse): void {\n const amountInUnits = Math.floor(config.price * 1e6).toString();\n\n const requirements = [{\n scheme: 'exact',\n network: this.networkId,\n maxAmountRequired: amountInUnits,\n resource: this.manifest.provider.wallet,\n description: `${config.name} - $${config.price} ${config.currency}`,\n extra: JSON.stringify({ \n facilitator: this.cdpConfig.useMainnet ? 'cdp' : 'x402.org',\n mainnet: this.cdpConfig.useMainnet,\n }),\n }];\n\n const encoded = Buffer.from(JSON.stringify(requirements)).toString('base64');\n\n res.writeHead(402, {\n 'Content-Type': 'application/json',\n [PAYMENT_REQUIRED_HEADER]: encoded,\n });\n res.end(JSON.stringify({\n error: 'Payment required',\n message: `Service requires $${config.price} ${config.currency}`,\n x402: requirements[0],\n }, null, 2));\n }\n\n /**\n * Basic payment validation\n */\n private validatePayment(\n payment: X402PaymentPayload,\n config: ServiceConfig\n ): { valid: boolean; error?: string } {\n if (payment.x402Version !== X402_VERSION) {\n return { valid: false, error: `Unsupported x402 version: ${payment.x402Version}` };\n }\n\n if (payment.scheme !== 'exact') {\n return { valid: false, error: `Unsupported scheme: ${payment.scheme}` };\n }\n\n if (payment.network !== this.networkId) {\n return { valid: false, error: `Network mismatch: expected ${this.networkId}, got ${payment.network}` };\n }\n\n return { valid: true };\n }\n\n /**\n * Verify payment with facilitator (testnet or CDP)\n */\n private async verifyWithFacilitator(\n payment: X402PaymentPayload,\n config: ServiceConfig\n ): Promise<{ valid: boolean; error?: string }> {\n try {\n const amountInUnits = Math.floor(config.price * 1e6).toString();\n\n const requirements = {\n scheme: 'exact',\n network: this.networkId,\n maxAmountRequired: amountInUnits,\n resource: this.manifest.provider.wallet,\n payTo: this.manifest.provider.wallet,\n };\n\n const requestBody = {\n paymentPayload: payment,\n paymentRequirements: requirements,\n };\n\n // Build headers\n let headers: Record<string, string> = { 'Content-Type': 'application/json' };\n \n if (this.cdpConfig.useMainnet) {\n // Add CDP auth headers for mainnet\n const authHeaders = await getCDPAuthHeaders(\n 'POST',\n '/platform/v2/x402/verify',\n requestBody\n );\n headers = { ...headers, ...authHeaders };\n }\n\n const response = await fetch(`${this.facilitatorUrl}/verify`, {\n method: 'POST',\n headers,\n body: JSON.stringify(requestBody),\n });\n\n const result = await response.json() as any;\n\n if (!response.ok || !result.isValid) {\n return { valid: false, error: result.invalidReason || result.error || 'Verification failed' };\n }\n\n return { valid: true };\n } catch (err: any) {\n return { valid: false, error: `Facilitator error: ${err.message}` };\n }\n }\n\n /**\n * Settle payment with facilitator (execute on-chain transfer)\n */\n private async settleWithFacilitator(\n payment: X402PaymentPayload,\n config: ServiceConfig\n ): Promise<{ transaction?: string; status: string }> {\n const amountInUnits = Math.floor(config.price * 1e6).toString();\n\n const requirements = {\n scheme: 'exact',\n network: this.networkId,\n maxAmountRequired: amountInUnits,\n resource: this.manifest.provider.wallet,\n payTo: this.manifest.provider.wallet,\n };\n\n const requestBody = {\n paymentPayload: payment,\n paymentRequirements: requirements,\n };\n\n // Build headers\n let headers: Record<string, string> = { 'Content-Type': 'application/json' };\n \n if (this.cdpConfig.useMainnet) {\n // Add CDP auth headers for mainnet\n const authHeaders = await getCDPAuthHeaders(\n 'POST',\n '/platform/v2/x402/settle',\n requestBody\n );\n headers = { ...headers, ...authHeaders };\n }\n\n const response = await fetch(`${this.facilitatorUrl}/settle`, {\n method: 'POST',\n headers,\n body: JSON.stringify(requestBody),\n });\n\n const result = await response.json() as any;\n\n if (!response.ok || !result.success) {\n throw new Error(result.error || result.errorReason || 'Settlement failed');\n }\n\n return {\n transaction: result.transaction,\n status: result.status || 'settled',\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(\n res: ServerResponse, \n status: number, \n data: any,\n extraHeaders?: Record<string, string>\n ): void {\n const headers: Record<string, string> = { 'Content-Type': 'application/json' };\n if (extraHeaders) {\n Object.assign(headers, extraHeaders);\n }\n res.writeHead(status, headers);\n res.end(JSON.stringify(data, null, 2));\n }\n}\n"],"mappings":"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","names":["import_os","import_path","import_fs","import_fs","X402_VERSION","PAYMENT_REQUIRED_HEADER","PAYMENT_HEADER","resolve","resolve"]}