moltspay 1.4.0 → 1.5.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/.env.example +14 -0
- package/README.md +185 -93
- package/dist/cli/index.js +69 -33
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/index.mjs +69 -33
- package/dist/cli/index.mjs.map +1 -1
- package/dist/client/index.d.mts +3 -0
- package/dist/client/index.d.ts +3 -0
- package/dist/client/index.js +46 -26
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +46 -26
- package/dist/client/index.mjs.map +1 -1
- package/dist/index.js +50 -28
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +50 -28
- package/dist/index.mjs.map +1 -1
- package/dist/mcp/index.d.mts +1 -0
- package/dist/mcp/index.d.ts +1 -0
- package/dist/mcp/index.js +1498 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/index.mjs +1492 -0
- package/dist/mcp/index.mjs.map +1 -0
- package/dist/server/index.js +4 -2
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +4 -2
- package/dist/server/index.mjs.map +1 -1
- package/package.json +12 -4
package/dist/index.js
CHANGED
|
@@ -2253,8 +2253,10 @@ var MoltsPayServer = class {
|
|
|
2253
2253
|
isProxyAllowed(clientIP) {
|
|
2254
2254
|
const allowedIPs = process.env.PROXY_ALLOWED_IPS?.split(",").map((ip) => ip.trim()) || [];
|
|
2255
2255
|
if (allowedIPs.length === 0) {
|
|
2256
|
-
|
|
2257
|
-
|
|
2256
|
+
return true;
|
|
2257
|
+
}
|
|
2258
|
+
if (allowedIPs.includes("*")) {
|
|
2259
|
+
return true;
|
|
2258
2260
|
}
|
|
2259
2261
|
const normalizedIP = clientIP === "::1" ? "127.0.0.1" : clientIP.replace("::ffff:", "");
|
|
2260
2262
|
const allowed = allowedIPs.includes(normalizedIP) || allowedIPs.includes(clientIP);
|
|
@@ -2784,11 +2786,26 @@ var MoltsPayClient = class {
|
|
|
2784
2786
|
throw new Error("Client not initialized. Run: npx moltspay init");
|
|
2785
2787
|
}
|
|
2786
2788
|
console.log(`[MoltsPay] Requesting service: ${service}`);
|
|
2787
|
-
|
|
2789
|
+
let executeUrl = `${serverUrl}/execute`;
|
|
2790
|
+
try {
|
|
2791
|
+
const services = await this.getServices(serverUrl);
|
|
2792
|
+
const svc = services.services?.find((s) => s.id === service);
|
|
2793
|
+
if (svc?.endpoint) {
|
|
2794
|
+
executeUrl = `${serverUrl}${svc.endpoint}`;
|
|
2795
|
+
console.log(`[MoltsPay] Using service endpoint: ${svc.endpoint}`);
|
|
2796
|
+
}
|
|
2797
|
+
} catch {
|
|
2798
|
+
}
|
|
2799
|
+
let requestBody;
|
|
2800
|
+
if (options.rawData) {
|
|
2801
|
+
requestBody = { service, ...params };
|
|
2802
|
+
} else {
|
|
2803
|
+
requestBody = { service, params };
|
|
2804
|
+
}
|
|
2788
2805
|
if (options.chain) {
|
|
2789
2806
|
requestBody.chain = options.chain;
|
|
2790
2807
|
}
|
|
2791
|
-
const initialRes = await fetch(
|
|
2808
|
+
const initialRes = await fetch(executeUrl, {
|
|
2792
2809
|
method: "POST",
|
|
2793
2810
|
headers: { "Content-Type": "application/json" },
|
|
2794
2811
|
body: JSON.stringify(requestBody)
|
|
@@ -2804,7 +2821,7 @@ var MoltsPayClient = class {
|
|
|
2804
2821
|
const paymentRequiredHeader = initialRes.headers.get(PAYMENT_REQUIRED_HEADER2);
|
|
2805
2822
|
if (wwwAuthHeader && wwwAuthHeader.toLowerCase().includes("payment")) {
|
|
2806
2823
|
console.log("[MoltsPay] Detected MPP protocol, using Tempo flow...");
|
|
2807
|
-
return await this.handleMPPPayment(
|
|
2824
|
+
return await this.handleMPPPayment(executeUrl, service, params, wwwAuthHeader, options);
|
|
2808
2825
|
}
|
|
2809
2826
|
if (!paymentRequiredHeader) {
|
|
2810
2827
|
throw new Error("Missing payment header (x-payment-required or www-authenticate)");
|
|
@@ -2865,7 +2882,7 @@ Please specify: --chain <chain_name>`
|
|
|
2865
2882
|
if (!req2) {
|
|
2866
2883
|
throw new Error(`Failed to find payment requirement for ${selectedChain}`);
|
|
2867
2884
|
}
|
|
2868
|
-
return await this.handleSolanaPayment(
|
|
2885
|
+
return await this.handleSolanaPayment(executeUrl, service, params, req2, solanaChain, options);
|
|
2869
2886
|
}
|
|
2870
2887
|
const chainName = selectedChain;
|
|
2871
2888
|
const chain = getChain(chainName);
|
|
@@ -2912,14 +2929,14 @@ Please specify: --chain <chain_name>`
|
|
|
2912
2929
|
if (!bnbSpender) {
|
|
2913
2930
|
throw new Error("Server did not provide bnbSpender address. Server may not support BNB payments.");
|
|
2914
2931
|
}
|
|
2915
|
-
return await this.handleBNBPayment(
|
|
2932
|
+
return await this.handleBNBPayment(executeUrl, service, params, {
|
|
2916
2933
|
to: payTo2,
|
|
2917
2934
|
amount,
|
|
2918
2935
|
token,
|
|
2919
2936
|
chainName,
|
|
2920
2937
|
chain,
|
|
2921
2938
|
spender: bnbSpender
|
|
2922
|
-
});
|
|
2939
|
+
}, options);
|
|
2923
2940
|
}
|
|
2924
2941
|
const payTo = req.payTo || req.resource;
|
|
2925
2942
|
if (!payTo) {
|
|
@@ -2950,11 +2967,11 @@ Please specify: --chain <chain_name>`
|
|
|
2950
2967
|
};
|
|
2951
2968
|
const paymentHeader = Buffer.from(JSON.stringify(payload)).toString("base64");
|
|
2952
2969
|
console.log(`[MoltsPay] Sending request with payment...`);
|
|
2953
|
-
const paidRequestBody = { service, params };
|
|
2970
|
+
const paidRequestBody = options.rawData ? { service, ...params } : { service, params };
|
|
2954
2971
|
if (options.chain) {
|
|
2955
2972
|
paidRequestBody.chain = options.chain;
|
|
2956
2973
|
}
|
|
2957
|
-
const paidRes = await fetch(
|
|
2974
|
+
const paidRes = await fetch(executeUrl, {
|
|
2958
2975
|
method: "POST",
|
|
2959
2976
|
headers: {
|
|
2960
2977
|
"Content-Type": "application/json",
|
|
@@ -2968,13 +2985,13 @@ Please specify: --chain <chain_name>`
|
|
|
2968
2985
|
}
|
|
2969
2986
|
this.recordSpending(amount);
|
|
2970
2987
|
console.log(`[MoltsPay] Success! Payment: ${result.payment?.status || "claimed"}`);
|
|
2971
|
-
return result.result;
|
|
2988
|
+
return result.result || result;
|
|
2972
2989
|
}
|
|
2973
2990
|
/**
|
|
2974
2991
|
* Handle MPP (Machine Payments Protocol) payment flow
|
|
2975
2992
|
* Called when pay() detects WWW-Authenticate header in 402 response
|
|
2976
2993
|
*/
|
|
2977
|
-
async handleMPPPayment(
|
|
2994
|
+
async handleMPPPayment(executeUrl, service, params, wwwAuthHeader, options = {}) {
|
|
2978
2995
|
const { privateKeyToAccount: privateKeyToAccount2 } = await import("viem/accounts");
|
|
2979
2996
|
const { createWalletClient, createPublicClient, http } = await import("viem");
|
|
2980
2997
|
const { tempoModerato } = await import("viem/chains");
|
|
@@ -3035,13 +3052,14 @@ Please specify: --chain <chain_name>`
|
|
|
3035
3052
|
source: `did:pkh:eip155:${chainId}:${account.address}`
|
|
3036
3053
|
};
|
|
3037
3054
|
const credentialB64 = Buffer.from(JSON.stringify(credential)).toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
3038
|
-
const
|
|
3055
|
+
const retryBody = options.rawData ? { service, ...params, chain: "tempo_moderato" } : { service, params, chain: "tempo_moderato" };
|
|
3056
|
+
const paidRes = await fetch(executeUrl, {
|
|
3039
3057
|
method: "POST",
|
|
3040
3058
|
headers: {
|
|
3041
3059
|
"Content-Type": "application/json",
|
|
3042
3060
|
"Authorization": `Payment ${credentialB64}`
|
|
3043
3061
|
},
|
|
3044
|
-
body: JSON.stringify(
|
|
3062
|
+
body: JSON.stringify(retryBody)
|
|
3045
3063
|
});
|
|
3046
3064
|
const result = await paidRes.json();
|
|
3047
3065
|
if (!paidRes.ok) {
|
|
@@ -3061,7 +3079,7 @@ Please specify: --chain <chain_name>`
|
|
|
3061
3079
|
* 4. Server executes service
|
|
3062
3080
|
* 5. Server calls transferFrom if successful (pay-for-success)
|
|
3063
3081
|
*/
|
|
3064
|
-
async handleBNBPayment(
|
|
3082
|
+
async handleBNBPayment(executeUrl, service, params, paymentDetails, options = {}) {
|
|
3065
3083
|
const { to, amount, token, chainName, chain, spender } = paymentDetails;
|
|
3066
3084
|
const tokenConfig = chain.tokens[token];
|
|
3067
3085
|
const provider = new import_ethers.ethers.JsonRpcProvider(chain.rpc);
|
|
@@ -3157,13 +3175,14 @@ Run: npx moltspay approve --chain ${chainName} --spender ${spender}`
|
|
|
3157
3175
|
};
|
|
3158
3176
|
const paymentHeader = Buffer.from(JSON.stringify(payload)).toString("base64");
|
|
3159
3177
|
console.log(`[MoltsPay] Sending BNB payment request...`);
|
|
3160
|
-
const
|
|
3178
|
+
const bnbRequestBody = options.rawData ? { service, ...params, chain: chainName } : { service, params, chain: chainName };
|
|
3179
|
+
const paidRes = await fetch(executeUrl, {
|
|
3161
3180
|
method: "POST",
|
|
3162
3181
|
headers: {
|
|
3163
3182
|
"Content-Type": "application/json",
|
|
3164
3183
|
"X-Payment": paymentHeader
|
|
3165
3184
|
},
|
|
3166
|
-
body: JSON.stringify(
|
|
3185
|
+
body: JSON.stringify(bnbRequestBody)
|
|
3167
3186
|
});
|
|
3168
3187
|
const result = await paidRes.json();
|
|
3169
3188
|
if (!paidRes.ok) {
|
|
@@ -3180,7 +3199,7 @@ Run: npx moltspay approve --chain ${chainName} --spender ${spender}`
|
|
|
3180
3199
|
* 1. Client creates and signs a transfer transaction
|
|
3181
3200
|
* 2. Server submits the transaction after service completes
|
|
3182
3201
|
*/
|
|
3183
|
-
async handleSolanaPayment(
|
|
3202
|
+
async handleSolanaPayment(executeUrl, service, params, requirements, chain, options = {}) {
|
|
3184
3203
|
const solanaWallet = loadSolanaWallet(this.configDir);
|
|
3185
3204
|
if (!solanaWallet) {
|
|
3186
3205
|
throw new Error("No Solana wallet found. Run: npx moltspay init --chain solana_devnet");
|
|
@@ -3233,13 +3252,14 @@ Run: npx moltspay approve --chain ${chainName} --spender ${spender}`
|
|
|
3233
3252
|
}
|
|
3234
3253
|
};
|
|
3235
3254
|
const paymentHeader = Buffer.from(JSON.stringify(payload)).toString("base64");
|
|
3236
|
-
const
|
|
3255
|
+
const solanaRequestBody = options.rawData ? { service, ...params, chain } : { service, params, chain };
|
|
3256
|
+
const paidRes = await fetch(executeUrl, {
|
|
3237
3257
|
method: "POST",
|
|
3238
3258
|
headers: {
|
|
3239
3259
|
"Content-Type": "application/json",
|
|
3240
3260
|
"X-Payment": paymentHeader
|
|
3241
3261
|
},
|
|
3242
|
-
body: JSON.stringify(
|
|
3262
|
+
body: JSON.stringify(solanaRequestBody)
|
|
3243
3263
|
});
|
|
3244
3264
|
const result = await paidRes.json();
|
|
3245
3265
|
if (!paidRes.ok) {
|
|
@@ -3384,15 +3404,17 @@ Run: npx moltspay approve --chain ${chainName} --spender ${spender}`
|
|
|
3384
3404
|
loadWallet() {
|
|
3385
3405
|
const walletPath = (0, import_path2.join)(this.configDir, "wallet.json");
|
|
3386
3406
|
if ((0, import_fs4.existsSync)(walletPath)) {
|
|
3387
|
-
|
|
3388
|
-
|
|
3389
|
-
|
|
3390
|
-
|
|
3391
|
-
|
|
3392
|
-
|
|
3393
|
-
|
|
3407
|
+
if (process.platform !== "win32") {
|
|
3408
|
+
try {
|
|
3409
|
+
const stats = (0, import_fs4.statSync)(walletPath);
|
|
3410
|
+
const mode = stats.mode & 511;
|
|
3411
|
+
if (mode !== 384) {
|
|
3412
|
+
console.warn(`[MoltsPay] WARNING: wallet.json has insecure permissions (${mode.toString(8)})`);
|
|
3413
|
+
console.warn(`[MoltsPay] Fixing permissions to 0600...`);
|
|
3414
|
+
(0, import_fs4.chmodSync)(walletPath, 384);
|
|
3415
|
+
}
|
|
3416
|
+
} catch {
|
|
3394
3417
|
}
|
|
3395
|
-
} catch (err) {
|
|
3396
3418
|
}
|
|
3397
3419
|
const content = (0, import_fs4.readFileSync)(walletPath, "utf-8");
|
|
3398
3420
|
return JSON.parse(content);
|