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.mjs
CHANGED
|
@@ -20,7 +20,20 @@ var CHAINS = {
|
|
|
20
20
|
name: "Base",
|
|
21
21
|
chainId: 8453,
|
|
22
22
|
rpc: "https://mainnet.base.org",
|
|
23
|
+
tokens: {
|
|
24
|
+
USDC: {
|
|
25
|
+
address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
|
26
|
+
decimals: 6,
|
|
27
|
+
symbol: "USDC"
|
|
28
|
+
},
|
|
29
|
+
USDT: {
|
|
30
|
+
address: "0xfde4C96c8593536E31F229EA8f37b2ADa2699bb2",
|
|
31
|
+
decimals: 6,
|
|
32
|
+
symbol: "USDT"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
23
35
|
usdc: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
|
36
|
+
// deprecated, for backward compat
|
|
24
37
|
explorer: "https://basescan.org/address/",
|
|
25
38
|
explorerTx: "https://basescan.org/tx/",
|
|
26
39
|
avgBlockTime: 2
|
|
@@ -29,6 +42,18 @@ var CHAINS = {
|
|
|
29
42
|
name: "Polygon",
|
|
30
43
|
chainId: 137,
|
|
31
44
|
rpc: "https://polygon-rpc.com",
|
|
45
|
+
tokens: {
|
|
46
|
+
USDC: {
|
|
47
|
+
address: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
|
|
48
|
+
decimals: 6,
|
|
49
|
+
symbol: "USDC"
|
|
50
|
+
},
|
|
51
|
+
USDT: {
|
|
52
|
+
address: "0xc2132D05D31c914a87C6611C10748AEb04B58e8F",
|
|
53
|
+
decimals: 6,
|
|
54
|
+
symbol: "USDT"
|
|
55
|
+
}
|
|
56
|
+
},
|
|
32
57
|
usdc: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
|
|
33
58
|
explorer: "https://polygonscan.com/address/",
|
|
34
59
|
explorerTx: "https://polygonscan.com/tx/",
|
|
@@ -38,6 +63,18 @@ var CHAINS = {
|
|
|
38
63
|
name: "Ethereum",
|
|
39
64
|
chainId: 1,
|
|
40
65
|
rpc: "https://eth.llamarpc.com",
|
|
66
|
+
tokens: {
|
|
67
|
+
USDC: {
|
|
68
|
+
address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
|
69
|
+
decimals: 6,
|
|
70
|
+
symbol: "USDC"
|
|
71
|
+
},
|
|
72
|
+
USDT: {
|
|
73
|
+
address: "0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
|
74
|
+
decimals: 6,
|
|
75
|
+
symbol: "USDT"
|
|
76
|
+
}
|
|
77
|
+
},
|
|
41
78
|
usdc: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
|
42
79
|
explorer: "https://etherscan.io/address/",
|
|
43
80
|
explorerTx: "https://etherscan.io/tx/",
|
|
@@ -48,6 +85,19 @@ var CHAINS = {
|
|
|
48
85
|
name: "Base Sepolia",
|
|
49
86
|
chainId: 84532,
|
|
50
87
|
rpc: "https://sepolia.base.org",
|
|
88
|
+
tokens: {
|
|
89
|
+
USDC: {
|
|
90
|
+
address: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
|
|
91
|
+
decimals: 6,
|
|
92
|
+
symbol: "USDC"
|
|
93
|
+
},
|
|
94
|
+
USDT: {
|
|
95
|
+
address: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
|
|
96
|
+
// Same as USDC on testnet (no official USDT)
|
|
97
|
+
decimals: 6,
|
|
98
|
+
symbol: "USDT"
|
|
99
|
+
}
|
|
100
|
+
},
|
|
51
101
|
usdc: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
|
|
52
102
|
explorer: "https://sepolia.basescan.org/address/",
|
|
53
103
|
explorerTx: "https://sepolia.basescan.org/tx/",
|
|
@@ -57,6 +107,19 @@ var CHAINS = {
|
|
|
57
107
|
name: "Sepolia",
|
|
58
108
|
chainId: 11155111,
|
|
59
109
|
rpc: "https://rpc.sepolia.org",
|
|
110
|
+
tokens: {
|
|
111
|
+
USDC: {
|
|
112
|
+
address: "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238",
|
|
113
|
+
decimals: 6,
|
|
114
|
+
symbol: "USDC"
|
|
115
|
+
},
|
|
116
|
+
USDT: {
|
|
117
|
+
address: "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238",
|
|
118
|
+
// Same as USDC on testnet
|
|
119
|
+
decimals: 6,
|
|
120
|
+
symbol: "USDT"
|
|
121
|
+
}
|
|
122
|
+
},
|
|
60
123
|
usdc: "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238",
|
|
61
124
|
explorer: "https://sepolia.etherscan.io/address/",
|
|
62
125
|
explorerTx: "https://sepolia.etherscan.io/tx/",
|
|
@@ -143,8 +206,13 @@ var MoltsPayClient = class {
|
|
|
143
206
|
*
|
|
144
207
|
* This is GASLESS for the client - server pays gas to claim payment.
|
|
145
208
|
* This is PAY-FOR-SUCCESS - payment only claimed if service succeeds.
|
|
209
|
+
*
|
|
210
|
+
* @param serverUrl - Server URL
|
|
211
|
+
* @param service - Service ID
|
|
212
|
+
* @param params - Service parameters
|
|
213
|
+
* @param options - Payment options (token selection)
|
|
146
214
|
*/
|
|
147
|
-
async pay(serverUrl, service, params) {
|
|
215
|
+
async pay(serverUrl, service, params, options = {}) {
|
|
148
216
|
if (!this.wallet || !this.walletData) {
|
|
149
217
|
throw new Error("Client not initialized. Run: npx moltspay init");
|
|
150
218
|
}
|
|
@@ -191,12 +259,25 @@ var MoltsPayClient = class {
|
|
|
191
259
|
}
|
|
192
260
|
const amount = Number(amountRaw) / 1e6;
|
|
193
261
|
this.checkLimits(amount);
|
|
194
|
-
|
|
262
|
+
let token = options.token || "USDC";
|
|
263
|
+
if (options.autoSelect) {
|
|
264
|
+
const balances = await this.getBalance();
|
|
265
|
+
if (balances.usdc >= amount) {
|
|
266
|
+
token = "USDC";
|
|
267
|
+
} else if (balances.usdt >= amount) {
|
|
268
|
+
token = "USDT";
|
|
269
|
+
} else {
|
|
270
|
+
throw new Error(`Insufficient balance: need $${amount}, have ${balances.usdc} USDC / ${balances.usdt} USDT`);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
console.log(`[MoltsPay] Signing payment: $${amount} ${token} (gasless)`);
|
|
195
274
|
const payTo = req.payTo || req.resource;
|
|
196
275
|
if (!payTo) {
|
|
197
276
|
throw new Error("Missing payTo address in payment requirements");
|
|
198
277
|
}
|
|
199
|
-
const authorization = await this.signEIP3009(payTo, amount, chain);
|
|
278
|
+
const authorization = await this.signEIP3009(payTo, amount, chain, token);
|
|
279
|
+
const tokenConfig = chain.tokens[token];
|
|
280
|
+
const tokenName = token === "USDC" ? "USD Coin" : "Tether USD";
|
|
200
281
|
const payload = {
|
|
201
282
|
x402Version: X402_VERSION,
|
|
202
283
|
payload: authorization,
|
|
@@ -204,11 +285,11 @@ var MoltsPayClient = class {
|
|
|
204
285
|
accepted: {
|
|
205
286
|
scheme: "exact",
|
|
206
287
|
network,
|
|
207
|
-
asset:
|
|
288
|
+
asset: tokenConfig.address,
|
|
208
289
|
amount: amountRaw,
|
|
209
290
|
payTo,
|
|
210
291
|
maxTimeoutSeconds: req.maxTimeoutSeconds || 300,
|
|
211
|
-
extra: req.extra || { name:
|
|
292
|
+
extra: req.extra || { name: tokenName, version: "2" }
|
|
212
293
|
}
|
|
213
294
|
};
|
|
214
295
|
const paymentHeader = Buffer.from(JSON.stringify(payload)).toString("base64");
|
|
@@ -232,12 +313,14 @@ var MoltsPayClient = class {
|
|
|
232
313
|
/**
|
|
233
314
|
* Sign EIP-3009 transferWithAuthorization (GASLESS)
|
|
234
315
|
* This only signs - no on-chain transaction, no gas needed.
|
|
316
|
+
* Supports both USDC and USDT.
|
|
235
317
|
*/
|
|
236
|
-
async signEIP3009(to, amount, chain) {
|
|
318
|
+
async signEIP3009(to, amount, chain, token = "USDC") {
|
|
237
319
|
const validAfter = 0;
|
|
238
320
|
const validBefore = Math.floor(Date.now() / 1e3) + 3600;
|
|
239
321
|
const nonce = ethers.hexlify(ethers.randomBytes(32));
|
|
240
|
-
const
|
|
322
|
+
const tokenConfig = chain.tokens[token];
|
|
323
|
+
const value = BigInt(Math.floor(amount * 10 ** tokenConfig.decimals)).toString();
|
|
241
324
|
const authorization = {
|
|
242
325
|
from: this.wallet.address,
|
|
243
326
|
to,
|
|
@@ -246,11 +329,12 @@ var MoltsPayClient = class {
|
|
|
246
329
|
validBefore: validBefore.toString(),
|
|
247
330
|
nonce
|
|
248
331
|
};
|
|
332
|
+
const tokenName = token === "USDC" ? "USD Coin" : "Tether USD";
|
|
249
333
|
const domain = {
|
|
250
|
-
name:
|
|
334
|
+
name: tokenName,
|
|
251
335
|
version: "2",
|
|
252
336
|
chainId: chain.chainId,
|
|
253
|
-
verifyingContract:
|
|
337
|
+
verifyingContract: tokenConfig.address
|
|
254
338
|
};
|
|
255
339
|
const types = {
|
|
256
340
|
TransferWithAuthorization: [
|
|
@@ -385,7 +469,7 @@ var MoltsPayClient = class {
|
|
|
385
469
|
return { address: wallet.address, configDir };
|
|
386
470
|
}
|
|
387
471
|
/**
|
|
388
|
-
* Get wallet balance
|
|
472
|
+
* Get wallet balance (USDC, USDT, and native token)
|
|
389
473
|
*/
|
|
390
474
|
async getBalance() {
|
|
391
475
|
if (!this.wallet) {
|
|
@@ -398,12 +482,15 @@ var MoltsPayClient = class {
|
|
|
398
482
|
throw new Error(`Unknown chain: ${this.config.chain}`);
|
|
399
483
|
}
|
|
400
484
|
const provider = new ethers.JsonRpcProvider(chain.rpc);
|
|
401
|
-
const
|
|
402
|
-
const
|
|
403
|
-
|
|
404
|
-
|
|
485
|
+
const tokenAbi = ["function balanceOf(address) view returns (uint256)"];
|
|
486
|
+
const [nativeBalance, usdcBalance, usdtBalance] = await Promise.all([
|
|
487
|
+
provider.getBalance(this.wallet.address),
|
|
488
|
+
new ethers.Contract(chain.tokens.USDC.address, tokenAbi, provider).balanceOf(this.wallet.address),
|
|
489
|
+
new ethers.Contract(chain.tokens.USDT.address, tokenAbi, provider).balanceOf(this.wallet.address)
|
|
490
|
+
]);
|
|
405
491
|
return {
|
|
406
|
-
usdc: parseFloat(ethers.formatUnits(usdcBalance,
|
|
492
|
+
usdc: parseFloat(ethers.formatUnits(usdcBalance, chain.tokens.USDC.decimals)),
|
|
493
|
+
usdt: parseFloat(ethers.formatUnits(usdtBalance, chain.tokens.USDT.decimals)),
|
|
407
494
|
native: parseFloat(ethers.formatEther(nativeBalance))
|
|
408
495
|
};
|
|
409
496
|
}
|
|
@@ -863,16 +950,24 @@ var X402_VERSION3 = 2;
|
|
|
863
950
|
var PAYMENT_REQUIRED_HEADER2 = "x-payment-required";
|
|
864
951
|
var PAYMENT_HEADER2 = "x-payment";
|
|
865
952
|
var PAYMENT_RESPONSE_HEADER = "x-payment-response";
|
|
866
|
-
var
|
|
867
|
-
"eip155:8453":
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
953
|
+
var TOKEN_ADDRESSES = {
|
|
954
|
+
"eip155:8453": {
|
|
955
|
+
USDC: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
|
956
|
+
USDT: "0xfde4C96c8593536E31F229EA8f37b2ADa2699bb2"
|
|
957
|
+
},
|
|
958
|
+
"eip155:84532": {
|
|
959
|
+
USDC: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
|
|
960
|
+
USDT: "0x036CbD53842c5426634e7929541eC2318f3dCF7e"
|
|
961
|
+
// Same as USDC on testnet
|
|
962
|
+
}
|
|
871
963
|
};
|
|
872
|
-
var
|
|
873
|
-
name: "USD Coin",
|
|
874
|
-
version: "2"
|
|
964
|
+
var TOKEN_DOMAINS = {
|
|
965
|
+
USDC: { name: "USD Coin", version: "2" },
|
|
966
|
+
USDT: { name: "Tether USD", version: "2" }
|
|
875
967
|
};
|
|
968
|
+
function getAcceptedCurrencies(config) {
|
|
969
|
+
return config.acceptedCurrencies ?? [config.currency];
|
|
970
|
+
}
|
|
876
971
|
function loadEnvFile2() {
|
|
877
972
|
const envPaths = [
|
|
878
973
|
path2.join(process.cwd(), ".env"),
|
|
@@ -1020,6 +1115,7 @@ var MoltsPayServer = class {
|
|
|
1020
1115
|
description: s.description,
|
|
1021
1116
|
price: s.price,
|
|
1022
1117
|
currency: s.currency,
|
|
1118
|
+
acceptedCurrencies: getAcceptedCurrencies(s),
|
|
1023
1119
|
input: s.input,
|
|
1024
1120
|
output: s.output,
|
|
1025
1121
|
available: this.skills.has(s.id)
|
|
@@ -1057,6 +1153,7 @@ var MoltsPayServer = class {
|
|
|
1057
1153
|
description: s.description,
|
|
1058
1154
|
price: s.price,
|
|
1059
1155
|
currency: s.currency,
|
|
1156
|
+
acceptedCurrencies: getAcceptedCurrencies(s),
|
|
1060
1157
|
input: s.input,
|
|
1061
1158
|
output: s.output,
|
|
1062
1159
|
available: this.skills.has(s.id)
|
|
@@ -1123,7 +1220,14 @@ var MoltsPayServer = class {
|
|
|
1123
1220
|
if (!validation.valid) {
|
|
1124
1221
|
return this.sendJson(res, 402, { error: validation.error });
|
|
1125
1222
|
}
|
|
1126
|
-
const
|
|
1223
|
+
const paymentToken = this.detectPaymentToken(payment);
|
|
1224
|
+
if (paymentToken && !this.isTokenAccepted(skill.config, paymentToken)) {
|
|
1225
|
+
const accepted = getAcceptedCurrencies(skill.config);
|
|
1226
|
+
return this.sendJson(res, 402, {
|
|
1227
|
+
error: `Token ${paymentToken} not accepted. Accepted: ${accepted.join(", ")}`
|
|
1228
|
+
});
|
|
1229
|
+
}
|
|
1230
|
+
const requirements = this.buildPaymentRequirements(skill.config, paymentToken);
|
|
1127
1231
|
console.log(`[MoltsPay] Verifying payment...`);
|
|
1128
1232
|
const verifyResult = await this.registry.verify(payment, requirements);
|
|
1129
1233
|
if (!verifyResult.valid) {
|
|
@@ -1178,12 +1282,15 @@ var MoltsPayServer = class {
|
|
|
1178
1282
|
}
|
|
1179
1283
|
/**
|
|
1180
1284
|
* Return 402 with x402 payment requirements (v2 format)
|
|
1285
|
+
* Includes requirements for all accepted currencies
|
|
1181
1286
|
*/
|
|
1182
1287
|
sendPaymentRequired(config, res) {
|
|
1183
|
-
const
|
|
1288
|
+
const acceptedTokens = getAcceptedCurrencies(config);
|
|
1289
|
+
const accepts = acceptedTokens.map((token) => this.buildPaymentRequirements(config, token));
|
|
1184
1290
|
const paymentRequired = {
|
|
1185
1291
|
x402Version: X402_VERSION3,
|
|
1186
|
-
accepts
|
|
1292
|
+
accepts,
|
|
1293
|
+
acceptedCurrencies: acceptedTokens,
|
|
1187
1294
|
resource: {
|
|
1188
1295
|
url: `/execute?service=${config.id}`,
|
|
1189
1296
|
description: `${config.name} - $${config.price} ${config.currency}`,
|
|
@@ -1198,6 +1305,7 @@ var MoltsPayServer = class {
|
|
|
1198
1305
|
res.end(JSON.stringify({
|
|
1199
1306
|
error: "Payment required",
|
|
1200
1307
|
message: `Service requires $${config.price} ${config.currency}`,
|
|
1308
|
+
acceptedCurrencies: acceptedTokens,
|
|
1201
1309
|
x402: paymentRequired
|
|
1202
1310
|
}, null, 2));
|
|
1203
1311
|
}
|
|
@@ -1220,20 +1328,47 @@ var MoltsPayServer = class {
|
|
|
1220
1328
|
}
|
|
1221
1329
|
/**
|
|
1222
1330
|
* Build payment requirements for facilitator
|
|
1331
|
+
* Returns requirements for the primary currency (USDC by default)
|
|
1332
|
+
* Server accepts any of the acceptedCurrencies
|
|
1223
1333
|
*/
|
|
1224
|
-
buildPaymentRequirements(config) {
|
|
1334
|
+
buildPaymentRequirements(config, token) {
|
|
1225
1335
|
const amountInUnits = Math.floor(config.price * 1e6).toString();
|
|
1226
|
-
const
|
|
1336
|
+
const acceptedTokens = getAcceptedCurrencies(config);
|
|
1337
|
+
const selectedToken = token && acceptedTokens.includes(token) ? token : acceptedTokens[0];
|
|
1338
|
+
const tokenAddresses = TOKEN_ADDRESSES[this.networkId] || {};
|
|
1339
|
+
const tokenAddress = tokenAddresses[selectedToken];
|
|
1340
|
+
const tokenDomain = TOKEN_DOMAINS[selectedToken] || TOKEN_DOMAINS.USDC;
|
|
1227
1341
|
return {
|
|
1228
1342
|
scheme: "exact",
|
|
1229
1343
|
network: this.networkId,
|
|
1230
|
-
asset:
|
|
1344
|
+
asset: tokenAddress,
|
|
1231
1345
|
amount: amountInUnits,
|
|
1232
1346
|
payTo: this.manifest.provider.wallet,
|
|
1233
1347
|
maxTimeoutSeconds: 300,
|
|
1234
|
-
extra:
|
|
1348
|
+
extra: tokenDomain
|
|
1235
1349
|
};
|
|
1236
1350
|
}
|
|
1351
|
+
/**
|
|
1352
|
+
* Detect which token is being used in the payment
|
|
1353
|
+
*/
|
|
1354
|
+
detectPaymentToken(payment) {
|
|
1355
|
+
const asset = payment.accepted?.asset || payment.payload?.asset;
|
|
1356
|
+
if (!asset) return void 0;
|
|
1357
|
+
const tokenAddresses = TOKEN_ADDRESSES[this.networkId] || {};
|
|
1358
|
+
for (const [symbol, address] of Object.entries(tokenAddresses)) {
|
|
1359
|
+
if (address.toLowerCase() === asset.toLowerCase()) {
|
|
1360
|
+
return symbol;
|
|
1361
|
+
}
|
|
1362
|
+
}
|
|
1363
|
+
return void 0;
|
|
1364
|
+
}
|
|
1365
|
+
/**
|
|
1366
|
+
* Check if payment token is accepted for service
|
|
1367
|
+
*/
|
|
1368
|
+
isTokenAccepted(config, token) {
|
|
1369
|
+
const accepted = getAcceptedCurrencies(config);
|
|
1370
|
+
return accepted.includes(token);
|
|
1371
|
+
}
|
|
1237
1372
|
async readBody(req) {
|
|
1238
1373
|
return new Promise((resolve2, reject) => {
|
|
1239
1374
|
let body = "";
|
|
@@ -1433,18 +1568,22 @@ var MoltsPayServer = class {
|
|
|
1433
1568
|
/**
|
|
1434
1569
|
* Build payment requirements for proxy endpoint (uses provided wallet)
|
|
1435
1570
|
*/
|
|
1436
|
-
buildProxyPaymentRequirements(config, wallet) {
|
|
1571
|
+
buildProxyPaymentRequirements(config, wallet, token) {
|
|
1437
1572
|
const amountInUnits = Math.floor(config.price * 1e6).toString();
|
|
1438
|
-
const
|
|
1573
|
+
const acceptedTokens = getAcceptedCurrencies(config);
|
|
1574
|
+
const selectedToken = token && acceptedTokens.includes(token) ? token : acceptedTokens[0];
|
|
1575
|
+
const tokenAddresses = TOKEN_ADDRESSES[this.networkId] || {};
|
|
1576
|
+
const tokenAddress = tokenAddresses[selectedToken];
|
|
1577
|
+
const tokenDomain = TOKEN_DOMAINS[selectedToken] || TOKEN_DOMAINS.USDC;
|
|
1439
1578
|
return {
|
|
1440
1579
|
scheme: "exact",
|
|
1441
1580
|
network: this.networkId,
|
|
1442
|
-
asset:
|
|
1581
|
+
asset: tokenAddress,
|
|
1443
1582
|
amount: amountInUnits,
|
|
1444
1583
|
payTo: wallet,
|
|
1445
1584
|
// Use provided wallet, not manifest
|
|
1446
1585
|
maxTimeoutSeconds: 300,
|
|
1447
|
-
extra:
|
|
1586
|
+
extra: tokenDomain
|
|
1448
1587
|
};
|
|
1449
1588
|
}
|
|
1450
1589
|
/**
|
|
@@ -1577,7 +1716,7 @@ program.command("status").description("Show wallet status and balance").option("
|
|
|
1577
1716
|
return;
|
|
1578
1717
|
}
|
|
1579
1718
|
const config = client.getConfig();
|
|
1580
|
-
let balance = { usdc: 0, native: 0 };
|
|
1719
|
+
let balance = { usdc: 0, usdt: 0, native: 0 };
|
|
1581
1720
|
try {
|
|
1582
1721
|
balance = await client.getBalance();
|
|
1583
1722
|
} catch (err) {
|
|
@@ -1594,7 +1733,7 @@ program.command("status").description("Show wallet status and balance").option("
|
|
|
1594
1733
|
console.log("\n\u{1F4CA} MoltsPay Status\n");
|
|
1595
1734
|
console.log(` Wallet: ${client.address}`);
|
|
1596
1735
|
console.log(` Chain: ${config.chain}`);
|
|
1597
|
-
console.log(` Balance: ${balance.usdc.toFixed(2)} USDC`);
|
|
1736
|
+
console.log(` Balance: ${balance.usdc.toFixed(2)} USDC | ${balance.usdt.toFixed(2)} USDT`);
|
|
1598
1737
|
console.log(` Native: ${balance.native.toFixed(6)} ETH`);
|
|
1599
1738
|
console.log("");
|
|
1600
1739
|
console.log(" Limits:");
|
|
@@ -1838,7 +1977,7 @@ program.command("stop").description("Stop the running MoltsPay server").action(a
|
|
|
1838
1977
|
process.exit(1);
|
|
1839
1978
|
}
|
|
1840
1979
|
});
|
|
1841
|
-
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) => {
|
|
1980
|
+
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) => {
|
|
1842
1981
|
const client = new MoltsPayClient();
|
|
1843
1982
|
if (!client.isInitialized) {
|
|
1844
1983
|
console.error("\u274C Wallet not initialized. Run: npx moltspay init");
|
|
@@ -1873,6 +2012,7 @@ program.command("pay <server> <service> [params]").description("Pay for a servic
|
|
|
1873
2012
|
process.exit(1);
|
|
1874
2013
|
}
|
|
1875
2014
|
const imageDisplay = params.image_url || (params.image_base64 ? `[local file: ${options.image}]` : null);
|
|
2015
|
+
const token = (options.token || "USDC").toUpperCase();
|
|
1876
2016
|
if (!options.json) {
|
|
1877
2017
|
console.log(`
|
|
1878
2018
|
\u{1F4B3} MoltsPay - Paying for service
|
|
@@ -1881,11 +2021,12 @@ program.command("pay <server> <service> [params]").description("Pay for a servic
|
|
|
1881
2021
|
console.log(` Service: ${service}`);
|
|
1882
2022
|
console.log(` Prompt: ${params.prompt}`);
|
|
1883
2023
|
if (imageDisplay) console.log(` Image: ${imageDisplay}`);
|
|
2024
|
+
console.log(` Token: ${token}`);
|
|
1884
2025
|
console.log(` Wallet: ${client.address}`);
|
|
1885
2026
|
console.log("");
|
|
1886
2027
|
}
|
|
1887
2028
|
try {
|
|
1888
|
-
const result = await client.pay(server, service, params);
|
|
2029
|
+
const result = await client.pay(server, service, params, { token });
|
|
1889
2030
|
if (options.json) {
|
|
1890
2031
|
console.log(JSON.stringify(result));
|
|
1891
2032
|
} else {
|