moltspay 0.9.7 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/README.md +42 -3
  2. package/dist/cdp/index.js +1 -1
  3. package/dist/cdp/index.js.map +1 -1
  4. package/dist/cdp/index.mjs +1 -1
  5. package/dist/cdp/index.mjs.map +1 -1
  6. package/dist/chains/index.js +1 -1
  7. package/dist/chains/index.js.map +1 -1
  8. package/dist/chains/index.mjs +1 -1
  9. package/dist/chains/index.mjs.map +1 -1
  10. package/dist/cli/index.js +5028 -109
  11. package/dist/cli/index.js.map +1 -1
  12. package/dist/cli/index.mjs +5019 -96
  13. package/dist/cli/index.mjs.map +1 -1
  14. package/dist/client/index.d.mts +18 -3
  15. package/dist/client/index.d.ts +18 -3
  16. package/dist/client/index.js +89 -10
  17. package/dist/client/index.js.map +1 -1
  18. package/dist/client/index.mjs +89 -10
  19. package/dist/client/index.mjs.map +1 -1
  20. package/dist/facilitators/index.js +1 -1
  21. package/dist/facilitators/index.js.map +1 -1
  22. package/dist/facilitators/index.mjs +1 -1
  23. package/dist/facilitators/index.mjs.map +1 -1
  24. package/dist/index.js +193 -36
  25. package/dist/index.js.map +1 -1
  26. package/dist/index.mjs +193 -36
  27. package/dist/index.mjs.map +1 -1
  28. package/dist/server/index.d.mts +25 -5
  29. package/dist/server/index.d.ts +25 -5
  30. package/dist/server/index.js +104 -26
  31. package/dist/server/index.js.map +1 -1
  32. package/dist/server/index.mjs +104 -26
  33. package/dist/server/index.mjs.map +1 -1
  34. package/dist/verify/index.js +1 -1
  35. package/dist/verify/index.js.map +1 -1
  36. package/dist/verify/index.mjs +1 -1
  37. package/dist/verify/index.mjs.map +1 -1
  38. package/dist/wallet/index.js +1 -1
  39. package/dist/wallet/index.js.map +1 -1
  40. package/dist/wallet/index.mjs +1 -1
  41. package/dist/wallet/index.mjs.map +1 -1
  42. package/package.json +3 -2
  43. package/schemas/moltspay.services.schema.json +58 -2
