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 +192 -10
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/index.mjs +201 -16
- package/dist/cli/index.mjs.map +1 -1
- package/dist/client/index.d.mts +7 -2
- package/dist/client/index.d.ts +7 -2
- package/dist/client/index.js +13 -4
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +13 -4
- package/dist/client/index.mjs.map +1 -1
- package/dist/index.js +13 -4
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +13 -4
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -2
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
|
|
222
|
-
|
|
223
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2106
|
+
if (services.provider) {
|
|
2107
|
+
console.log(`
|
|
1936
2108
|
\u{1F3EA} ${services.provider.name}
|
|
1937
2109
|
`);
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
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
|
}
|