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/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
- console.log(`[MoltsPay] /proxy denied: no PROXY_ALLOWED_IPS configured`);
2257
- return false;
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
- const requestBody = { service, params };
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(`${serverUrl}/execute`, {
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(serverUrl, service, params, wwwAuthHeader);
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(serverUrl, service, params, req2, solanaChain);
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(serverUrl, service, params, {
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(`${serverUrl}/execute`, {
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(serverUrl, service, params, wwwAuthHeader) {
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 paidRes = await fetch(`${serverUrl}/execute`, {
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({ service, params, chain: "tempo_moderato" })
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(serverUrl, service, params, paymentDetails) {
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 paidRes = await fetch(`${serverUrl}/execute`, {
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({ service, params, chain: chainName })
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(serverUrl, service, params, requirements, chain) {
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 paidRes = await fetch(`${serverUrl}/execute`, {
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({ service, params, chain })
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
- try {
3388
- const stats = (0, import_fs4.statSync)(walletPath);
3389
- const mode = stats.mode & 511;
3390
- if (mode !== 384) {
3391
- console.warn(`[MoltsPay] WARNING: wallet.json has insecure permissions (${mode.toString(8)})`);
3392
- console.warn(`[MoltsPay] Fixing permissions to 0600...`);
3393
- (0, import_fs4.chmodSync)(walletPath, 384);
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);