moltspay 1.0.0 → 1.2.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/cli/index.js CHANGED
@@ -6,6 +6,9 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
6
  var __getOwnPropNames = Object.getOwnPropertyNames;
7
7
  var __getProtoOf = Object.getPrototypeOf;
8
8
  var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __esm = (fn, res) => function __init() {
10
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
11
+ };
9
12
  var __copyProps = (to, from, except, desc) => {
10
13
  if (from && typeof from === "object" || typeof from === "function") {
11
14
  for (let key of __getOwnPropNames(from))
@@ -23,7 +26,15 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
23
26
  mod
24
27
  ));
25
28
 
29
+ // node_modules/tsup/assets/cjs_shims.js
30
+ var init_cjs_shims = __esm({
31
+ "node_modules/tsup/assets/cjs_shims.js"() {
32
+ "use strict";
33
+ }
34
+ });
35
+
26
36
  // src/cli/index.ts
37
+ init_cjs_shims();
27
38
  var import_commander = require("commander");
28
39
  var import_os2 = require("os");
29
40
  var import_path2 = require("path");
@@ -31,12 +42,14 @@ var import_fs4 = require("fs");
31
42
  var import_child_process = require("child_process");
32
43
 
33
44
  // src/client/index.ts
45
+ init_cjs_shims();
34
46
  var import_fs = require("fs");
35
47
  var import_os = require("os");
36
48
  var import_path = require("path");
37
49
  var import_ethers = require("ethers");
38
50
 
39
51
  // src/chains/index.ts
52
+ init_cjs_shims();
40
53
  var CHAINS = {
41
54
  // ============ Mainnet ============
42
55
  base: {
@@ -157,6 +170,9 @@ function getChain(name) {
157
170
  return config;
158
171
  }
159
172
 
173
+ // src/client/types.ts
174
+ init_cjs_shims();
175
+
160
176
  // src/client/index.ts
161
177
  var X402_VERSION = 2;
162
178
  var PAYMENT_REQUIRED_HEADER = "x-payment-required";
@@ -218,11 +234,20 @@ var MoltsPayClient = class {
218
234
  * Get services from a provider
219
235
  */
220
236
  async getServices(serverUrl) {
221
- const res = await fetch(`${serverUrl}/services`);
222
- if (!res.ok) {
223
- throw new Error(`Failed to get services: ${res.statusText}`);
237
+ const normalizedUrl = serverUrl.replace(/\/(services|api\/services|registry\/services)\/?$/, "");
238
+ const endpoints = ["/services", "/api/services", "/registry/services"];
239
+ for (const endpoint of endpoints) {
240
+ try {
241
+ const res = await fetch(`${normalizedUrl}${endpoint}`);
242
+ if (!res.ok) continue;
243
+ const contentType = res.headers.get("content-type") || "";
244
+ if (!contentType.includes("application/json")) continue;
245
+ return await res.json();
246
+ } catch {
247
+ continue;
248
+ }
224
249
  }
225
- return res.json();
250
+ throw new Error(`Failed to get services: no valid endpoint found at ${normalizedUrl}`);
226
251
  }
227
252
  /**
228
253
  * Pay for a service and get the result (x402 protocol)
@@ -600,11 +625,16 @@ Please specify: --chain base or --chain polygon`
600
625
  };
601
626
 
602
627
  // src/server/index.ts
628
+ init_cjs_shims();
603
629
  var import_fs3 = require("fs");
604
630
  var import_http = require("http");
605
631
  var path2 = __toESM(require("path"));
606
632
 
633
+ // src/facilitators/index.ts
634
+ init_cjs_shims();
635
+
607
636
  // src/facilitators/interface.ts
637
+ init_cjs_shims();
608
638
  var BaseFacilitator = class {
609
639
  supportsNetwork(network) {
610
640
  return this.supportedNetworks.includes(network);
@@ -612,6 +642,7 @@ var BaseFacilitator = class {
612
642
  };
613
643
 
614
644
  // src/facilitators/cdp.ts
645
+ init_cjs_shims();
615
646
  var import_fs2 = require("fs");
616
647
  var path = __toESM(require("path"));
617
648
  var X402_VERSION2 = 2;
@@ -825,6 +856,7 @@ var CDPFacilitator = class extends BaseFacilitator {
825
856
  };
826
857
 
827
858
  // src/facilitators/registry.ts
859
+ init_cjs_shims();
828
860
  var FacilitatorRegistry = class {
829
861
  factories = /* @__PURE__ */ new Map();
830
862
  instances = /* @__PURE__ */ new Map();
@@ -1048,6 +1080,9 @@ var FacilitatorRegistry = class {
1048
1080
  }
1049
1081
  };
1050
1082
 
1083
+ // src/server/types.ts
1084
+ init_cjs_shims();
1085
+
1051
1086
  // src/server/index.ts
1052
1087
  var X402_VERSION3 = 2;
1053
1088
  var PAYMENT_REQUIRED_HEADER2 = "x-payment-required";
@@ -1795,6 +1830,19 @@ var MoltsPayServer = class {
1795
1830
  }
1796
1831
  };
1797
1832
 
1833
+ // src/onramp/index.ts
1834
+ init_cjs_shims();
1835
+ async function printQRCode(url) {
1836
+ const qrcodeModule = await import("qrcode-terminal");
1837
+ const qrcode = qrcodeModule.default || qrcodeModule;
1838
+ return new Promise((resolve2) => {
1839
+ qrcode.generate(url, { small: true }, (qr) => {
1840
+ console.log(qr);
1841
+ resolve2();
1842
+ });
1843
+ });
1844
+ }
1845
+
1798
1846
  // src/cli/index.ts
1799
1847
  var readline = __toESM(require("readline"));
1800
1848
  var program = new import_commander.Command();
@@ -1886,6 +1934,51 @@ program.command("config").description("Update MoltsPay settings").option("--max-
1886
1934
  }
1887
1935
  }
1888
1936
  });
