moltspay 0.9.5 → 0.9.6
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/cdp/index.d.mts +1 -1
- package/dist/cdp/index.d.ts +1 -1
- package/dist/cdp/index.js +63 -0
- package/dist/cdp/index.js.map +1 -1
- package/dist/cdp/index.mjs +63 -0
- package/dist/cdp/index.mjs.map +1 -1
- package/dist/chains/index.d.mts +9 -5
- package/dist/chains/index.d.ts +9 -5
- package/dist/chains/index.js +85 -0
- package/dist/chains/index.js.map +1 -1
- package/dist/chains/index.mjs +83 -0
- package/dist/chains/index.mjs.map +1 -1
- package/dist/cli/index.js +179 -38
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/index.mjs +179 -38
- package/dist/cli/index.mjs.map +1 -1
- package/dist/client/index.d.mts +18 -3
- package/dist/client/index.d.ts +18 -3
- package/dist/client/index.js +102 -15
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +102 -15
- package/dist/client/index.mjs.map +1 -1
- package/dist/{index-Dg8n6wdW.d.mts → index-B3v8IWjM.d.mts} +11 -1
- package/dist/{index-Dg8n6wdW.d.ts → index-B3v8IWjM.d.ts} +11 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +193 -42
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +193 -42
- package/dist/index.mjs.map +1 -1
- package/dist/server/index.d.mts +19 -1
- package/dist/server/index.d.ts +19 -1
- package/dist/server/index.js +71 -19
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +71 -19
- package/dist/server/index.mjs.map +1 -1
- package/dist/verify/index.d.mts +7 -0
- package/dist/verify/index.d.ts +7 -0
- package/dist/verify/index.js +83 -8
- package/dist/verify/index.js.map +1 -1
- package/dist/verify/index.mjs +83 -8
- package/dist/verify/index.mjs.map +1 -1
- package/dist/wallet/index.d.mts +16 -8
- package/dist/wallet/index.d.ts +16 -8
- package/dist/wallet/index.js +114 -18
- package/dist/wallet/index.js.map +1 -1
- package/dist/wallet/index.mjs +114 -18
- package/dist/wallet/index.mjs.map +1 -1
- package/package.json +1 -1
- package/schemas/moltspay.services.schema.json +13 -3
package/dist/cli/index.js
CHANGED
|
@@ -43,7 +43,20 @@ var CHAINS = {
|
|
|
43
43
|
name: "Base",
|
|
44
44
|
chainId: 8453,
|
|
45
45
|
rpc: "https://mainnet.base.org",
|
|
46
|
+
tokens: {
|
|
47
|
+
USDC: {
|
|
48
|
+
address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
|
49
|
+
decimals: 6,
|
|
50
|
+
symbol: "USDC"
|
|
51
|
+
},
|
|
52
|
+
USDT: {
|
|
53
|
+
address: "0xfde4C96c8593536E31F229EA8f37b2ADa2699bb2",
|
|
54
|
+
decimals: 6,
|
|
55
|
+
symbol: "USDT"
|
|
56
|
+
}
|
|
57
|
+
},
|
|
46
58
|
usdc: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
|
59
|
+
// deprecated, for backward compat
|
|
47
60
|
explorer: "https://basescan.org/address/",
|
|
48
61
|
explorerTx: "https://basescan.org/tx/",
|
|
49
62
|
avgBlockTime: 2
|
|
@@ -52,6 +65,18 @@ var CHAINS = {
|
|
|
52
65
|
name: "Polygon",
|
|
53
66
|
chainId: 137,
|
|
54
67
|
rpc: "https://polygon-rpc.com",
|
|
68
|
+
tokens: {
|
|
69
|
+
USDC: {
|
|
70
|
+
address: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
|
|
71
|
+
decimals: 6,
|
|
72
|
+
symbol: "USDC"
|
|
73
|
+
},
|
|
74
|
+
USDT: {
|
|
75
|
+
address: "0xc2132D05D31c914a87C6611C10748AEb04B58e8F",
|
|
76
|
+
decimals: 6,
|
|
77
|
+
symbol: "USDT"
|
|
78
|
+
}
|
|
79
|
+
},
|
|
55
80
|
usdc: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
|
|
56
81
|
explorer: "https://polygonscan.com/address/",
|
|
57
82
|
explorerTx: "https://polygonscan.com/tx/",
|
|
@@ -61,6 +86,18 @@ var CHAINS = {
|
|
|
61
86
|
name: "Ethereum",
|
|
62
87
|
chainId: 1,
|
|
63
88
|
rpc: "https://eth.llamarpc.com",
|
|
89
|
+
tokens: {
|
|
90
|
+
USDC: {
|
|
91
|
+
address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
|
92
|
+
decimals: 6,
|
|
93
|
+
symbol: "USDC"
|
|
94
|
+
},
|
|
95
|
+
USDT: {
|
|
96
|
+
address: "0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
|
97
|
+
decimals: 6,
|
|
98
|
+
symbol: "USDT"
|
|
99
|
+
}
|
|
100
|
+
},
|
|
64
101
|
usdc: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
|
65
102
|
explorer: "https://etherscan.io/address/",
|
|
66
103
|
explorerTx: "https://etherscan.io/tx/",
|
|
@@ -71,6 +108,19 @@ var CHAINS = {
|
|
|
71
108
|
name: "Base Sepolia",
|
|
72
109
|
chainId: 84532,
|
|
73
110
|
rpc: "https://sepolia.base.org",
|
|
111
|
+
tokens: {
|
|
112
|
+
USDC: {
|
|
113
|
+
address: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
|
|
114
|
+
decimals: 6,
|
|
115
|
+
symbol: "USDC"
|
|
116
|
+
},
|
|
117
|
+
USDT: {
|
|
118
|
+
address: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
|
|
119
|
+
// Same as USDC on testnet (no official USDT)
|
|
120
|
+
decimals: 6,
|
|
121
|
+
symbol: "USDT"
|
|
122
|
+
}
|
|
123
|
+
},
|
|
74
124
|
usdc: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
|
|
75
125
|
explorer: "https://sepolia.basescan.org/address/",
|
|
76
126
|
explorerTx: "https://sepolia.basescan.org/tx/",
|
|
@@ -80,6 +130,19 @@ var CHAINS = {
|
|
|
80
130
|
name: "Sepolia",
|
|
81
131
|
chainId: 11155111,
|
|
82
132
|
rpc: "https://rpc.sepolia.org",
|
|
133
|
+
tokens: {
|
|
134
|
+
USDC: {
|
|
135
|
+
address: "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238",
|
|
136
|
+
decimals: 6,
|
|
137
|
+
symbol: "USDC"
|
|
138
|
+
},
|
|
139
|
+
USDT: {
|
|
140
|
+
address: "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238",
|
|
141
|
+
// Same as USDC on testnet
|
|
142
|
+
decimals: 6,
|
|
143
|
+
symbol: "USDT"
|
|
144
|
+
}
|
|
145
|
+
},
|
|
83
146
|
usdc: "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238",
|
|
84
147
|
explorer: "https://sepolia.etherscan.io/address/",
|
|
85
148
|
explorerTx: "https://sepolia.etherscan.io/tx/",
|
|
@@ -166,8 +229,13 @@ var MoltsPayClient = class {
|
|
|
166
229
|
*
|
|
167
230
|
* This is GASLESS for the client - server pays gas to claim payment.
|
|
168
231
|
* This is PAY-FOR-SUCCESS - payment only claimed if service succeeds.
|
|
232
|
+
*
|
|
233
|
+
* @param serverUrl - Server URL
|
|
234
|
+
* @param service - Service ID
|
|
235
|
+
* @param params - Service parameters
|
|
236
|
+
* @param options - Payment options (token selection)
|
|
169
237
|
*/
|
|
170
|
-
async pay(serverUrl, service, params) {
|
|
238
|
+
async pay(serverUrl, service, params, options = {}) {
|
|
171
239
|
if (!this.wallet || !this.walletData) {
|
|
172
240
|
throw new Error("Client not initialized. Run: npx moltspay init");
|
|
173
241
|
}
|
|
@@ -214,12 +282,25 @@ var MoltsPayClient = class {
|
|
|
214
282
|
}
|
|
215
283
|
const amount = Number(amountRaw) / 1e6;
|
|
216
284
|
this.checkLimits(amount);
|
|
217
|
-
|
|
285
|
+
let token = options.token || "USDC";
|
|
286
|
+
if (options.autoSelect) {
|
|
287
|
+
const balances = await this.getBalance();
|
|
288
|
+
if (balances.usdc >= amount) {
|
|
289
|
+
token = "USDC";
|
|
290
|
+
} else if (balances.usdt >= amount) {
|
|
291
|
+
token = "USDT";
|
|
292
|
+
} else {
|
|
293
|
+
throw new Error(`Insufficient balance: need $${amount}, have ${balances.usdc} USDC / ${balances.usdt} USDT`);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
console.log(`[MoltsPay] Signing payment: $${amount} ${token} (gasless)`);
|
|
218
297
|
const payTo = req.payTo || req.resource;
|
|
219
298
|
if (!payTo) {
|
|
220
299
|
throw new Error("Missing payTo address in payment requirements");
|
|
221
300
|
}
|
|
222
|
-
const authorization = await this.signEIP3009(payTo, amount, chain);
|
|
301
|
+
const authorization = await this.signEIP3009(payTo, amount, chain, token);
|
|
302
|
+
const tokenConfig = chain.tokens[token];
|
|
303
|
+
const tokenName = token === "USDC" ? "USD Coin" : "Tether USD";
|
|
223
304
|
const payload = {
|
|
224
305
|
x402Version: X402_VERSION,
|
|
225
306
|
payload: authorization,
|
|
@@ -227,11 +308,11 @@ var MoltsPayClient = class {
|
|
|
227
308
|
accepted: {
|
|
228
309
|
scheme: "exact",
|
|
229
310
|
network,
|
|
230
|
-
asset:
|
|
311
|
+
asset: tokenConfig.address,
|
|
231
312
|
amount: amountRaw,
|
|
232
313
|
payTo,
|
|
233
314
|
maxTimeoutSeconds: req.maxTimeoutSeconds || 300,
|
|
234
|
-
extra: req.extra || { name:
|
|
315
|
+
extra: req.extra || { name: tokenName, version: "2" }
|
|
235
316
|
}
|
|
236
317
|
};
|
|
237
318
|
const paymentHeader = Buffer.from(JSON.stringify(payload)).toString("base64");
|
|
@@ -255,12 +336,14 @@ var MoltsPayClient = class {
|
|
|
255
336
|
/**
|
|
256
337
|
* Sign EIP-3009 transferWithAuthorization (GASLESS)
|
|
257
338
|
* This only signs - no on-chain transaction, no gas needed.
|
|
339
|
+
* Supports both USDC and USDT.
|
|
258
340
|
*/
|
|
259
|
-
async signEIP3009(to, amount, chain) {
|
|
341
|
+
async signEIP3009(to, amount, chain, token = "USDC") {
|
|
260
342
|
const validAfter = 0;
|
|
261
343
|
const validBefore = Math.floor(Date.now() / 1e3) + 3600;
|
|
262
344
|
const nonce = import_ethers.ethers.hexlify(import_ethers.ethers.randomBytes(32));
|
|
263
|
-
const
|
|
345
|
+
const tokenConfig = chain.tokens[token];
|
|
346
|
+
const value = BigInt(Math.floor(amount * 10 ** tokenConfig.decimals)).toString();
|
|
264
347
|
const authorization = {
|
|
265
348
|
from: this.wallet.address,
|
|
266
349
|
to,
|
|
@@ -269,11 +352,12 @@ var MoltsPayClient = class {
|
|
|
269
352
|
validBefore: validBefore.toString(),
|
|
270
353
|
nonce
|
|
271
354
|
};
|
|
355
|
+
const tokenName = token === "USDC" ? "USD Coin" : "Tether USD";
|
|
272
356
|
const domain = {
|
|
273
|
-
name:
|
|
357
|
+
name: tokenName,
|
|
274
358
|
version: "2",
|
|
275
359
|
chainId: chain.chainId,
|
|
276
|
-
verifyingContract:
|
|
360
|
+
verifyingContract: tokenConfig.address
|
|
277
361
|
};
|
|
278
362
|
const types = {
|
|
279
363
|
TransferWithAuthorization: [
|
|
@@ -408,7 +492,7 @@ var MoltsPayClient = class {
|
|
|
408
492
|
return { address: wallet.address, configDir };
|
|
409
493
|
}
|
|
410
494
|
/**
|
|
411
|
-
* Get wallet balance
|
|
495
|
+
* Get wallet balance (USDC, USDT, and native token)
|
|
412
496
|
*/
|
|
413
497
|
async getBalance() {
|
|
414
498
|
if (!this.wallet) {
|
|
@@ -421,12 +505,15 @@ var MoltsPayClient = class {
|
|
|
421
505
|
throw new Error(`Unknown chain: ${this.config.chain}`);
|
|
422
506
|
}
|
|
423
507
|
const provider = new import_ethers.ethers.JsonRpcProvider(chain.rpc);
|
|
424
|
-
const
|
|
425
|
-
const
|
|
426
|
-
|
|
427
|
-
|
|
508
|
+
const tokenAbi = ["function balanceOf(address) view returns (uint256)"];
|
|
509
|
+
const [nativeBalance, usdcBalance, usdtBalance] = await Promise.all([
|
|
510
|
+
provider.getBalance(this.wallet.address),
|
|
511
|
+
new import_ethers.ethers.Contract(chain.tokens.USDC.address, tokenAbi, provider).balanceOf(this.wallet.address),
|
|
512
|
+
new import_ethers.ethers.Contract(chain.tokens.USDT.address, tokenAbi, provider).balanceOf(this.wallet.address)
|
|
513
|
+
]);
|
|
428
514
|
return {
|
|
429
|
-
usdc: parseFloat(import_ethers.ethers.formatUnits(usdcBalance,
|
|
515
|
+
usdc: parseFloat(import_ethers.ethers.formatUnits(usdcBalance, chain.tokens.USDC.decimals)),
|
|
516
|
+
usdt: parseFloat(import_ethers.ethers.formatUnits(usdtBalance, chain.tokens.USDT.decimals)),
|
|
430
517
|
native: parseFloat(import_ethers.ethers.formatEther(nativeBalance))
|
|
431
518
|
};
|
|
432
519
|
}
|
|
@@ -886,16 +973,24 @@ var X402_VERSION3 = 2;
|
|
|
886
973
|
var PAYMENT_REQUIRED_HEADER2 = "x-payment-required";
|
|
887
974
|
var PAYMENT_HEADER2 = "x-payment";
|
|
888
975
|
var PAYMENT_RESPONSE_HEADER = "x-payment-response";
|
|
889
|
-
var
|
|
890
|
-
"eip155:8453":
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
976
|
+
var TOKEN_ADDRESSES = {
|
|
977
|
+
"eip155:8453": {
|
|
978
|
+
USDC: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
|
979
|
+
USDT: "0xfde4C96c8593536E31F229EA8f37b2ADa2699bb2"
|
|
980
|
+
},
|
|
981
|
+
"eip155:84532": {
|
|
982
|
+
USDC: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
|
|
983
|
+
USDT: "0x036CbD53842c5426634e7929541eC2318f3dCF7e"
|
|
984
|
+
// Same as USDC on testnet
|
|
985
|
+
}
|
|
894
986
|
};
|
|
895
|
-
var
|
|
896
|
-
name: "USD Coin",
|
|
897
|
-
version: "2"
|
|
987
|
+
var TOKEN_DOMAINS = {
|
|
988
|
+
USDC: { name: "USD Coin", version: "2" },
|
|
989
|
+
USDT: { name: "Tether USD", version: "2" }
|
|
898
990
|
};
|
|
991
|
+
function getAcceptedCurrencies(config) {
|
|
992
|
+
return config.acceptedCurrencies ?? [config.currency];
|
|
993
|
+
}
|
|
899
994
|
function loadEnvFile2() {
|
|
900
995
|
const envPaths = [
|
|
901
996
|
path2.join(process.cwd(), ".env"),
|
|
@@ -1043,6 +1138,7 @@ var MoltsPayServer = class {
|
|
|
1043
1138
|
description: s.description,
|
|
1044
1139
|
price: s.price,
|
|
1045
1140
|
currency: s.currency,
|
|
1141
|
+
acceptedCurrencies: getAcceptedCurrencies(s),
|
|
1046
1142
|
input: s.input,
|
|
1047
1143
|
output: s.output,
|
|
1048
1144
|
available: this.skills.has(s.id)
|
|
@@ -1080,6 +1176,7 @@ var MoltsPayServer = class {
|
|
|
1080
1176
|
description: s.description,
|
|
1081
1177
|
price: s.price,
|
|
1082
1178
|
currency: s.currency,
|
|
1179
|
+
acceptedCurrencies: getAcceptedCurrencies(s),
|
|
1083
1180
|
input: s.input,
|
|
1084
1181
|
output: s.output,
|
|
1085
1182
|
available: this.skills.has(s.id)
|
|
@@ -1146,7 +1243,14 @@ var MoltsPayServer = class {
|
|
|
1146
1243
|
if (!validation.valid) {
|
|
1147
1244
|
return this.sendJson(res, 402, { error: validation.error });
|
|
1148
1245
|
}
|
|
1149
|
-
const
|
|
1246
|
+
const paymentToken = this.detectPaymentToken(payment);
|
|
1247
|
+
if (paymentToken && !this.isTokenAccepted(skill.config, paymentToken)) {
|
|
1248
|
+
const accepted = getAcceptedCurrencies(skill.config);
|
|
1249
|
+
return this.sendJson(res, 402, {
|
|
1250
|
+
error: `Token ${paymentToken} not accepted. Accepted: ${accepted.join(", ")}`
|
|
1251
|
+
});
|
|
1252
|
+
}
|
|
1253
|
+
const requirements = this.buildPaymentRequirements(skill.config, paymentToken);
|
|
1150
1254
|
console.log(`[MoltsPay] Verifying payment...`);
|
|
1151
1255
|
const verifyResult = await this.registry.verify(payment, requirements);
|
|
1152
1256
|
if (!verifyResult.valid) {
|
|
@@ -1201,12 +1305,15 @@ var MoltsPayServer = class {
|
|
|
1201
1305
|
}
|
|
1202
1306
|
/**
|
|
1203
1307
|
* Return 402 with x402 payment requirements (v2 format)
|
|
1308
|
+
* Includes requirements for all accepted currencies
|
|
1204
1309
|
*/
|
|
1205
1310
|
sendPaymentRequired(config, res) {
|
|
1206
|
-
const
|
|
1311
|
+
const acceptedTokens = getAcceptedCurrencies(config);
|
|
1312
|
+
const accepts = acceptedTokens.map((token) => this.buildPaymentRequirements(config, token));
|
|
1207
1313
|
const paymentRequired = {
|
|
1208
1314
|
x402Version: X402_VERSION3,
|
|
1209
|
-
accepts
|
|
1315
|
+
accepts,
|
|
1316
|
+
acceptedCurrencies: acceptedTokens,
|
|
1210
1317
|
resource: {
|
|
1211
1318
|
url: `/execute?service=${config.id}`,
|
|
1212
1319
|
description: `${config.name} - $${config.price} ${config.currency}`,
|
|
@@ -1221,6 +1328,7 @@ var MoltsPayServer = class {
|
|
|
1221
1328
|
res.end(JSON.stringify({
|
|
1222
1329
|
error: "Payment required",
|
|
1223
1330
|
message: `Service requires $${config.price} ${config.currency}`,
|
|
1331
|
+
acceptedCurrencies: acceptedTokens,
|
|
1224
1332
|
x402: paymentRequired
|
|
1225
1333
|
}, null, 2));
|
|
1226
1334
|
}
|
|
@@ -1243,20 +1351,47 @@ var MoltsPayServer = class {
|
|
|
1243
1351
|
}
|
|
1244
1352
|
/**
|
|
1245
1353
|
* Build payment requirements for facilitator
|
|
1354
|
+
* Returns requirements for the primary currency (USDC by default)
|
|
1355
|
+
* Server accepts any of the acceptedCurrencies
|
|
1246
1356
|
*/
|
|
1247
|
-
buildPaymentRequirements(config) {
|
|
1357
|
+
buildPaymentRequirements(config, token) {
|
|
1248
1358
|
const amountInUnits = Math.floor(config.price * 1e6).toString();
|
|
1249
|
-
const
|
|
1359
|
+
const acceptedTokens = getAcceptedCurrencies(config);
|
|
1360
|
+
const selectedToken = token && acceptedTokens.includes(token) ? token : acceptedTokens[0];
|
|
1361
|
+
const tokenAddresses = TOKEN_ADDRESSES[this.networkId] || {};
|
|
1362
|
+
const tokenAddress = tokenAddresses[selectedToken];
|
|
1363
|
+
const tokenDomain = TOKEN_DOMAINS[selectedToken] || TOKEN_DOMAINS.USDC;
|
|
1250
1364
|
return {
|
|
1251
1365
|
scheme: "exact",
|
|
1252
1366
|
network: this.networkId,
|
|
1253
|
-
asset:
|
|
1367
|
+
asset: tokenAddress,
|
|
1254
1368
|
amount: amountInUnits,
|
|
1255
1369
|
payTo: this.manifest.provider.wallet,
|
|
1256
1370
|
maxTimeoutSeconds: 300,
|
|
1257
|
-
extra:
|
|
1371
|
+
extra: tokenDomain
|
|
1258
1372
|
};
|
|
1259
1373
|
}
|
|
1374
|
+
/**
|
|
1375
|
+
* Detect which token is being used in the payment
|
|
1376
|
+
*/
|
|
1377
|
+
detectPaymentToken(payment) {
|
|
1378
|
+
const asset = payment.accepted?.asset || payment.payload?.asset;
|
|
1379
|
+
if (!asset) return void 0;
|
|
1380
|
+
const tokenAddresses = TOKEN_ADDRESSES[this.networkId] || {};
|
|
1381
|
+
for (const [symbol, address] of Object.entries(tokenAddresses)) {
|
|
1382
|
+
if (address.toLowerCase() === asset.toLowerCase()) {
|
|
1383
|
+
return symbol;
|
|
1384
|
+
}
|
|
1385
|
+
}
|
|
1386
|
+
return void 0;
|
|
1387
|
+
}
|
|
1388
|
+
/**
|
|
1389
|
+
* Check if payment token is accepted for service
|
|
1390
|
+
*/
|
|
1391
|
+
isTokenAccepted(config, token) {
|
|
1392
|
+
const accepted = getAcceptedCurrencies(config);
|
|
1393
|
+
return accepted.includes(token);
|
|
1394
|
+
}
|
|
1260
1395
|
async readBody(req) {
|
|
1261
1396
|
return new Promise((resolve2, reject) => {
|
|
1262
1397
|
let body = "";
|
|
@@ -1456,18 +1591,22 @@ var MoltsPayServer = class {
|
|
|
1456
1591
|
/**
|
|
1457
1592
|
* Build payment requirements for proxy endpoint (uses provided wallet)
|
|
1458
1593
|
*/
|
|
1459
|
-
buildProxyPaymentRequirements(config, wallet) {
|
|
1594
|
+
buildProxyPaymentRequirements(config, wallet, token) {
|
|
1460
1595
|
const amountInUnits = Math.floor(config.price * 1e6).toString();
|
|
1461
|
-
const
|
|
1596
|
+
const acceptedTokens = getAcceptedCurrencies(config);
|
|
1597
|
+
const selectedToken = token && acceptedTokens.includes(token) ? token : acceptedTokens[0];
|
|
1598
|
+
const tokenAddresses = TOKEN_ADDRESSES[this.networkId] || {};
|
|
1599
|
+
const tokenAddress = tokenAddresses[selectedToken];
|
|
1600
|
+
const tokenDomain = TOKEN_DOMAINS[selectedToken] || TOKEN_DOMAINS.USDC;
|
|
1462
1601
|
return {
|
|
1463
1602
|
scheme: "exact",
|
|
1464
1603
|
network: this.networkId,
|
|
1465
|
-
asset:
|
|
1604
|
+
asset: tokenAddress,
|
|
1466
1605
|
amount: amountInUnits,
|
|
1467
1606
|
payTo: wallet,
|
|
1468
1607
|
// Use provided wallet, not manifest
|
|
1469
1608
|
maxTimeoutSeconds: 300,
|
|
1470
|
-
extra:
|
|
1609
|
+
extra: tokenDomain
|
|
1471
1610
|
};
|
|
1472
1611
|
}
|
|
1473
1612
|
/**
|
|
@@ -1600,7 +1739,7 @@ program.command("status").description("Show wallet status and balance").option("
|
|
|
1600
1739
|
return;
|
|
1601
1740
|
}
|
|
1602
1741
|
const config = client.getConfig();
|
|
1603
|
-
let balance = { usdc: 0, native: 0 };
|
|
1742
|
+
let balance = { usdc: 0, usdt: 0, native: 0 };
|
|
1604
1743
|
try {
|
|
1605
1744
|
balance = await client.getBalance();
|
|
1606
1745
|
} catch (err) {
|
|
@@ -1617,7 +1756,7 @@ program.command("status").description("Show wallet status and balance").option("
|
|
|
1617
1756
|
console.log("\n\u{1F4CA} MoltsPay Status\n");
|
|
1618
1757
|
console.log(` Wallet: ${client.address}`);
|
|
1619
1758
|
console.log(` Chain: ${config.chain}`);
|
|
1620
|
-
console.log(` Balance: ${balance.usdc.toFixed(2)} USDC`);
|
|
1759
|
+
console.log(` Balance: ${balance.usdc.toFixed(2)} USDC | ${balance.usdt.toFixed(2)} USDT`);
|
|
1621
1760
|
console.log(` Native: ${balance.native.toFixed(6)} ETH`);
|
|
1622
1761
|
console.log("");
|
|
1623
1762
|
console.log(" Limits:");
|
|
@@ -1861,7 +2000,7 @@ program.command("stop").description("Stop the running MoltsPay server").action(a
|
|
|
1861
2000
|
process.exit(1);
|
|
1862
2001
|
}
|
|
1863
2002
|
});
|
|
1864
|
-
program.command("pay <server> <service> [params]").description("Pay for a service and get the result").option("--prompt <text>", "Prompt for the service").option("--image <path>", "Image URL or local file path").option("--json", "Output raw JSON only").action(async (server, service, paramsJson, options) => {
|
|
2003
|
+
program.command("pay <server> <service> [params]").description("Pay for a service and get the result").option("--prompt <text>", "Prompt for the service").option("--image <path>", "Image URL or local file path").option("--token <token>", "Token to pay with (USDC or USDT)", "USDC").option("--json", "Output raw JSON only").action(async (server, service, paramsJson, options) => {
|
|
1865
2004
|
const client = new MoltsPayClient();
|
|
1866
2005
|
if (!client.isInitialized) {
|
|
1867
2006
|
console.error("\u274C Wallet not initialized. Run: npx moltspay init");
|
|
@@ -1896,6 +2035,7 @@ program.command("pay <server> <service> [params]").description("Pay for a servic
|
|
|
1896
2035
|
process.exit(1);
|
|
1897
2036
|
}
|
|
1898
2037
|
const imageDisplay = params.image_url || (params.image_base64 ? `[local file: ${options.image}]` : null);
|
|
2038
|
+
const token = (options.token || "USDC").toUpperCase();
|
|
1899
2039
|
if (!options.json) {
|
|
1900
2040
|
console.log(`
|
|
1901
2041
|
\u{1F4B3} MoltsPay - Paying for service
|
|
@@ -1904,11 +2044,12 @@ program.command("pay <server> <service> [params]").description("Pay for a servic
|
|
|
1904
2044
|
console.log(` Service: ${service}`);
|
|
1905
2045
|
console.log(` Prompt: ${params.prompt}`);
|
|
1906
2046
|
if (imageDisplay) console.log(` Image: ${imageDisplay}`);
|
|
2047
|
+
console.log(` Token: ${token}`);
|
|
1907
2048
|
console.log(` Wallet: ${client.address}`);
|
|
1908
2049
|
console.log("");
|
|
1909
2050
|
}
|
|
1910
2051
|
try {
|
|
1911
|
-
const result = await client.pay(server, service, params);
|
|
2052
|
+
const result = await client.pay(server, service, params, { token });
|
|
1912
2053
|
if (options.json) {
|
|
1913
2054
|
console.log(JSON.stringify(result));
|
|
1914
2055
|
} else {
|