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.
@@ -38,6 +38,7 @@ interface ServiceInfo {
38
38
  output: Record<string, any>;
39
39
  available: boolean;
40
40
  provider?: ProviderInfo;
41
+ endpoint?: string;
41
42
  }
42
43
  interface ProviderInfo {
43
44
  name: string;
@@ -81,6 +82,8 @@ interface PayOptions {
81
82
  autoSelect?: boolean;
82
83
  /** Chain to pay on */
83
84
  chain?: 'base' | 'polygon' | 'base_sepolia' | 'tempo_moderato' | 'bnb' | 'bnb_testnet' | 'solana' | 'solana_devnet';
85
+ /** Send raw data at top level instead of wrapped in { params } */
86
+ rawData?: boolean;
84
87
  }
85
88
  declare class MoltsPayClient {
86
89
  private configDir;
@@ -38,6 +38,7 @@ interface ServiceInfo {
38
38
  output: Record<string, any>;
39
39
  available: boolean;
40
40
  provider?: ProviderInfo;
41
+ endpoint?: string;
41
42
  }
42
43
  interface ProviderInfo {
43
44
  name: string;
@@ -81,6 +82,8 @@ interface PayOptions {
81
82
  autoSelect?: boolean;
82
83
  /** Chain to pay on */
83
84
  chain?: 'base' | 'polygon' | 'base_sepolia' | 'tempo_moderato' | 'bnb' | 'bnb_testnet' | 'solana' | 'solana_devnet';
85
+ /** Send raw data at top level instead of wrapped in { params } */
86
+ rawData?: boolean;
84
87
  }
85
88
  declare class MoltsPayClient {
86
89
  private configDir;
@@ -422,11 +422,26 @@ var MoltsPayClient = class {
422
422
  throw new Error("Client not initialized. Run: npx moltspay init");
423
423
  }
424
424
  console.log(`[MoltsPay] Requesting service: ${service}`);
425
- const requestBody = { service, params };
425
+ let executeUrl = `${serverUrl}/execute`;
426
+ try {
427
+ const services = await this.getServices(serverUrl);
428
+ const svc = services.services?.find((s) => s.id === service);
429
+ if (svc?.endpoint) {
430
+ executeUrl = `${serverUrl}${svc.endpoint}`;
431
+ console.log(`[MoltsPay] Using service endpoint: ${svc.endpoint}`);
432
+ }
433
+ } catch {
434
+ }
435
+ let requestBody;
436
+ if (options.rawData) {
437
+ requestBody = { service, ...params };
438
+ } else {
439
+ requestBody = { service, params };
440
+ }
426
441
  if (options.chain) {
427
442
  requestBody.chain = options.chain;
428
443
  }
429
- const initialRes = await fetch(`${serverUrl}/execute`, {
444
+ const initialRes = await fetch(executeUrl, {
430
445
  method: "POST",
431
446
  headers: { "Content-Type": "application/json" },
432
447
  body: JSON.stringify(requestBody)
@@ -442,7 +457,7 @@ var MoltsPayClient = class {
442
457
  const paymentRequiredHeader = initialRes.headers.get(PAYMENT_REQUIRED_HEADER);
443
458
  if (wwwAuthHeader && wwwAuthHeader.toLowerCase().includes("payment")) {
444
459
  console.log("[MoltsPay] Detected MPP protocol, using Tempo flow...");
445
- return await this.handleMPPPayment(serverUrl, service, params, wwwAuthHeader);
460
+ return await this.handleMPPPayment(executeUrl, service, params, wwwAuthHeader, options);
446
461
  }
447
462
  if (!paymentRequiredHeader) {
448
463
  throw new Error("Missing payment header (x-payment-required or www-authenticate)");
@@ -503,7 +518,7 @@ Please specify: --chain <chain_name>`
503
518
  if (!req2) {
504
519
  throw new Error(`Failed to find payment requirement for ${selectedChain}`);
505
520
  }
506
- return await this.handleSolanaPayment(serverUrl, service, params, req2, solanaChain);
521
+ return await this.handleSolanaPayment(executeUrl, service, params, req2, solanaChain, options);
507
522
  }
508
523
  const chainName = selectedChain;
509
524
  const chain = getChain(chainName);
@@ -550,14 +565,14 @@ Please specify: --chain <chain_name>`
550
565
  if (!bnbSpender) {
551
566
  throw new Error("Server did not provide bnbSpender address. Server may not support BNB payments.");
552
567
  }
553
- return await this.handleBNBPayment(serverUrl, service, params, {
568
+ return await this.handleBNBPayment(executeUrl, service, params, {
554
569
  to: payTo2,
555
570
  amount,
556
571
  token,
557
572
  chainName,
558
573
  chain,
559
574
  spender: bnbSpender
560
- });
575
+ }, options);
561
576
  }
562
577
  const payTo = req.payTo || req.resource;
563
578
  if (!payTo) {
@@ -588,11 +603,11 @@ Please specify: --chain <chain_name>`
588
603
  };
589
604
  const paymentHeader = Buffer.from(JSON.stringify(payload)).toString("base64");
590
605
  console.log(`[MoltsPay] Sending request with payment...`);
591
- const paidRequestBody = { service, params };
606
+ const paidRequestBody = options.rawData ? { service, ...params } : { service, params };
592
607
  if (options.chain) {
593
608
  paidRequestBody.chain = options.chain;
594
609
  }
595
- const paidRes = await fetch(`${serverUrl}/execute`, {
610
+ const paidRes = await fetch(executeUrl, {
596
611
  method: "POST",
597
612
  headers: {
598
613
  "Content-Type": "application/json",
@@ -606,13 +621,13 @@ Please specify: --chain <chain_name>`
606
621
  }
607
622
  this.recordSpending(amount);
608
623
  console.log(`[MoltsPay] Success! Payment: ${result.payment?.status || "claimed"}`);
609
- return result.result;
624
+ return result.result || result;
610
625
  }
611
626
  /**
612
627
  * Handle MPP (Machine Payments Protocol) payment flow
613
628
  * Called when pay() detects WWW-Authenticate header in 402 response
614
629
  */
615
- async handleMPPPayment(serverUrl, service, params, wwwAuthHeader) {
630
+ async handleMPPPayment(executeUrl, service, params, wwwAuthHeader, options = {}) {
616
631
  const { privateKeyToAccount } = await import("viem/accounts");
617
632
  const { createWalletClient, createPublicClient, http } = await import("viem");
618
633
  const { tempoModerato } = await import("viem/chains");
@@ -673,13 +688,14 @@ Please specify: --chain <chain_name>`
673
688
  source: `did:pkh:eip155:${chainId}:${account.address}`
674
689
  };
675
690
  const credentialB64 = Buffer.from(JSON.stringify(credential)).toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
676
- const paidRes = await fetch(`${serverUrl}/execute`, {
691
+ const retryBody = options.rawData ? { service, ...params, chain: "tempo_moderato" } : { service, params, chain: "tempo_moderato" };
692
+ const paidRes = await fetch(executeUrl, {
677
693
  method: "POST",
678
694
  headers: {
679
695
  "Content-Type": "application/json",
680
696
  "Authorization": `Payment ${credentialB64}`
681
697
  },
682
- body: JSON.stringify({ service, params, chain: "tempo_moderato" })
698
+ body: JSON.stringify(retryBody)
683
699
  });
684
700
  const result = await paidRes.json();
685
701
  if (!paidRes.ok) {
@@ -699,7 +715,7 @@ Please specify: --chain <chain_name>`
699
715
  * 4. Server executes service
700
716
  * 5. Server calls transferFrom if successful (pay-for-success)
701
717
  */
702
- async handleBNBPayment(serverUrl, service, params, paymentDetails) {
718
+ async handleBNBPayment(executeUrl, service, params, paymentDetails, options = {}) {
703
719
  const { to, amount, token, chainName, chain, spender } = paymentDetails;
704
720
  const tokenConfig = chain.tokens[token];
705
721
  const provider = new import_ethers.ethers.JsonRpcProvider(chain.rpc);
@@ -795,13 +811,14 @@ Run: npx moltspay approve --chain ${chainName} --spender ${spender}`
795
811
  };
796
812
  const paymentHeader = Buffer.from(JSON.stringify(payload)).toString("base64");
797
813
  console.log(`[MoltsPay] Sending BNB payment request...`);
798
- const paidRes = await fetch(`${serverUrl}/execute`, {
814
+ const bnbRequestBody = options.rawData ? { service, ...params, chain: chainName } : { service, params, chain: chainName };
815
+ const paidRes = await fetch(executeUrl, {
799
816
  method: "POST",
800
817
  headers: {
801
818
  "Content-Type": "application/json",
802
819
  "X-Payment": paymentHeader
803
820
  },
804
- body: JSON.stringify({ service, params, chain: chainName })
821
+ body: JSON.stringify(bnbRequestBody)
805
822
  });
806
823
  const result = await paidRes.json();
807
824
  if (!paidRes.ok) {
@@ -818,7 +835,7 @@ Run: npx moltspay approve --chain ${chainName} --spender ${spender}`
818
835
  * 1. Client creates and signs a transfer transaction
819
836
  * 2. Server submits the transaction after service completes
820
837
  */
821
- async handleSolanaPayment(serverUrl, service, params, requirements, chain) {
838
+ async handleSolanaPayment(executeUrl, service, params, requirements, chain, options = {}) {
822
839
  const solanaWallet = loadSolanaWallet(this.configDir);
823
840
  if (!solanaWallet) {
824
841
  throw new Error("No Solana wallet found. Run: npx moltspay init --chain solana_devnet");
@@ -871,13 +888,14 @@ Run: npx moltspay approve --chain ${chainName} --spender ${spender}`
871
888
  }
872
889
  };
873
890
  const paymentHeader = Buffer.from(JSON.stringify(payload)).toString("base64");
874
- const paidRes = await fetch(`${serverUrl}/execute`, {
891
+ const solanaRequestBody = options.rawData ? { service, ...params, chain } : { service, params, chain };
892
+ const paidRes = await fetch(executeUrl, {
875
893
  method: "POST",
876
894
  headers: {
877
895
  "Content-Type": "application/json",
878
896
  "X-Payment": paymentHeader
879
897
  },
880
- body: JSON.stringify({ service, params, chain })
898
+ body: JSON.stringify(solanaRequestBody)
881
899
  });
882
900
  const result = await paidRes.json();
883
901
  if (!paidRes.ok) {
@@ -1022,15 +1040,17 @@ Run: npx moltspay approve --chain ${chainName} --spender ${spender}`
1022
1040
  loadWallet() {
1023
1041
  const walletPath = (0, import_path2.join)(this.configDir, "wallet.json");
1024
1042
  if ((0, import_fs2.existsSync)(walletPath)) {
1025
- try {
1026
- const stats = (0, import_fs2.statSync)(walletPath);
1027
- const mode = stats.mode & 511;
1028
- if (mode !== 384) {
1029
- console.warn(`[MoltsPay] WARNING: wallet.json has insecure permissions (${mode.toString(8)})`);
1030
- console.warn(`[MoltsPay] Fixing permissions to 0600...`);
1031
- (0, import_fs2.chmodSync)(walletPath, 384);
1043
+ if (process.platform !== "win32") {
1044
+ try {
1045
+ const stats = (0, import_fs2.statSync)(walletPath);
1046
+ const mode = stats.mode & 511;
1047
+ if (mode !== 384) {
1048
+ console.warn(`[MoltsPay] WARNING: wallet.json has insecure permissions (${mode.toString(8)})`);
1049
+ console.warn(`[MoltsPay] Fixing permissions to 0600...`);
1050
+ (0, import_fs2.chmodSync)(walletPath, 384);
1051
+ }
1052
+ } catch {
1032
1053
  }
1033
- } catch (err) {
1034
1054
  }
1035
1055
  const content = (0, import_fs2.readFileSync)(walletPath, "utf-8");
1036
1056
  return JSON.parse(content);