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.
- package/README.md +42 -3
- package/dist/cdp/index.js +1 -1
- package/dist/cdp/index.js.map +1 -1
- package/dist/cdp/index.mjs +1 -1
- package/dist/cdp/index.mjs.map +1 -1
- package/dist/chains/index.js +1 -1
- package/dist/chains/index.js.map +1 -1
- package/dist/chains/index.mjs +1 -1
- package/dist/chains/index.mjs.map +1 -1
- package/dist/cli/index.js +5028 -109
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/index.mjs +5019 -96
- package/dist/cli/index.mjs.map +1 -1
- package/dist/client/index.d.mts +18 -3
- package/dist/client/index.d.ts +18 -3
- package/dist/client/index.js +89 -10
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +89 -10
- package/dist/client/index.mjs.map +1 -1
- package/dist/facilitators/index.js +1 -1
- package/dist/facilitators/index.js.map +1 -1
- package/dist/facilitators/index.mjs +1 -1
- package/dist/facilitators/index.mjs.map +1 -1
- package/dist/index.js +193 -36
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +193 -36
- package/dist/index.mjs.map +1 -1
- package/dist/server/index.d.mts +25 -5
- package/dist/server/index.d.ts +25 -5
- package/dist/server/index.js +104 -26
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +104 -26
- package/dist/server/index.mjs.map +1 -1
- package/dist/verify/index.js +1 -1
- package/dist/verify/index.js.map +1 -1
- package/dist/verify/index.mjs +1 -1
- package/dist/verify/index.mjs.map +1 -1
- package/dist/wallet/index.js +1 -1
- package/dist/wallet/index.js.map +1 -1
- package/dist/wallet/index.mjs +1 -1
- package/dist/wallet/index.mjs.map +1 -1
- package/package.json +3 -2
- package/schemas/moltspay.services.schema.json +58 -2
package/dist/server/index.mjs
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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
|
|
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 (
|
|
827
|
-
|
|
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
|
-
*
|
|
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[
|
|
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:
|
|
915
|
+
network: selectedNetwork,
|
|
846
916
|
asset: tokenAddress,
|
|
847
917
|
amount: amountInUnits,
|
|
848
|
-
payTo:
|
|
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
|
|
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
|
-
|
|
967
|
-
|
|
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:
|
|
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],
|