@@ -60,7 +60,7 @@ var CDPFacilitator = class extends BaseFacilitator {
60
60
  this.apiKeyId = config.apiKeyId || process.env.CDP_API_KEY_ID;
61
61
  this.apiKeySecret = config.apiKeySecret || process.env.CDP_API_KEY_SECRET;
62
62
  this.endpoint = this.useMainnet ? CDP_MAINNET_URL : CDP_TESTNET_URL;
63
- this.supportedNetworks = this.useMainnet ? ["eip155:8453"] : ["eip155:8453", "eip155:84532"];
63
+ this.supportedNetworks = this.useMainnet ? ["eip155:8453", "eip155:137"] : ["eip155:8453", "eip155:84532", "eip155:137"];
64
64
  if (this.useMainnet && (!this.apiKeyId || !this.apiKeySecret)) {
65
65
  console.warn("[CDPFacilitator] WARNING: Mainnet mode but missing CDP credentials!");
66
66
  console.warn("[CDPFacilitator] Set CDP_API_KEY_ID and CDP_API_KEY_SECRET");
@@ -461,8 +461,17 @@ var TOKEN_ADDRESSES = {
461
461
  USDC: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
462
462
  USDT: "0x036CbD53842c5426634e7929541eC2318f3dCF7e"
463
463
  // Same as USDC on testnet
464
+ },
465
+ "eip155:137": {
466
+ USDC: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
467
+ USDT: "0xc2132D05D31c914a87C6611C10748AEb04B58e8F"
464
468
  }
465
469
  };
470
+ var CHAIN_TO_NETWORK = {
471
+ "base": "eip155:8453",
472
+ "base_sepolia": "eip155:84532",
473
+ "polygon": "eip155:137"
474
+ };
466
475
  var TOKEN_DOMAINS = {
467
476
  USDC: { name: "USD Coin", version: "2" },
468
477
  USDT: { name: "Tether USD", version: "2" }
@@ -528,11 +537,17 @@ var MoltsPayServer = class {
528
537
  };
529
538
  this.registry = new FacilitatorRegistry(facilitatorConfig);
530
539
  const primaryFacilitator = this.registry.get(facilitatorConfig.primary);
531
- const networkName = this.useMainnet ? "Base mainnet" : "Base Sepolia (testnet)";
532
540
  console.log(`[MoltsPay] Loaded ${this.manifest.services.length} services from ${servicesPath}`);
533
541
  console.log(`[MoltsPay] Provider: ${this.manifest.provider.name}`);
534
542
  console.log(`[MoltsPay] Receive wallet: ${this.manifest.provider.wallet}`);
535
- console.log(`[MoltsPay] Network: ${this.networkId} (${networkName})`);
543
+ const chains = this.manifest.provider.chains;
544
+ if (chains && chains.length > 0) {
545
+ const chainNames = chains.map((c) => c.chain || c.network).join(", ");
546
+ console.log(`[MoltsPay] Chains: ${chainNames} (multi-chain enabled)`);
547
+ } else {
548
+ const networkName = this.useMainnet ? "Base mainnet" : "Base Sepolia (testnet)";
549
+ console.log(`[MoltsPay] Network: ${this.networkId} (${networkName})`);
550
+ }
536
551
  console.log(`[MoltsPay] Facilitator: ${primaryFacilitator.displayName} (${facilitatorConfig.strategy || "failover"})`);
537
552
  console.log(`[MoltsPay] Protocol: x402 (gasless for both client AND server)`);
538
553
  }
@@ -547,6 +562,42 @@ var MoltsPayServer = class {
547
562
  this.skills.set(serviceId, { id: serviceId, config, handler });
548
563
  return this;
549
564
  }
565
+ /**
566
+ * Get all configured chains for this provider
567
+ * Returns array of { network, wallet, tokens } for each chain
568
+ */
569
+ getProviderChains() {
570
+ const provider = this.manifest.provider;
571
+ if (provider.chains && provider.chains.length > 0) {
572
+ return provider.chains.map((c) => ({
573
+ network: c.network || CHAIN_TO_NETWORK[c.chain] || "eip155:8453",
574
+ wallet: c.wallet || provider.wallet,
575
+ tokens: c.tokens || ["USDC"]
576
+ }));
577
+ }
578
+ const chain = provider.chain || "base";
579
+ const network = CHAIN_TO_NETWORK[chain] || this.networkId;
580
+ return [{
581
+ network,
582
+ wallet: provider.wallet,
583
+ tokens: ["USDC"]
584
+ }];
585
+ }
586
+ /**
587
+ * Get wallet address for a specific network
588
+ */
589
+ getWalletForNetwork(network) {
590
+ const chains = this.getProviderChains();
591
+ const chain = chains.find((c) => c.network === network);
592
+ return chain?.wallet || this.manifest.provider.wallet;
593
+ }
594
+ /**
595
+ * Check if a network is accepted by this provider
596
+ */
597
+ isNetworkAccepted(network) {
598
+ const chains = this.getProviderChains();
599
+ return chains.some((c) => c.network === network);
600
+ }
550
601
  /**
551
602
  * Start HTTP server
552
603
  */
@@ -729,7 +780,9 @@ var MoltsPayServer = class {
729
780
  error: `Token ${paymentToken} not accepted. Accepted: ${accepted.join(", ")}`
730
781
  });
731
782
  }
732
- const requirements = this.buildPaymentRequirements(skill.config, paymentToken);
783
+ const paymentNetwork = payment.accepted?.network || payment.network || this.networkId;
784
+ const paymentWallet = this.getWalletForNetwork(paymentNetwork);
785
+ const requirements = this.buildPaymentRequirements(skill.config, paymentNetwork, paymentWallet, paymentToken);
733
786
  console.log(`[MoltsPay] Verifying payment...`);
734
787
  const verifyResult = await this.registry.verify(payment, requirements);
