moltspay 0.9.3 → 0.9.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/.env.example +7 -0
  2. package/dist/cdp/index.d.mts +1 -1
  3. package/dist/cdp/index.d.ts +1 -1
  4. package/dist/cdp/index.js +63 -0
  5. package/dist/cdp/index.js.map +1 -1
  6. package/dist/cdp/index.mjs +63 -0
  7. package/dist/cdp/index.mjs.map +1 -1
  8. package/dist/chains/index.d.mts +9 -5
  9. package/dist/chains/index.d.ts +9 -5
  10. package/dist/chains/index.js +85 -0
  11. package/dist/chains/index.js.map +1 -1
  12. package/dist/chains/index.mjs +83 -0
  13. package/dist/chains/index.mjs.map +1 -1
  14. package/dist/cli/index.js +234 -41
  15. package/dist/cli/index.js.map +1 -1
  16. package/dist/cli/index.mjs +234 -41
  17. package/dist/cli/index.mjs.map +1 -1
  18. package/dist/client/index.d.mts +18 -3
  19. package/dist/client/index.d.ts +18 -3
  20. package/dist/client/index.js +102 -15
  21. package/dist/client/index.js.map +1 -1
  22. package/dist/client/index.mjs +102 -15
  23. package/dist/client/index.mjs.map +1 -1
  24. package/dist/{index-Dg8n6wdW.d.mts → index-B3v8IWjM.d.mts} +11 -1
  25. package/dist/{index-Dg8n6wdW.d.ts → index-B3v8IWjM.d.ts} +11 -1
  26. package/dist/index.d.mts +1 -1
  27. package/dist/index.d.ts +1 -1
  28. package/dist/index.js +248 -45
  29. package/dist/index.js.map +1 -1
  30. package/dist/index.mjs +248 -45
  31. package/dist/index.mjs.map +1 -1
  32. package/dist/server/index.d.mts +23 -1
  33. package/dist/server/index.d.ts +23 -1
  34. package/dist/server/index.js +126 -22
  35. package/dist/server/index.js.map +1 -1
  36. package/dist/server/index.mjs +126 -22
  37. package/dist/server/index.mjs.map +1 -1
  38. package/dist/verify/index.d.mts +7 -0
  39. package/dist/verify/index.d.ts +7 -0
  40. package/dist/verify/index.js +83 -8
  41. package/dist/verify/index.js.map +1 -1
  42. package/dist/verify/index.mjs +83 -8
  43. package/dist/verify/index.mjs.map +1 -1
  44. package/dist/wallet/index.d.mts +16 -8
  45. package/dist/wallet/index.d.ts +16 -8
  46. package/dist/wallet/index.js +114 -18
  47. package/dist/wallet/index.js.map +1 -1
  48. package/dist/wallet/index.mjs +114 -18
  49. package/dist/wallet/index.mjs.map +1 -1
  50. package/package.json +1 -1
  51. package/schemas/moltspay.services.schema.json +13 -3
@@ -3,12 +3,19 @@ import { d as FacilitatorSelection } from '../registry-OsEO2dOu.mjs';
3
3
  /**
4
4
  * MoltsPay Server Types
5
5
  */