1937
+ program.command("fund <amount>").description("Fund wallet with USDC via Coinbase (US debit card / Apple Pay)").option("--chain <chain>", "Chain to fund (base or polygon)", "base").option("--config-dir <dir>", "Config directory", DEFAULT_CONFIG_DIR).action(async (amountStr, options) => {
1938
+ const client = new MoltsPayClient({ configDir: options.configDir });
1939
+ if (!client.isInitialized) {
1940
+ console.log("\u274C Not initialized. Run: npx moltspay init");
1941
+ return;
1942
+ }
1943
+ const amount = parseFloat(amountStr);
1944
+ if (isNaN(amount) || amount < 5) {
1945
+ console.log("\u274C Minimum $5.");
1946
+ return;
1947
+ }
1948
+ const chain = options.chain?.toLowerCase() || "base";
1949
+ if (!["base", "polygon"].includes(chain)) {
1950
+ console.log("\u274C Invalid chain. Use: base or polygon");
1951
+ return;
1952
+ }
1953
+ console.log("\n\u{1F4B3} Fund your agent wallet\n");
1954
+ console.log(` Wallet: ${client.address}`);
1955
+ console.log(` Chain: ${chain}`);
1956
+ console.log(` Amount: $${amount.toFixed(2)}
1957
+ `);
1958
+ try {
1959
+ const ONRAMP_API = process.env.MOLTSPAY_ONRAMP_API || "https://moltspay.com/api/v1/onramp";
1960
+ const response = await fetch(`${ONRAMP_API}/create`, {
1961
+ method: "POST",
1962
+ headers: { "Content-Type": "application/json" },
1963
+ body: JSON.stringify({
1964
+ address: client.address,
1965
+ amount,
1966
+ chain
1967
+ })
1968
+ });
1969
+ if (!response.ok) {
1970
+ const errorData = await response.json().catch(() => ({ error: "Server error" }));
1971
+ throw new Error(errorData.error || `Server returned ${response.status}`);
1972
+ }
1973
+ const result = await response.json();
1974
+ const { url } = result;
1975
+ console.log(" Scan to pay (US debit card / Apple Pay):\n");
1976
+ await printQRCode(url);
1977
+ console.log("\n \u23F1\uFE0F QR code expires in 5 minutes\n");
1978
+ } catch (error) {
1979
+ console.log(`\u274C ${error.message}`);
1980
+ }
1981
+ });
1889
1982
  program.command("status").description("Show wallet status and balance").option("--config-dir <dir>", "Config directory", DEFAULT_CONFIG_DIR).option("--json", "Output as JSON").action(async (options) => {
1890
1983
  const client = new MoltsPayClient({ configDir: options.configDir });
1891
1984
  if (!client.isInitialized) {
@@ -1925,6 +2018,84 @@ program.command("status").description("Show wallet status and balance").option("
1925
2018
  console.log("");
1926
2019
  }
1927
2020
  });
2021
+ program.command("list").description("List recent transactions").option("--days <n>", "Number of days to look back", "7").option("--chain <chain>", "Chain to query (base, polygon, or all)", "all").option("--limit <n>", "Max transactions to show", "20").option("--config-dir <dir>", "Config directory", DEFAULT_CONFIG_DIR).action(async (options) => {
2022
+ const client = new MoltsPayClient({ configDir: options.configDir });
2023
+ if (!client.isInitialized) {
2024
+ console.log("\u274C Not initialized. Run: npx moltspay init");
2025
+ return;
2026
+ }
2027
+ const days = parseInt(options.days) || 7;
2028
+ const limit = parseInt(options.limit) || 20;
2029
+ const chain = options.chain?.toLowerCase() || "all";
2030
+ if (!["base", "polygon", "all"].includes(chain)) {
2031
+ console.log("\u274C Invalid chain. Use: base, polygon, or all");
2032
+ return;
2033
+ }
2034
+ const wallet = client.address;
2035
+ const cutoffTime = Date.now() - days * 24 * 60 * 60 * 1e3;
2036
+ const explorers = {
2037
+ base: {
2038
+ api: "https://base.blockscout.com/api/v2",
2039
+ usdc: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
2040
+ name: "Base"
2041
+ },
2042
+ polygon: {
2043
+ api: "https://polygon.blockscout.com/api/v2",
2044
+ usdc: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
2045
+ name: "Polygon"
2046
+ }
2047
+ };
2048
+ const chainsToQuery = chain === "all" ? ["base", "polygon"] : [chain];
2049
+ console.log(`
2050
+ \u{1F4DC} Transactions (last ${days} day${days > 1 ? "s" : ""})
2051
+ `);
2052
+ let allTxns = [];
2053
+ for (const c of chainsToQuery) {
2054
+ const explorer = explorers[c];
2055
+ try {
2056
+ const url = `${explorer.api}/addresses/${wallet}/token-transfers?type=ERC-20&token=${explorer.usdc}`;
2057
+ const response = await fetch(url);
2058
+ const data = await response.json();
2059
+ if (data.items && Array.isArray(data.items)) {
2060
+ for (const tx of data.items) {
2061
+ const timestamp = new Date(tx.timestamp).getTime();
2062
+ if (timestamp < cutoffTime) continue;
2063
+ const isIncoming = tx.to.hash.toLowerCase() === wallet.toLowerCase();
2064
+ const decimals = parseInt(tx.total.decimals) || 6;
2065
+ allTxns.push({
2066
+ chain: c,
2067
+ timestamp,
2068
+ type: isIncoming ? "IN" : "OUT",
2069
+ amount: parseInt(tx.total.value) / Math.pow(10, decimals),
2070
+ other: isIncoming ? tx.from.hash : tx.to.hash,
2071
+ hash: tx.transaction_hash
2072
+ });
2073
+ }
2074
+ }
2075
+ } catch (error) {
2076
+ console.log(` \u26A0\uFE0F ${explorer.name}: API error`);
2077
+ }
2078
+ }
2079
+ allTxns.sort((a, b) => b.timestamp - a.timestamp);
2080
+ allTxns = allTxns.slice(0, limit);
2081
+ if (allTxns.length === 0) {
2082
+ console.log(" (no transactions found)\n");
2083
+ } else {
2084
+ for (const tx of allTxns) {
2085
+ const sign = tx.type === "IN" ? "+" : "-";
2086
+ const color = tx.type === "IN" ? "\x1B[32m" : "\x1B[31m";
2087
+ const reset = "\x1B[0m";
2088
+ const date = new Date(tx.timestamp).toISOString().slice(5, 16).replace("T", " ");
2089
+ const chainTag = chain === "all" ? `[${tx.chain.toUpperCase()}] ` : "";
2090
+ console.log(` ${color}${sign}${tx.amount.toFixed(2)} USDC${reset} | ${chainTag}${tx.type === "IN" ? "from" : "to"} ${tx.other.slice(0, 10)}...${tx.other.slice(-4)} | ${date}`);
2091
+ }
2092
+ const inTotal = allTxns.filter((t) => t.type === "IN").reduce((s, t) => s + t.amount, 0);
2093
+ const outTotal = allTxns.filter((t) => t.type === "OUT").reduce((s, t) => s + t.amount, 0);
2094
+ console.log(`
2095
+ \u{1F4CA} ${allTxns.length} transaction(s) | \x1B[32m+$${inTotal.toFixed(2)}\x1B[0m in | \x1B[31m-$${outTotal.toFixed(2)}\x1B[0m out
2096
+ `);
2097
+ }
2098
+ });
1928
2099
  program.command("services <url>").description("List services from a provider").option("--json", "Output as JSON").action(async (url, options) => {
1929
2100
  try {
1930
2101
  const client = new MoltsPayClient();
@@ -1932,20 +2103,31 @@ program.command("services <url>").description("List services from a provider").o
1932
2103
  if (options.json) {
1933
2104
  console.log(JSON.stringify(services, null, 2));
1934
2105
  } else {
1935
- console.log(`
2106
+ if (services.provider) {
2107
+ console.log(`
1936
2108
  \u{1F3EA} ${services.provider.name}
1937
2109
  `);
1938
- console.log(` ${services.provider.description || ""}`);
1939
- console.log(` Wallet: ${services.provider.wallet}`);
1940
- console.log(` Chain: ${services.provider.chain}`);
2110
+ console.log(` ${services.provider.description || ""}`);
2111
+ console.log(` Wallet: ${services.provider.wallet}`);
2112
+ const chains = services.provider.chains ? Array.isArray(services.provider.chains) ? services.provider.chains.map((c) => typeof c === "string" ? c : c.chain).join(", ") : services.provider.chains : services.provider.chain || "base";
2113
+ console.log(` Chains: ${chains}`);
2114
+ } else {
2115
+ console.log(`
2116
+ \u{1F3EA} MoltsPay Service Registry
2117
+ `);
2118
+ console.log(` ${services.services?.length || 0} services available`);
2119
+ }
1941
2120
  console.log("\n\u{1F4E6} Services:\n");
1942
2121
  for (const svc of services.services) {
1943
- const status = svc.available ? "\u2705" : "\u274C";
1944
- console.log(` ${status} ${svc.id}`);
2122
+ const status = svc.available !== false ? "\u2705" : "\u274C";
2123
+ console.log(` ${status} ${svc.id || svc.name}`);
1945
2124
  console.log(` ${svc.name} - $${svc.price} ${svc.currency}`);
1946
2125
  if (svc.description) {
1947
2126
  console.log(` ${svc.description}`);
1948
2127
  }
2128
+ if (svc.provider && !services.provider) {
2129
+ console.log(` Provider: ${svc.provider.name || svc.provider.username}`);
2130
+ }
1949
2131
  console.log("");
1950
2132
  }
1951
2133
  }