735
788
  if (!verifyResult.valid) {
@@ -784,15 +837,29 @@ var MoltsPayServer = class {
784
837
  }
785
838
  /**
786
839
  * Return 402 with x402 payment requirements (v2 format)
787
- * Includes requirements for all accepted currencies
840
+ * Includes requirements for all chains and all accepted currencies
788
841
  */
789
842
  sendPaymentRequired(config, res) {
790
843
  const acceptedTokens = getAcceptedCurrencies(config);
791
- const accepts = acceptedTokens.map((token) => this.buildPaymentRequirements(config, token));
844
+ const providerChains = this.getProviderChains();
845
+ const accepts = [];
846
+ for (const chainConfig of providerChains) {
847
+ for (const token of acceptedTokens) {
848
+ if (chainConfig.tokens.includes(token)) {
849
+ accepts.push(this.buildPaymentRequirements(config, chainConfig.network, chainConfig.wallet, token));
850
+ }
851
+ }
852
+ }
853
+ const acceptedChains = providerChains.map((c) => {
854
+ if (c.network === "eip155:8453") return "base";
855
+ if (c.network === "eip155:137") return "polygon";
856
+ return c.network;
857
+ });
792
858
  const paymentRequired = {
793
859
  x402Version: X402_VERSION2,
794
860
  accepts,
795
861
  acceptedCurrencies: acceptedTokens,
862
+ acceptedChains,
796
863
  resource: {
797
864
  url: `/execute?service=${config.id}`,
798
865
  description: `${config.name} - $${config.price} ${config.currency}`,
@@ -808,6 +875,7 @@ var MoltsPayServer = class {
808
875
  error: "Payment required",
809
876
  message: `Service requires $${config.price} ${config.currency}`,
810
877
  acceptedCurrencies: acceptedTokens,
878
+ acceptedChains,
811
879
  x402: paymentRequired
812
880
  }, null, 2));
813
881
  }
@@ -819,46 +887,50 @@ var MoltsPayServer = class {
819
887
  return { valid: false, error: `Unsupported x402 version: ${payment.x402Version}` };
820
888
  }
821
889
  const scheme = payment.accepted?.scheme || payment.scheme;
822
- const network = payment.accepted?.network || payment.network;
890
+ const network = payment.accepted?.network || payment.network || this.networkId;
823
891
  if (scheme !== "exact") {
824
892
  return { valid: false, error: `Unsupported scheme: ${scheme}` };
825
893
  }
826
- if (network !== this.networkId) {
827
- return { valid: false, error: `Network mismatch: expected ${this.networkId}, got ${network}` };
894
+ if (!this.isNetworkAccepted(network)) {
895
+ const acceptedChains = this.getProviderChains().map((c) => c.network).join(", ");
896
+ return { valid: false, error: `Network not accepted: ${network}. Accepted: ${acceptedChains}` };
828
897
  }
829
898
  return { valid: true };
830
899
  }
831
900
  /**
832
901
  * Build payment requirements for facilitator
833
- * Returns requirements for the primary currency (USDC by default)
834
- * Server accepts any of the acceptedCurrencies
902
+ * Now supports multi-chain: takes network and wallet as parameters
835
903
  */
836
- buildPaymentRequirements(config, token) {
904
+ buildPaymentRequirements(config, network, wallet, token) {
837
905
  const amountInUnits = Math.floor(config.price * 1e6).toString();
838
906
  const acceptedTokens = getAcceptedCurrencies(config);
907
+ const selectedNetwork = network || this.networkId;
908
+ const selectedWallet = wallet || this.manifest.provider.wallet;
839
909
  const selectedToken = token && acceptedTokens.includes(token) ? token : acceptedTokens[0];
840
- const tokenAddresses = TOKEN_ADDRESSES[this.networkId] || {};
910
+ const tokenAddresses = TOKEN_ADDRESSES[selectedNetwork] || {};
841
911
  const tokenAddress = tokenAddresses[selectedToken];
842
912
  const tokenDomain = TOKEN_DOMAINS[selectedToken] || TOKEN_DOMAINS.USDC;
843
913
  return {
844
914
  scheme: "exact",
845
- network: this.networkId,
915
+ network: selectedNetwork,
846
916
  asset: tokenAddress,
847
917
  amount: amountInUnits,
848
- payTo: this.manifest.provider.wallet,
918
+ payTo: selectedWallet,
849
919
  maxTimeoutSeconds: 300,
850
920
  extra: tokenDomain
851
921
  };
852
922
  }
853
923
  /**
854
924
  * Detect which token is being used in the payment
925
+ * Checks across all supported networks
855
926
  */
856
927
  detectPaymentToken(payment) {
857
928
  const asset = payment.accepted?.asset || payment.payload?.asset;
858
929
  if (!asset) return void 0;
859
- const tokenAddresses = TOKEN_ADDRESSES[this.networkId] || {};
930
+ const paymentNetwork = payment.accepted?.network || payment.network || this.networkId;
931
+ const tokenAddresses = TOKEN_ADDRESSES[paymentNetwork] || {};
860
932
  for (const [symbol, address] of Object.entries(tokenAddresses)) {
861
- if (address.toLowerCase() === asset.toLowerCase()) {
933
+ if (address && address.toLowerCase() === asset.toLowerCase()) {
862
934
  return symbol;
863
935
  }
864
936
  }
@@ -933,6 +1005,10 @@ var MoltsPayServer = class {
933
1005
  if (isNaN(amountNum) || amountNum <= 0) {
934
1006
  return this.sendJson(res, 400, { error: "Invalid amount" });
935
1007
  }
1008
+ const supportedChains = ["base", "polygon", "base_sepolia"];
1009
+ if (chain && !supportedChains.includes(chain)) {
1010
+ return this.sendJson(res, 400, { error: `Unsupported chain: ${chain}. Supported: ${supportedChains.join(", ")}` });
1011
+ }
936
1012
  const proxyConfig = {
937
1013
  id: serviceId || "proxy",
938
1014
  name: description || "Proxy Payment",
@@ -944,9 +1020,9 @@ var MoltsPayServer = class {
944
1020
  input: {},
945
1021
  output: {}
946
1022
  };
947
- const requirements = this.buildProxyPaymentRequirements(proxyConfig, wallet);
1023
+ const requirements = this.buildProxyPaymentRequirements(proxyConfig, wallet, currency, chain);
948
1024
  if (!paymentHeader) {
949
- return this.sendProxyPaymentRequired(proxyConfig, wallet, memo, res);
1025
+ return this.sendProxyPaymentRequired(proxyConfig, wallet, memo, chain, res);
950
1026
  }
951
1027
  let payment;
952
1028
  try {
@@ -963,8 +1039,9 @@ var MoltsPayServer = class {
963
1039
  if (scheme !== "exact") {
964
1040
  return this.sendJson(res, 402, { error: `Unsupported scheme: ${scheme}` });
965
1041
  }
966
- if (network !== this.networkId) {
967
- return this.sendJson(res, 402, { error: `Network mismatch: expected ${this.networkId}, got ${network}` });
1042
+ const expectedNetwork = chain ? CHAIN_TO_NETWORK[chain] || this.networkId : this.networkId;
1043
+ if (network !== expectedNetwork) {
1044
+ return this.sendJson(res, 402, { error: `Network mismatch: expected ${expectedNetwork}, got ${network}` });
968
1045
  }
969
1046
  console.log(`[MoltsPay] /proxy: Verifying payment for ${wallet}...`);
970
1047
  const verifyResult = await this.registry.verify(payment, requirements);
@@ -1070,16 +1147,17 @@ var MoltsPayServer = class {
1070
1147
  /**
1071
1148
  * Build payment requirements for proxy endpoint (uses provided wallet)
1072
1149
  */
1073
- buildProxyPaymentRequirements(config, wallet, token) {
1150
+ buildProxyPaymentRequirements(config, wallet, token, chain) {
1074
1151
  const amountInUnits = Math.floor(config.price * 1e6).toString();
1075
1152
  const acceptedTokens = getAcceptedCurrencies(config);
1153
+ const networkId = chain ? CHAIN_TO_NETWORK[chain] || this.networkId : this.networkId;
1076
1154
  const selectedToken = token && acceptedTokens.includes(token) ? token : acceptedTokens[0];
1077
- const tokenAddresses = TOKEN_ADDRESSES[this.networkId] || {};
1155
+ const tokenAddresses = TOKEN_ADDRESSES[networkId] || TOKEN_ADDRESSES[this.networkId] || {};
1078
1156
  const tokenAddress = tokenAddresses[selectedToken];
1079
1157
  const tokenDomain = TOKEN_DOMAINS[selectedToken] || TOKEN_DOMAINS.USDC;
1080
1158
  return {
1081
1159
  scheme: "exact",
1082
- network: this.networkId,
1160
+ network: networkId,
1083
1161
  asset: tokenAddress,
1084
1162
  amount: amountInUnits,
1085
1163
  payTo: wallet,
@@ -1091,8 +1169,8 @@ var MoltsPayServer = class {
1091
1169
  /**
1092
1170
  * Return 402 with x402 payment requirements for proxy endpoint
1093
1171
  */
1094
- sendProxyPaymentRequired(config, wallet, memo, res) {
1095
- const requirements = this.buildProxyPaymentRequirements(config, wallet);
1172
+ sendProxyPaymentRequired(config, wallet, memo, chain, res) {
1173
+ const requirements = this.buildProxyPaymentRequirements(config, wallet, config.currency, chain);
1096
1174
  const paymentRequired = {
1097
1175
  x402Version: X402_VERSION2,
1098
1176
  accepts: [requirements],