moltspay 0.9.2 → 0.9.5

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 CHANGED
@@ -23,6 +23,13 @@ FACILITATOR_PRIMARY=cdp
23
23
  # Options: failover | cheapest | fastest | random | roundrobin
24
24
  FACILITATOR_STRATEGY=failover
25
25
 
26
+ # ===========================================
27
+ # Skill Execution (v0.9.4+)
28
+ # ===========================================
29
+ # Timeout for skill execution in seconds (default: 1200 = 20 minutes)
30
+ # Prevents hung skills from blocking requests forever
31
+ SKILL_TIMEOUT_SECONDS=1200
32
+
26
33
  # ===========================================
27
34
  # Proxy Endpoint (v0.9.2+)
28
35
  # ===========================================
package/dist/cli/index.js CHANGED
@@ -1007,6 +1007,9 @@ var MoltsPayServer = class {
1007
1007
  if (url.pathname === "/services" && req.method === "GET") {
1008
1008
  return this.handleGetServices(res);
1009
1009
  }
1010
+ if (url.pathname === "/.well-known/agent-services.json" && req.method === "GET") {
1011
+ return this.handleAgentServicesDiscovery(res);
1012
+ }
1010
1013
  if (url.pathname === "/health" && req.method === "GET") {
1011
1014
  return await this.handleHealthCheck(res);
1012
1015
  }
@@ -1030,6 +1033,43 @@ var MoltsPayServer = class {
1030
1033
  this.sendJson(res, 500, { error: err.message || "Internal error" });
1031
1034
  }
1032
1035
  }
1036
+ /**
1037
+ * GET /.well-known/agent-services.json - Standard discovery endpoint
1038
+ */
1039
+ handleAgentServicesDiscovery(res) {
1040
+ const services = this.manifest.services.map((s) => ({
1041
+ id: s.id,
1042
+ name: s.name,
1043
+ description: s.description,
1044
+ price: s.price,
1045
+ currency: s.currency,
1046
+ input: s.input,
1047
+ output: s.output,
1048
+ available: this.skills.has(s.id)
1049
+ }));
1050
+ this.sendJson(res, 200, {
1051
+ version: "1.0",
1052
+ provider: {
1053
+ name: this.manifest.provider.name,
1054
+ description: this.manifest.provider.description,
1055
+ wallet: this.manifest.provider.wallet,
1056
+ chain: this.manifest.provider.chain || "base"
1057
+ },
1058
+ services,
1059
+ endpoints: {
1060
+ services: "/services",
1061
+ execute: "/execute",
1062
+ health: "/health"
1063
+ },
1064
+ payment: {
1065
+ protocol: "x402",
1066
+ version: X402_VERSION3,
1067
+ network: this.networkId,
1068
+ schemes: ["exact"],
1069
+ mainnet: this.useMainnet
1070
+ }
1071
+ });
1072
+ }
1033
1073
  /**
1034
1074
  * GET /services - List available services
1035
1075
  */
@@ -1116,10 +1156,16 @@ var MoltsPayServer = class {
1116
1156
  });
1117
1157
  }
1118
1158
  console.log(`[MoltsPay] Verified by ${verifyResult.facilitator}`);
1119
- console.log(`[MoltsPay] Executing skill: ${service}`);
1159
+ const timeoutSeconds = parseInt(process.env.SKILL_TIMEOUT_SECONDS || "1200");
1160
+ console.log(`[MoltsPay] Executing skill: ${service} (timeout: ${timeoutSeconds}s)`);
1120
1161
  let result;