6
+ type TokenSymbol = 'USDC' | 'USDT';
6
7
  interface ServiceConfig {
7
8
  id: string;
8
9
  name: string;
9
10
  description?: string;
10
11
  price: number;
11
12
  currency: string;
13
+ /**
14
+ * Tokens accepted for payment (optional).
15
+ * If not specified, defaults to [currency].
16
+ * Example: ["USDC", "USDT"]
17
+ */
18
+ acceptedCurrencies?: TokenSymbol[];
12
19
  input: Record<string, InputField>;
13
20
  output: Record<string, OutputField>;
14
21
  /** Shell command to execute for this service. Params passed as JSON to stdin. */
@@ -120,6 +127,10 @@ declare class MoltsPayServer {
120
127
  * Handle incoming request
121
128
  */
122
129
  private handleRequest;
130
+ /**
131
+ * GET /.well-known/agent-services.json - Standard discovery endpoint
132
+ */
133
+ private handleAgentServicesDiscovery;
123
134
  /**
124
135
  * GET /services - List available services
125
136
  */
@@ -134,6 +145,7 @@ declare class MoltsPayServer {
134
145
  private handleExecute;
135
146
  /**
136
147
  * Return 402 with x402 payment requirements (v2 format)
148
+ * Includes requirements for all accepted currencies
137
149
  */
138
150
  private sendPaymentRequired;
139
151
  /**
@@ -142,8 +154,18 @@ declare class MoltsPayServer {
142
154
  private validatePayment;
143
155
  /**
144
156
  * Build payment requirements for facilitator
157
+ * Returns requirements for the primary currency (USDC by default)
158
+ * Server accepts any of the acceptedCurrencies
145
159
  */
146
160
  private buildPaymentRequirements;
161
+ /**
162
+ * Detect which token is being used in the payment
163
+ */
164
+ private detectPaymentToken;
165
+ /**
166
+ * Check if payment token is accepted for service
167
+ */
168
+ private isTokenAccepted;
147
169
  private readBody;
148
170
  private sendJson;
149
171
  /**
@@ -173,4 +195,4 @@ declare class MoltsPayServer {
173
195
  private sendProxyPaymentRequired;
174
196
  }
175
197
 
176
- export { type Charge, type ChargeStatus, type InputField, MoltsPayServer, type MoltsPayServerOptions, type MoltsPayServerOptionsExtended, type OutputField, type PaymentRequest, type ProviderConfig, type RegisteredSkill, type ServiceConfig, type ServicesManifest, type SkillFunction, type VerifyRequest };
198
+ export { type Charge, type ChargeStatus, type InputField, MoltsPayServer, type MoltsPayServerOptions, type MoltsPayServerOptionsExtended, type OutputField, type PaymentRequest, type ProviderConfig, type RegisteredSkill, type ServiceConfig, type ServicesManifest, type SkillFunction, type TokenSymbol, type VerifyRequest };
@@ -3,12 +3,19 @@ import { d as FacilitatorSelection } from '../registry-OsEO2dOu.js';
3
3
  /**
4
4
  * MoltsPay Server Types
5
5
  */
6
+ type TokenSymbol = 'USDC' | 'USDT';
6
7
  interface ServiceConfig {
7
8
  id: string;
8
9
  name: string;
9
10
  description?: string;
10
11
  price: number;
11
12
  currency: string;
13
+ /**
14
+ * Tokens accepted for payment (optional).
15
+ * If not specified, defaults to [currency].
16
+ * Example: ["USDC", "USDT"]
17
+ */
18
+ acceptedCurrencies?: TokenSymbol[];
12
19
  input: Record<string, InputField>;
13
20
  output: Record<string, OutputField>;
14
21
  /** Shell command to execute for this service. Params passed as JSON to stdin. */
@@ -120,6 +127,10 @@ declare class MoltsPayServer {
120
127
  * Handle incoming request
121
128
  */
122
129
  private handleRequest;
130
+ /**
131
+ * GET /.well-known/agent-services.json - Standard discovery endpoint
132
+ */
133
+ private handleAgentServicesDiscovery;
123
134
  /**
124
135
  * GET /services - List available services
125
136
  */
@@ -134,6 +145,7 @@ declare class MoltsPayServer {
134
145
  private handleExecute;
135
146
  /**
136
147
  * Return 402 with x402 payment requirements (v2 format)
148
+ * Includes requirements for all accepted currencies
137
149
  */
138
150
  private sendPaymentRequired;
139
151
  /**
@@ -142,8 +154,18 @@ declare class MoltsPayServer {
142
154
  private validatePayment;
143
155
  /**
144
156
  * Build payment requirements for facilitator
157
+ * Returns requirements for the primary currency (USDC by default)
158
+ * Server accepts any of the acceptedCurrencies
145
159
  */
146
160
  private buildPaymentRequirements;
161
+ /**
162
+ * Detect which token is being used in the payment
163
+ */
164
+ private detectPaymentToken;
165
+ /**
166
+ * Check if payment token is accepted for service
167
+ */
168
+ private isTokenAccepted;
147
169
  private readBody;
148
170
  private sendJson;
149
171
  /**
@@ -173,4 +195,4 @@ declare class MoltsPayServer {
173
195
  private sendProxyPaymentRequired;
174
196
  }
175
197
 
176
- export { type Charge, type ChargeStatus, type InputField, MoltsPayServer, type MoltsPayServerOptions, type MoltsPayServerOptionsExtended, type OutputField, type PaymentRequest, type ProviderConfig, type RegisteredSkill, type ServiceConfig, type ServicesManifest, type SkillFunction, type VerifyRequest };
198
+ export { type Charge, type ChargeStatus, type InputField, MoltsPayServer, type MoltsPayServerOptions, type MoltsPayServerOptionsExtended, type OutputField, type PaymentRequest, type ProviderConfig, type RegisteredSkill, type ServiceConfig, type ServicesManifest, type SkillFunction, type TokenSymbol, type VerifyRequest };
@@ -486,16 +486,24 @@ var X402_VERSION2 = 2;
486
486
  var PAYMENT_REQUIRED_HEADER = "x-payment-required";
487
487
  var PAYMENT_HEADER = "x-payment";
488
488
  var PAYMENT_RESPONSE_HEADER = "x-payment-response";
489
- var USDC_ADDRESSES = {
490
- "eip155:8453": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
491
- // Base mainnet
492
- "eip155:84532": "0x036CbD53842c5426634e7929541eC2318f3dCF7e"
493
- // Base Sepolia
489
+ var TOKEN_ADDRESSES = {
490
+ "eip155:8453": {
491
+ USDC: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
492
+ USDT: "0xfde4C96c8593536E31F229EA8f37b2ADa2699bb2"
493
+ },
494
+ "eip155:84532": {
495
+ USDC: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
496
+ USDT: "0x036CbD53842c5426634e7929541eC2318f3dCF7e"
497
+ // Same as USDC on testnet
498
+ }
494
499
  };
495
- var USDC_DOMAIN = {
496
- name: "USD Coin",
497
- version: "2"
500
+ var TOKEN_DOMAINS = {
501
+ USDC: { name: "USD Coin", version: "2" },
502
+ USDT: { name: "Tether USD", version: "2" }
498
503
  };
504
+ function getAcceptedCurrencies(config) {
505
+ return config.acceptedCurrencies ?? [config.currency];
506
+ }
499
507
  function loadEnvFile2() {
500
508
  const envPaths = [
501
509
  path2.join(process.cwd(), ".env"),
@@ -607,6 +615,9 @@ var MoltsPayServer = class {
607
615
  if (url.pathname === "/services" && req.method === "GET") {
608
616
  return this.handleGetServices(res);
609
617
  }
618
+ if (url.pathname === "/.well-known/agent-services.json" && req.method === "GET") {
619
+ return this.handleAgentServicesDiscovery(res);
620
+ }
610
621
  if (url.pathname === "/health" && req.method === "GET") {
611
622
  return await this.handleHealthCheck(res);
612
623
  }
@@ -630,6 +641,44 @@ var MoltsPayServer = class {
630
641
  this.sendJson(res, 500, { error: err.message || "Internal error" });
631
642
  }
632
643
  }
644
+ /**
645
+ * GET /.well-known/agent-services.json - Standard discovery endpoint
646
+ */
647
+ handleAgentServicesDiscovery(res) {
648
+ const services = this.manifest.services.map((s) => ({
649
+ id: s.id,
650
+ name: s.name,
651
+ description: s.description,
652
+ price: s.price,
653
+ currency: s.currency,
654
+ acceptedCurrencies: getAcceptedCurrencies(s),
655
+ input: s.input,
656
+ output: s.output,
657
+ available: this.skills.has(s.id)
658
+ }));
659
+ this.sendJson(res, 200, {
660
+ version: "1.0",
661
+ provider: {
662
+ name: this.manifest.provider.name,
663
+ description: this.manifest.provider.description,
664
+ wallet: this.manifest.provider.wallet,
665
+ chain: this.manifest.provider.chain || "base"
666
+ },
667
+ services,
668
+ endpoints: {
669
+ services: "/services",
670
+ execute: "/execute",
671
+ health: "/health"
672
+ },
673
+ payment: {
674
+ protocol: "x402",
675
+ version: X402_VERSION2,
676
+ network: this.networkId,
677
+ schemes: ["exact"],
678
+ mainnet: this.useMainnet
679
+ }
680
+ });
681
+ }
633
682
  /**
634
683
  * GET /services - List available services
635
684
  */
@@ -640,6 +689,7 @@ var MoltsPayServer = class {
640
689
  description: s.description,
641
690
  price: s.price,
642
691
  currency: s.currency,
692
+ acceptedCurrencies: getAcceptedCurrencies(s),
643
693
  input: s.input,
644
694
  output: s.output,
645
695
  available: this.skills.has(s.id)
@@ -706,7 +756,14 @@ var MoltsPayServer = class {
706
756
  if (!validation.valid) {
707
757
  return this.sendJson(res, 402, { error: validation.error });
708
758
  }
709
- const requirements = this.buildPaymentRequirements(skill.config);
759
+ const paymentToken = this.detectPaymentToken(payment);
760
+ if (paymentToken && !this.isTokenAccepted(skill.config, paymentToken)) {
761
+ const accepted = getAcceptedCurrencies(skill.config);
762
+ return this.sendJson(res, 402, {
763
+ error: `Token ${paymentToken} not accepted. Accepted: ${accepted.join(", ")}`
764
+ });
765
+ }
766
+ const requirements = this.buildPaymentRequirements(skill.config, paymentToken);
710
767
  console.log(`[MoltsPay] Verifying payment...`);
711
768
  const verifyResult = await this.registry.verify(payment, requirements);
712
769
  if (!verifyResult.valid) {
@@ -716,10 +773,16 @@ var MoltsPayServer = class {
716
773
  });
717
774
  }
718
775
  console.log(`[MoltsPay] Verified by ${verifyResult.facilitator}`);
719
- console.log(`[MoltsPay] Executing skill: ${service}`);
776
+ const timeoutSeconds = parseInt(process.env.SKILL_TIMEOUT_SECONDS || "1200");
777
+ console.log(`[MoltsPay] Executing skill: ${service} (timeout: ${timeoutSeconds}s)`);
720
778
  let result;
721
779
  try {
722
- result = await skill.handler(params || {});
780
+ result = await Promise.race([
781
+ skill.handler(params || {}),
782
+ new Promise(
783
+ (_, reject) => setTimeout(() => reject(new Error(`Skill timeout after ${timeoutSeconds}s`)), timeoutSeconds * 1e3)
784
+ )
785
+ ]);
723
786
  } catch (err) {
724
787
  console.error("[MoltsPay] Skill execution failed:", err.message);
725
788
  return this.sendJson(res, 500, {
@@ -755,12 +818,15 @@ var MoltsPayServer = class {
755
818
  }
756
819
  /**
757
820
  * Return 402 with x402 payment requirements (v2 format)
821
+ * Includes requirements for all accepted currencies
758
822
  */
759
823
  sendPaymentRequired(config, res) {
760
- const requirements = this.buildPaymentRequirements(config);
824
+ const acceptedTokens = getAcceptedCurrencies(config);
825
+ const accepts = acceptedTokens.map((token) => this.buildPaymentRequirements(config, token));
761
826
  const paymentRequired = {
762
827
  x402Version: X402_VERSION2,
763
- accepts: [requirements],
828
+ accepts,
829
+ acceptedCurrencies: acceptedTokens,
764
830
  resource: {
765
831
  url: `/execute?service=${config.id}`,
766
832
  description: `${config.name} - $${config.price} ${config.currency}`,
@@ -775,6 +841,7 @@ var MoltsPayServer = class {
775
841
  res.end(JSON.stringify({
776
842
  error: "Payment required",
777
843
  message: `Service requires $${config.price} ${config.currency}`,
844
+ acceptedCurrencies: acceptedTokens,
778
845
  x402: paymentRequired
779
846
  }, null, 2));
780
847
  }
@@ -797,20 +864,47 @@ var MoltsPayServer = class {
797
864
  }
798
865
  /**
799
866
  * Build payment requirements for facilitator
867
+ * Returns requirements for the primary currency (USDC by default)
868
+ * Server accepts any of the acceptedCurrencies
800
869
  */
801
- buildPaymentRequirements(config) {
870
+ buildPaymentRequirements(config, token) {
802
871
  const amountInUnits = Math.floor(config.price * 1e6).toString();
803
- const usdcAddress = USDC_ADDRESSES[this.networkId];
872
+ const acceptedTokens = getAcceptedCurrencies(config);
873
+ const selectedToken = token && acceptedTokens.includes(token) ? token : acceptedTokens[0];
874
+ const tokenAddresses = TOKEN_ADDRESSES[this.networkId] || {};
875
+ const tokenAddress = tokenAddresses[selectedToken];
876
+ const tokenDomain = TOKEN_DOMAINS[selectedToken] || TOKEN_DOMAINS.USDC;
804
877
  return {
805
878
  scheme: "exact",
806
879
  network: this.networkId,
807
- asset: usdcAddress,
880
+ asset: tokenAddress,
808
881
  amount: amountInUnits,
809
882
  payTo: this.manifest.provider.wallet,
810
883
  maxTimeoutSeconds: 300,
811
- extra: USDC_DOMAIN
884
+ extra: tokenDomain
812
885
  };
813
886
  }
887
+ /**
888
+ * Detect which token is being used in the payment
889
+ */
890
+ detectPaymentToken(payment) {
891
+ const asset = payment.accepted?.asset || payment.payload?.asset;
892
+ if (!asset) return void 0;
893
+ const tokenAddresses = TOKEN_ADDRESSES[this.networkId] || {};
894
+ for (const [symbol, address] of Object.entries(tokenAddresses)) {
895
+ if (address.toLowerCase() === asset.toLowerCase()) {
896
+ return symbol;
897
+ }
898
+ }
899
+ return void 0;
900
+ }
901
+ /**
902
+ * Check if payment token is accepted for service
903
+ */
904
+ isTokenAccepted(config, token) {
905
+ const accepted = getAcceptedCurrencies(config);
906
+ return accepted.includes(token);
907
+ }
814
908
  async readBody(req) {
815
909
  return new Promise((resolve, reject) => {
816
910
  let body = "";
@@ -928,9 +1022,15 @@ var MoltsPayServer = class {
928
1022
  error: `Service not found: ${service}`
929
1023
  });
930
1024
  }
1025
+ const timeoutSeconds = parseInt(process.env.SKILL_TIMEOUT_SECONDS || "1200");
931
1026
  let result;
932
1027
  try {
933
- result = await skill.handler(params || {});
1028
+ result = await Promise.race([
1029
+ skill.handler(params || {}),
1030
+ new Promise(
1031
+ (_, reject) => setTimeout(() => reject(new Error(`Skill timeout after ${timeoutSeconds}s`)), timeoutSeconds * 1e3)
1032
+ )
1033
+ ]);
934
1034
  console.log(`[MoltsPay] /proxy: Skill succeeded, now settling payment...`);
935
1035
  } catch (err) {
936
1036
  console.error(`[MoltsPay] /proxy: Skill failed: ${err.message} - NOT settling`);
@@ -1004,18 +1104,22 @@ var MoltsPayServer = class {
1004
1104
  /**
1005
1105
  * Build payment requirements for proxy endpoint (uses provided wallet)
1006
1106
  */
1007
- buildProxyPaymentRequirements(config, wallet) {
1107
+ buildProxyPaymentRequirements(config, wallet, token) {
1008
1108
  const amountInUnits = Math.floor(config.price * 1e6).toString();
1009
- const usdcAddress = USDC_ADDRESSES[this.networkId];
1109
+ const acceptedTokens = getAcceptedCurrencies(config);
1110
+ const selectedToken = token && acceptedTokens.includes(token) ? token : acceptedTokens[0];
1111
+ const tokenAddresses = TOKEN_ADDRESSES[this.networkId] || {};
1112
+ const tokenAddress = tokenAddresses[selectedToken];
1113
+ const tokenDomain = TOKEN_DOMAINS[selectedToken] || TOKEN_DOMAINS.USDC;
1010
1114
  return {
1011
1115
  scheme: "exact",
1012
1116
  network: this.networkId,
1013
- asset: usdcAddress,
1117
+ asset: tokenAddress,
1014
1118
  amount: amountInUnits,
1015
1119
  payTo: wallet,
1016
1120
  // Use provided wallet, not manifest
1017
1121
  maxTimeoutSeconds: 300,
1018
- extra: USDC_DOMAIN
1122
+ extra: tokenDomain
1019
1123
  };
1020
1124
  }
1021
1125
  /**