moltspay 0.9.5 → 0.9.7
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/README.md +68 -45
- 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 +201 -38
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/index.mjs +201 -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 +112 -15
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +112 -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 +203 -42
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +203 -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/index.mjs
CHANGED
|
@@ -30802,16 +30802,24 @@ var X402_VERSION2 = 2;
|
|
|
30802
30802
|
var PAYMENT_REQUIRED_HEADER = "x-payment-required";
|
|
30803
30803
|
var PAYMENT_HEADER = "x-payment";
|
|
30804
30804
|
var PAYMENT_RESPONSE_HEADER = "x-payment-response";
|
|
30805
|
-
var
|
|
30806
|
-
"eip155:8453":
|
|
30807
|
-
|
|
30808
|
-
|
|
30809
|
-
|
|
30805
|
+
var TOKEN_ADDRESSES = {
|
|
30806
|
+
"eip155:8453": {
|
|
30807
|
+
USDC: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
|
30808
|
+
USDT: "0xfde4C96c8593536E31F229EA8f37b2ADa2699bb2"
|
|
30809
|
+
},
|
|
30810
|
+
"eip155:84532": {
|
|
30811
|
+
USDC: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
|
|
30812
|
+
USDT: "0x036CbD53842c5426634e7929541eC2318f3dCF7e"
|
|
30813
|
+
// Same as USDC on testnet
|
|
30814
|
+
}
|
|
30810
30815
|
};
|
|
30811
|
-
var
|
|
30812
|
-
name: "USD Coin",
|
|
30813
|
-
version: "2"
|
|
30816
|
+
var TOKEN_DOMAINS = {
|
|
30817
|
+
USDC: { name: "USD Coin", version: "2" },
|
|
30818
|
+
USDT: { name: "Tether USD", version: "2" }
|
|
30814
30819
|
};
|
|
30820
|
+
function getAcceptedCurrencies(config) {
|
|
30821
|
+
return config.acceptedCurrencies ?? [config.currency];
|
|
30822
|
+
}
|
|
30815
30823
|
function loadEnvFile2() {
|
|
30816
30824
|
const envPaths = [
|
|
30817
30825
|
path3.join(process.cwd(), ".env"),
|
|
@@ -30959,6 +30967,7 @@ var MoltsPayServer = class {
|
|
|
30959
30967
|
description: s.description,
|
|
30960
30968
|
price: s.price,
|
|
30961
30969
|
currency: s.currency,
|
|
30970
|
+
acceptedCurrencies: getAcceptedCurrencies(s),
|
|
30962
30971
|
input: s.input,
|
|
30963
30972
|
output: s.output,
|
|
30964
30973
|
available: this.skills.has(s.id)
|
|
@@ -30996,6 +31005,7 @@ var MoltsPayServer = class {
|
|
|
30996
31005
|
description: s.description,
|
|
30997
31006
|
price: s.price,
|
|
30998
31007
|
currency: s.currency,
|
|
31008
|
+
acceptedCurrencies: getAcceptedCurrencies(s),
|
|
30999
31009
|
input: s.input,
|
|
31000
31010
|
output: s.output,
|
|
31001
31011
|
available: this.skills.has(s.id)
|
|
@@ -31062,7 +31072,14 @@ var MoltsPayServer = class {
|
|
|
31062
31072
|
if (!validation.valid) {
|
|
31063
31073
|
return this.sendJson(res, 402, { error: validation.error });
|
|
31064
31074
|
}
|
|
31065
|
-
const
|
|
31075
|
+
const paymentToken = this.detectPaymentToken(payment);
|
|
31076
|
+
if (paymentToken && !this.isTokenAccepted(skill.config, paymentToken)) {
|
|
31077
|
+
const accepted = getAcceptedCurrencies(skill.config);
|
|
31078
|
+
return this.sendJson(res, 402, {
|
|
31079
|
+
error: `Token ${paymentToken} not accepted. Accepted: ${accepted.join(", ")}`
|
|
31080
|
+
});
|
|
31081
|
+
}
|
|
31082
|
+
const requirements = this.buildPaymentRequirements(skill.config, paymentToken);
|
|
31066
31083
|
console.log(`[MoltsPay] Verifying payment...`);
|
|
31067
31084
|
const verifyResult = await this.registry.verify(payment, requirements);
|
|
31068
31085
|
if (!verifyResult.valid) {
|
|
@@ -31117,12 +31134,15 @@ var MoltsPayServer = class {
|
|
|
31117
31134
|
}
|
|
31118
31135
|
/**
|
|
31119
31136
|
* Return 402 with x402 payment requirements (v2 format)
|
|
31137
|
+
* Includes requirements for all accepted currencies
|
|
31120
31138
|
*/
|
|
31121
31139
|
sendPaymentRequired(config, res) {
|
|
31122
|
-
const
|
|
31140
|
+
const acceptedTokens = getAcceptedCurrencies(config);
|
|
31141
|
+
const accepts = acceptedTokens.map((token) => this.buildPaymentRequirements(config, token));
|
|
31123
31142
|
const paymentRequired = {
|
|
31124
31143
|
x402Version: X402_VERSION2,
|
|
31125
|
-
accepts
|
|
31144
|
+
accepts,
|
|
31145
|
+
acceptedCurrencies: acceptedTokens,
|
|
31126
31146
|
resource: {
|
|
31127
31147
|
url: `/execute?service=${config.id}`,
|
|
31128
31148
|
description: `${config.name} - $${config.price} ${config.currency}`,
|
|
@@ -31137,6 +31157,7 @@ var MoltsPayServer = class {
|
|
|
31137
31157
|
res.end(JSON.stringify({
|
|
31138
31158
|
error: "Payment required",
|
|
31139
31159
|
message: `Service requires $${config.price} ${config.currency}`,
|
|
31160
|
+
acceptedCurrencies: acceptedTokens,
|
|
31140
31161
|
x402: paymentRequired
|
|
31141
31162
|
}, null, 2));
|
|
31142
31163
|
}
|
|
@@ -31159,20 +31180,47 @@ var MoltsPayServer = class {
|
|
|
31159
31180
|
}
|
|
31160
31181
|
/**
|
|
31161
31182
|
* Build payment requirements for facilitator
|
|
31183
|
+
* Returns requirements for the primary currency (USDC by default)
|
|
31184
|
+
* Server accepts any of the acceptedCurrencies
|
|
31162
31185
|
*/
|
|
31163
|
-
buildPaymentRequirements(config) {
|
|
31186
|
+
buildPaymentRequirements(config, token) {
|
|
31164
31187
|
const amountInUnits = Math.floor(config.price * 1e6).toString();
|
|
31165
|
-
const
|
|
31188
|
+
const acceptedTokens = getAcceptedCurrencies(config);
|
|
31189
|
+
const selectedToken = token && acceptedTokens.includes(token) ? token : acceptedTokens[0];
|
|
31190
|
+
const tokenAddresses = TOKEN_ADDRESSES[this.networkId] || {};
|
|
31191
|
+
const tokenAddress = tokenAddresses[selectedToken];
|
|
31192
|
+
const tokenDomain = TOKEN_DOMAINS[selectedToken] || TOKEN_DOMAINS.USDC;
|
|
31166
31193
|
return {
|
|
31167
31194
|
scheme: "exact",
|
|
31168
31195
|
network: this.networkId,
|
|
31169
|
-
asset:
|
|
31196
|
+
asset: tokenAddress,
|
|
31170
31197
|
amount: amountInUnits,
|
|
31171
31198
|
payTo: this.manifest.provider.wallet,
|
|
31172
31199
|
maxTimeoutSeconds: 300,
|
|
31173
|
-
extra:
|
|
31200
|
+
extra: tokenDomain
|
|
31174
31201
|
};
|
|
31175
31202
|
}
|
|
31203
|
+
/**
|
|
31204
|
+
* Detect which token is being used in the payment
|
|
31205
|
+
*/
|
|
31206
|
+
detectPaymentToken(payment) {
|
|
31207
|
+
const asset = payment.accepted?.asset || payment.payload?.asset;
|
|
31208
|
+
if (!asset) return void 0;
|
|
31209
|
+
const tokenAddresses = TOKEN_ADDRESSES[this.networkId] || {};
|
|
31210
|
+
for (const [symbol, address] of Object.entries(tokenAddresses)) {
|
|
31211
|
+
if (address.toLowerCase() === asset.toLowerCase()) {
|
|
31212
|
+
return symbol;
|
|
31213
|
+
}
|
|
31214
|
+
}
|
|
31215
|
+
return void 0;
|
|
31216
|
+
}
|
|
31217
|
+
/**
|
|
31218
|
+
* Check if payment token is accepted for service
|
|
31219
|
+
*/
|
|
31220
|
+
isTokenAccepted(config, token) {
|
|
31221
|
+
const accepted = getAcceptedCurrencies(config);
|
|
31222
|
+
return accepted.includes(token);
|
|
31223
|
+
}
|
|
31176
31224
|
async readBody(req) {
|
|
31177
31225
|
return new Promise((resolve, reject) => {
|
|
31178
31226
|
let body = "";
|
|
@@ -31372,18 +31420,22 @@ var MoltsPayServer = class {
|
|
|
31372
31420
|
/**
|
|
31373
31421
|
* Build payment requirements for proxy endpoint (uses provided wallet)
|
|
31374
31422
|
*/
|
|
31375
|
-
buildProxyPaymentRequirements(config, wallet) {
|
|
31423
|
+
buildProxyPaymentRequirements(config, wallet, token) {
|
|
31376
31424
|
const amountInUnits = Math.floor(config.price * 1e6).toString();
|
|
31377
|
-
const
|
|
31425
|
+
const acceptedTokens = getAcceptedCurrencies(config);
|
|
31426
|
+
const selectedToken = token && acceptedTokens.includes(token) ? token : acceptedTokens[0];
|
|
31427
|
+
const tokenAddresses = TOKEN_ADDRESSES[this.networkId] || {};
|
|
31428
|
+
const tokenAddress = tokenAddresses[selectedToken];
|
|
31429
|
+
const tokenDomain = TOKEN_DOMAINS[selectedToken] || TOKEN_DOMAINS.USDC;
|
|
31378
31430
|
return {
|
|
31379
31431
|
scheme: "exact",
|
|
31380
31432
|
network: this.networkId,
|
|
31381
|
-
asset:
|
|
31433
|
+
asset: tokenAddress,
|
|
31382
31434
|
amount: amountInUnits,
|
|
31383
31435
|
payTo: wallet,
|
|
31384
31436
|
// Use provided wallet, not manifest
|
|
31385
31437
|
maxTimeoutSeconds: 300,
|
|
31386
|
-
extra:
|
|
31438
|
+
extra: tokenDomain
|
|
31387
31439
|
};
|
|
31388
31440
|
}
|
|
31389
31441
|
/**
|
|
@@ -31429,7 +31481,20 @@ var CHAINS = {
|
|
|
31429
31481
|
name: "Base",
|
|
31430
31482
|
chainId: 8453,
|
|
31431
31483
|
rpc: "https://mainnet.base.org",
|
|
31484
|
+
tokens: {
|
|
31485
|
+
USDC: {
|
|
31486
|
+
address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
|
31487
|
+
decimals: 6,
|
|
31488
|
+
symbol: "USDC"
|
|
31489
|
+
},
|
|
31490
|
+
USDT: {
|
|
31491
|
+
address: "0xfde4C96c8593536E31F229EA8f37b2ADa2699bb2",
|
|
31492
|
+
decimals: 6,
|
|
31493
|
+
symbol: "USDT"
|
|
31494
|
+
}
|
|
31495
|
+
},
|
|
31432
31496
|
usdc: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
|
31497
|
+
// deprecated, for backward compat
|
|
31433
31498
|
explorer: "https://basescan.org/address/",
|
|
31434
31499
|
explorerTx: "https://basescan.org/tx/",
|
|
31435
31500
|
avgBlockTime: 2
|
|
@@ -31438,6 +31503,18 @@ var CHAINS = {
|
|
|
31438
31503
|
name: "Polygon",
|
|
31439
31504
|
chainId: 137,
|
|
31440
31505
|
rpc: "https://polygon-rpc.com",
|
|
31506
|
+
tokens: {
|
|
31507
|
+
USDC: {
|
|
31508
|
+
address: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
|
|
31509
|
+
decimals: 6,
|
|
31510
|
+
symbol: "USDC"
|
|
31511
|
+
},
|
|
31512
|
+
USDT: {
|
|
31513
|
+
address: "0xc2132D05D31c914a87C6611C10748AEb04B58e8F",
|
|
31514
|
+
decimals: 6,
|
|
31515
|
+
symbol: "USDT"
|
|
31516
|
+
}
|
|
31517
|
+
},
|
|
31441
31518
|
usdc: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
|
|
31442
31519
|
explorer: "https://polygonscan.com/address/",
|
|
31443
31520
|
explorerTx: "https://polygonscan.com/tx/",
|
|
@@ -31447,6 +31524,18 @@ var CHAINS = {
|
|
|
31447
31524
|
name: "Ethereum",
|
|
31448
31525
|
chainId: 1,
|
|
31449
31526
|
rpc: "https://eth.llamarpc.com",
|
|
31527
|
+
tokens: {
|
|
31528
|
+
USDC: {
|
|
31529
|
+
address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
|
31530
|
+
decimals: 6,
|
|
31531
|
+
symbol: "USDC"
|
|
31532
|
+
},
|
|
31533
|
+
USDT: {
|
|
31534
|
+
address: "0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
|
31535
|
+
decimals: 6,
|
|
31536
|
+
symbol: "USDT"
|
|
31537
|
+
}
|
|
31538
|
+
},
|
|
31450
31539
|
usdc: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
|
31451
31540
|
explorer: "https://etherscan.io/address/",
|
|
31452
31541
|
explorerTx: "https://etherscan.io/tx/",
|
|
@@ -31457,6 +31546,19 @@ var CHAINS = {
|
|
|
31457
31546
|
name: "Base Sepolia",
|
|
31458
31547
|
chainId: 84532,
|
|
31459
31548
|
rpc: "https://sepolia.base.org",
|
|
31549
|
+
tokens: {
|
|
31550
|
+
USDC: {
|
|
31551
|
+
address: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
|
|
31552
|
+
decimals: 6,
|
|
31553
|
+
symbol: "USDC"
|
|
31554
|
+
},
|
|
31555
|
+
USDT: {
|
|
31556
|
+
address: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
|
|
31557
|
+
// Same as USDC on testnet (no official USDT)
|
|
31558
|
+
decimals: 6,
|
|
31559
|
+
symbol: "USDT"
|
|
31560
|
+
}
|
|
31561
|
+
},
|
|
31460
31562
|
usdc: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
|
|
31461
31563
|
explorer: "https://sepolia.basescan.org/address/",
|
|
31462
31564
|
explorerTx: "https://sepolia.basescan.org/tx/",
|
|
@@ -31466,6 +31568,19 @@ var CHAINS = {
|
|
|
31466
31568
|
name: "Sepolia",
|
|
31467
31569
|
chainId: 11155111,
|
|
31468
31570
|
rpc: "https://rpc.sepolia.org",
|
|
31571
|
+
tokens: {
|
|
31572
|
+
USDC: {
|
|
31573
|
+
address: "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238",
|
|
31574
|
+
decimals: 6,
|
|
31575
|
+
symbol: "USDC"
|
|
31576
|
+
},
|
|
31577
|
+
USDT: {
|
|
31578
|
+
address: "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238",
|
|
31579
|
+
// Same as USDC on testnet
|
|
31580
|
+
decimals: 6,
|
|
31581
|
+
symbol: "USDT"
|
|
31582
|
+
}
|
|
31583
|
+
},
|
|
31469
31584
|
usdc: "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238",
|
|
31470
31585
|
explorer: "https://sepolia.etherscan.io/address/",
|
|
31471
31586
|
explorerTx: "https://sepolia.etherscan.io/tx/",
|
|
@@ -31574,8 +31689,13 @@ var MoltsPayClient = class {
|
|
|
31574
31689
|
*
|
|
31575
31690
|
* This is GASLESS for the client - server pays gas to claim payment.
|
|
31576
31691
|
* This is PAY-FOR-SUCCESS - payment only claimed if service succeeds.
|
|
31692
|
+
*
|
|
31693
|
+
* @param serverUrl - Server URL
|
|
31694
|
+
* @param service - Service ID
|
|
31695
|
+
* @param params - Service parameters
|
|
31696
|
+
* @param options - Payment options (token selection)
|
|
31577
31697
|
*/
|
|
31578
|
-
async pay(serverUrl, service, params) {
|
|
31698
|
+
async pay(serverUrl, service, params, options = {}) {
|
|
31579
31699
|
if (!this.wallet || !this.walletData) {
|
|
31580
31700
|
throw new Error("Client not initialized. Run: npx moltspay init");
|
|
31581
31701
|
}
|
|
@@ -31622,12 +31742,35 @@ var MoltsPayClient = class {
|
|
|
31622
31742
|
}
|
|
31623
31743
|
const amount = Number(amountRaw) / 1e6;
|
|
31624
31744
|
this.checkLimits(amount);
|
|
31625
|
-
|
|
31745
|
+
let token = options.token || "USDC";
|
|
31746
|
+
if (options.autoSelect) {
|
|
31747
|
+
const balances = await this.getBalance();
|
|
31748
|
+
if (balances.usdc >= amount) {
|
|
31749
|
+
token = "USDC";
|
|
31750
|
+
} else if (balances.usdt >= amount) {
|
|
31751
|
+
token = "USDT";
|
|
31752
|
+
} else {
|
|
31753
|
+
throw new Error(`Insufficient balance: need $${amount}, have ${balances.usdc} USDC / ${balances.usdt} USDT`);
|
|
31754
|
+
}
|
|
31755
|
+
}
|
|
31756
|
+
if (token === "USDT") {
|
|
31757
|
+
const balances = await this.getBalance();
|
|
31758
|
+
if (balances.native < 1e-4) {
|
|
31759
|
+
throw new Error(
|
|
31760
|
+
`USDT requires ETH for gas (~$0.01 on Base). Your ETH balance: ${balances.native.toFixed(6)} ETH. Please add a small amount of ETH to your wallet, or use USDC (gasless).`
|
|
31761
|
+
);
|
|
31762
|
+
}
|
|
31763
|
+
console.log(`[MoltsPay] \u26A0\uFE0F USDT requires gas (~$0.01). Proceeding with payment...`);
|
|
31764
|
+
} else {
|
|
31765
|
+
console.log(`[MoltsPay] Signing payment: $${amount} ${token} (gasless)`);
|
|
31766
|
+
}
|
|
31626
31767
|
const payTo = req.payTo || req.resource;
|
|
31627
31768
|
if (!payTo) {
|
|
31628
31769
|
throw new Error("Missing payTo address in payment requirements");
|
|
31629
31770
|
}
|
|
31630
|
-
const authorization = await this.signEIP3009(payTo, amount, chain2);
|
|
31771
|
+
const authorization = await this.signEIP3009(payTo, amount, chain2, token);
|
|
31772
|
+
const tokenConfig = chain2.tokens[token];
|
|
31773
|
+
const tokenName = token === "USDC" ? "USD Coin" : "Tether USD";
|
|
31631
31774
|
const payload = {
|
|
31632
31775
|
x402Version: X402_VERSION3,
|
|
31633
31776
|
payload: authorization,
|
|
@@ -31635,11 +31778,11 @@ var MoltsPayClient = class {
|
|
|
31635
31778
|
accepted: {
|
|
31636
31779
|
scheme: "exact",
|
|
31637
31780
|
network,
|
|
31638
|
-
asset:
|
|
31781
|
+
asset: tokenConfig.address,
|
|
31639
31782
|
amount: amountRaw,
|
|
31640
31783
|
payTo,
|
|
31641
31784
|
maxTimeoutSeconds: req.maxTimeoutSeconds || 300,
|
|
31642
|
-
extra: req.extra || { name:
|
|
31785
|
+
extra: req.extra || { name: tokenName, version: "2" }
|
|
31643
31786
|
}
|
|
31644
31787
|
};
|
|
31645
31788
|
const paymentHeader = Buffer.from(JSON.stringify(payload)).toString("base64");
|
|
@@ -31663,12 +31806,14 @@ var MoltsPayClient = class {
|
|
|
31663
31806
|
/**
|
|
31664
31807
|
* Sign EIP-3009 transferWithAuthorization (GASLESS)
|
|
31665
31808
|
* This only signs - no on-chain transaction, no gas needed.
|
|
31809
|
+
* Supports both USDC and USDT.
|
|
31666
31810
|
*/
|
|
31667
|
-
async signEIP3009(to, amount, chain2) {
|
|
31811
|
+
async signEIP3009(to, amount, chain2, token = "USDC") {
|
|
31668
31812
|
const validAfter = 0;
|
|
31669
31813
|
const validBefore = Math.floor(Date.now() / 1e3) + 3600;
|
|
31670
31814
|
const nonce = ethers.hexlify(ethers.randomBytes(32));
|
|
31671
|
-
const
|
|
31815
|
+
const tokenConfig = chain2.tokens[token];
|
|
31816
|
+
const value = BigInt(Math.floor(amount * 10 ** tokenConfig.decimals)).toString();
|
|
31672
31817
|
const authorization = {
|
|
31673
31818
|
from: this.wallet.address,
|
|
31674
31819
|
to,
|
|
@@ -31677,11 +31822,12 @@ var MoltsPayClient = class {
|
|
|
31677
31822
|
validBefore: validBefore.toString(),
|
|
31678
31823
|
nonce
|
|
31679
31824
|
};
|
|
31825
|
+
const tokenName = token === "USDC" ? "USD Coin" : "Tether USD";
|
|
31680
31826
|
const domain = {
|
|
31681
|
-
name:
|
|
31827
|
+
name: tokenName,
|
|
31682
31828
|
version: "2",
|
|
31683
31829
|
chainId: chain2.chainId,
|
|
31684
|
-
verifyingContract:
|
|
31830
|
+
verifyingContract: tokenConfig.address
|
|
31685
31831
|
};
|
|
31686
31832
|
const types = {
|
|
31687
31833
|
TransferWithAuthorization: [
|
|
@@ -31816,7 +31962,7 @@ var MoltsPayClient = class {
|
|
|
31816
31962
|
return { address: wallet.address, configDir };
|
|
31817
31963
|
}
|
|
31818
31964
|
/**
|
|
31819
|
-
* Get wallet balance
|
|
31965
|
+
* Get wallet balance (USDC, USDT, and native token)
|
|
31820
31966
|
*/
|
|
31821
31967
|
async getBalance() {
|
|
31822
31968
|
if (!this.wallet) {
|
|
@@ -31829,12 +31975,15 @@ var MoltsPayClient = class {
|
|
|
31829
31975
|
throw new Error(`Unknown chain: ${this.config.chain}`);
|
|
31830
31976
|
}
|
|
31831
31977
|
const provider = new ethers.JsonRpcProvider(chain2.rpc);
|
|
31832
|
-
const
|
|
31833
|
-
const
|
|
31834
|
-
|
|
31835
|
-
|
|
31978
|
+
const tokenAbi = ["function balanceOf(address) view returns (uint256)"];
|
|
31979
|
+
const [nativeBalance, usdcBalance, usdtBalance] = await Promise.all([
|
|
31980
|
+
provider.getBalance(this.wallet.address),
|
|
31981
|
+
new ethers.Contract(chain2.tokens.USDC.address, tokenAbi, provider).balanceOf(this.wallet.address),
|
|
31982
|
+
new ethers.Contract(chain2.tokens.USDT.address, tokenAbi, provider).balanceOf(this.wallet.address)
|
|
31983
|
+
]);
|
|
31836
31984
|
return {
|
|
31837
|
-
usdc: parseFloat(ethers.formatUnits(usdcBalance,
|
|
31985
|
+
usdc: parseFloat(ethers.formatUnits(usdcBalance, chain2.tokens.USDC.decimals)),
|
|
31986
|
+
usdt: parseFloat(ethers.formatUnits(usdtBalance, chain2.tokens.USDT.decimals)),
|
|
31838
31987
|
native: parseFloat(ethers.formatEther(nativeBalance))
|
|
31839
31988
|
};
|
|
31840
31989
|
}
|
|
@@ -31970,7 +32119,7 @@ init_esm_shims();
|
|
|
31970
32119
|
import { ethers as ethers4 } from "ethers";
|
|
31971
32120
|
var TRANSFER_EVENT_TOPIC = ethers4.id("Transfer(address,address,uint256)");
|
|
31972
32121
|
async function verifyPayment(params) {
|
|
31973
|
-
const { txHash, expectedAmount, expectedTo } = params;
|
|
32122
|
+
const { txHash, expectedAmount, expectedTo, expectedToken } = params;
|
|
31974
32123
|
let chain2;
|
|
31975
32124
|
try {
|
|
31976
32125
|
if (typeof params.chain === "number") {
|
|
@@ -31993,12 +32142,20 @@ async function verifyPayment(params) {
|
|
|
31993
32142
|
if (receipt.status !== 1) {
|
|
31994
32143
|
return { verified: false, error: "Transaction failed" };
|
|
31995
32144
|
}
|
|
31996
|
-
const
|
|
31997
|
-
if (!
|
|
31998
|
-
|
|
32145
|
+
const tokenAddresses = {};
|
|
32146
|
+
if (!expectedToken || expectedToken === "USDC") {
|
|
32147
|
+
tokenAddresses[chain2.tokens.USDC.address.toLowerCase()] = "USDC";
|
|
32148
|
+
}
|
|
32149
|
+
if (!expectedToken || expectedToken === "USDT") {
|
|
32150
|
+
tokenAddresses[chain2.tokens.USDT.address.toLowerCase()] = "USDT";
|
|
32151
|
+
}
|
|
32152
|
+
if (Object.keys(tokenAddresses).length === 0) {
|
|
32153
|
+
return { verified: false, error: `No token addresses configured for ${chain2.name}` };
|
|
31999
32154
|
}
|
|
32000
32155
|
for (const log of receipt.logs) {
|
|
32001
|
-
|
|
32156
|
+
const logAddress = log.address.toLowerCase();
|
|
32157
|
+
const detectedToken = tokenAddresses[logAddress];
|
|
32158
|
+
if (!detectedToken) {
|
|
32002
32159
|
continue;
|
|
32003
32160
|
}
|
|
32004
32161
|
if (log.topics.length < 3 || log.topics[0] !== TRANSFER_EVENT_TOPIC) {
|
|
@@ -32007,15 +32164,17 @@ async function verifyPayment(params) {
|
|
|
32007
32164
|
const from = "0x" + log.topics[1].slice(-40);
|
|
32008
32165
|
const to = "0x" + log.topics[2].slice(-40);
|
|
32009
32166
|
const amountRaw = BigInt(log.data);
|
|
32010
|
-
const
|
|
32167
|
+
const tokenConfig = chain2.tokens[detectedToken];
|
|
32168
|
+
const amount = Number(amountRaw) / 10 ** tokenConfig.decimals;
|
|
32011
32169
|
if (expectedTo && to.toLowerCase() !== expectedTo.toLowerCase()) {
|
|
32012
32170
|
continue;
|
|
32013
32171
|
}
|
|
32014
32172
|
if (amount < expectedAmount) {
|
|
32015
32173
|
return {
|
|
32016
32174
|
verified: false,
|
|
32017
|
-
error: `Insufficient amount: received ${amount}
|
|
32175
|
+
error: `Insufficient amount: received ${amount} ${detectedToken}, expected ${expectedAmount}`,
|
|
32018
32176
|
amount,
|
|
32177
|
+
token: detectedToken,
|
|
32019
32178
|
from,
|
|
32020
32179
|
to,
|
|
32021
32180
|
txHash,
|
|
@@ -32025,13 +32184,15 @@ async function verifyPayment(params) {
|
|
|
32025
32184
|
return {
|
|
32026
32185
|
verified: true,
|
|
32027
32186
|
amount,
|
|
32187
|
+
token: detectedToken,
|
|
32028
32188
|
from,
|
|
32029
32189
|
to,
|
|
32030
32190
|
txHash,
|
|
32031
32191
|
blockNumber: receipt.blockNumber
|
|
32032
32192
|
};
|
|
32033
32193
|
}
|
|
32034
|
-
|
|
32194
|
+
const tokenList = expectedToken ? expectedToken : "USDC/USDT";
|
|
32195
|
+
return { verified: false, error: `No ${tokenList} transfer found` };
|
|
32035
32196
|
} catch (e) {
|
|
32036
32197
|
return { verified: false, error: e.message || String(e) };
|
|
32037
32198
|
}
|