1121
1162
  try {
1122
- result = await skill.handler(params || {});
1163
+ result = await Promise.race([
1164
+ skill.handler(params || {}),
1165
+ new Promise(
1166
+ (_, reject) => setTimeout(() => reject(new Error(`Skill timeout after ${timeoutSeconds}s`)), timeoutSeconds * 1e3)
1167
+ )
1168
+ ]);
1123
1169
  } catch (err) {
1124
1170
  console.error("[MoltsPay] Skill execution failed:", err.message);
1125
1171
  return this.sendJson(res, 500, {
@@ -1316,7 +1362,72 @@ var MoltsPayServer = class {
1316
1362
  });
1317
1363
  }
1318
1364
  console.log(`[MoltsPay] /proxy: Verified by ${verifyResult.facilitator}`);
1319
- console.log(`[MoltsPay] /proxy: Settling payment...`);
1365
+ const { execute, service, params } = body;
1366
+ if (execute && service) {
1367
+ console.log(`[MoltsPay] /proxy: Executing skill first (pay on success): ${service}`);
1368
+ const skill = this.skills.get(service);
1369
+ if (!skill) {
1370
+ console.log(`[MoltsPay] /proxy: Service not found: ${service} - NOT settling`);
1371
+ return this.sendJson(res, 404, {
1372
+ success: false,
1373
+ paymentSettled: false,
1374
+ error: `Service not found: ${service}`
1375
+ });
1376
+ }
1377
+ const timeoutSeconds = parseInt(process.env.SKILL_TIMEOUT_SECONDS || "1200");
1378
+ let result;
1379
+ try {
1380
+ result = await Promise.race([
1381
+ skill.handler(params || {}),
1382
+ new Promise(
1383
+ (_, reject) => setTimeout(() => reject(new Error(`Skill timeout after ${timeoutSeconds}s`)), timeoutSeconds * 1e3)
1384
+ )
1385
+ ]);
1386
+ console.log(`[MoltsPay] /proxy: Skill succeeded, now settling payment...`);
1387
+ } catch (err) {
1388
+ console.error(`[MoltsPay] /proxy: Skill failed: ${err.message} - NOT settling`);
1389
+ return this.sendJson(res, 500, {
1390
+ success: false,
1391
+ paymentSettled: false,
1392
+ error: `Service execution failed: ${err.message}`
1393
+ });
1394
+ }
1395
+ let settlement2 = null;
1396
+ try {
1397
+ settlement2 = await this.registry.settle(payment, requirements);
1398
+ console.log(`[MoltsPay] /proxy: Payment settled by ${settlement2.facilitator}: ${settlement2.transaction || "pending"}`);
1399
+ } catch (err) {
1400
+ console.error("[MoltsPay] /proxy: Settlement failed:", err.message);
1401
+ return this.sendJson(res, 200, {
1402
+ success: true,
1403
+ verified: true,
1404
+ settled: false,
1405
+ settlementError: err.message,
1406
+ from: payment.payload?.authorization?.from,
1407
+ // Buyer's wallet address
1408
+ paidTo: wallet,
1409
+ amount: amountNum,
1410
+ currency: currency || "USDC",
1411
+ memo,
1412
+ result
1413
+ });
1414
+ }
1415
+ return this.sendJson(res, 200, {
1416
+ success: true,
1417
+ verified: true,
1418
+ settled: settlement2?.success || false,
1419
+ txHash: settlement2?.transaction,
1420
+ from: payment.payload?.authorization?.from,
1421
+ // Buyer's wallet address
1422
+ paidTo: wallet,
1423
+ amount: amountNum,
1424
+ currency: currency || "USDC",
1425
+ facilitator: settlement2?.facilitator,
1426
+ memo,
1427
+ result
1428
+ });
1429
+ }
1430
+ console.log(`[MoltsPay] /proxy: Settling payment (no execution)...`);
1320
1431
  let settlement = null;
1321
1432
  try {
1322
1433
  settlement = await this.registry.settle(payment, requirements);
@@ -1333,6 +1444,8 @@ var MoltsPayServer = class {
1333
1444
  verified: true,
1334
1445
  settled: settlement?.success || false,
1335
1446
  txHash: settlement?.transaction,
1447
+ from: payment.payload?.authorization?.from,
1448
+ // Buyer's wallet address
1336
1449
  paidTo: wallet,
1337
1450
  amount: amountNum,
1338
1451
  currency: currency || "USDC",