moltspay 0.9.6 → 1.0.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.
Files changed (43) hide show
  1. package/README.md +110 -48
  2. package/dist/cdp/index.js +1 -1
  3. package/dist/cdp/index.js.map +1 -1
  4. package/dist/cdp/index.mjs +1 -1
  5. package/dist/cdp/index.mjs.map +1 -1
  6. package/dist/chains/index.js +1 -1
  7. package/dist/chains/index.js.map +1 -1
  8. package/dist/chains/index.mjs +1 -1
  9. package/dist/chains/index.mjs.map +1 -1
  10. package/dist/cli/index.js +229 -48
  11. package/dist/cli/index.js.map +1 -1
  12. package/dist/cli/index.mjs +229 -48
  13. package/dist/cli/index.mjs.map +1 -1
  14. package/dist/client/index.d.mts +11 -1
  15. package/dist/client/index.d.ts +11 -1
  16. package/dist/client/index.js +87 -7
  17. package/dist/client/index.js.map +1 -1
  18. package/dist/client/index.mjs +87 -7
  19. package/dist/client/index.mjs.map +1 -1
  20. package/dist/facilitators/index.js +1 -1
  21. package/dist/facilitators/index.js.map +1 -1
  22. package/dist/facilitators/index.mjs +1 -1
  23. package/dist/facilitators/index.mjs.map +1 -1
  24. package/dist/index.js +191 -33
  25. package/dist/index.js.map +1 -1
  26. package/dist/index.mjs +191 -33
  27. package/dist/index.mjs.map +1 -1
  28. package/dist/server/index.d.mts +25 -5
  29. package/dist/server/index.d.ts +25 -5
  30. package/dist/server/index.js +104 -26
  31. package/dist/server/index.js.map +1 -1
  32. package/dist/server/index.mjs +104 -26
  33. package/dist/server/index.mjs.map +1 -1
  34. package/dist/verify/index.js +1 -1
  35. package/dist/verify/index.js.map +1 -1
  36. package/dist/verify/index.mjs +1 -1
  37. package/dist/verify/index.mjs.map +1 -1
  38. package/dist/wallet/index.js +1 -1
  39. package/dist/wallet/index.js.map +1 -1
  40. package/dist/wallet/index.mjs +1 -1
  41. package/dist/wallet/index.mjs.map +1 -1
  42. package/package.json +1 -1
  43. package/schemas/moltspay.services.schema.json +58 -2
package/dist/index.mjs CHANGED
@@ -30396,7 +30396,7 @@ var CDPFacilitator = class extends BaseFacilitator {
30396
30396
  this.apiKeyId = config.apiKeyId || process.env.CDP_API_KEY_ID;
30397
30397
  this.apiKeySecret = config.apiKeySecret || process.env.CDP_API_KEY_SECRET;
30398
30398
  this.endpoint = this.useMainnet ? CDP_MAINNET_URL : CDP_TESTNET_URL;
30399
- this.supportedNetworks = this.useMainnet ? ["eip155:8453"] : ["eip155:8453", "eip155:84532"];
30399
+ this.supportedNetworks = this.useMainnet ? ["eip155:8453", "eip155:137"] : ["eip155:8453", "eip155:84532", "eip155:137"];
30400
30400
  if (this.useMainnet && (!this.apiKeyId || !this.apiKeySecret)) {
30401
30401
  console.warn("[CDPFacilitator] WARNING: Mainnet mode but missing CDP credentials!");
30402
30402
  console.warn("[CDPFacilitator] Set CDP_API_KEY_ID and CDP_API_KEY_SECRET");
@@ -30811,8 +30811,17 @@ var TOKEN_ADDRESSES = {
30811
30811
  USDC: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
30812
30812
  USDT: "0x036CbD53842c5426634e7929541eC2318f3dCF7e"
30813
30813
  // Same as USDC on testnet
30814
+ },
30815
+ "eip155:137": {
30816
+ USDC: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
30817
+ USDT: "0xc2132D05D31c914a87C6611C10748AEb04B58e8F"
30814
30818
  }
30815
30819
  };
30820
+ var CHAIN_TO_NETWORK = {
30821
+ "base": "eip155:8453",
30822
+ "base_sepolia": "eip155:84532",
30823
+ "polygon": "eip155:137"
30824
+ };
30816
30825
  var TOKEN_DOMAINS = {
30817
30826
  USDC: { name: "USD Coin", version: "2" },
30818
30827
  USDT: { name: "Tether USD", version: "2" }
@@ -30878,11 +30887,17 @@ var MoltsPayServer = class {
30878
30887
  };
30879
30888
  this.registry = new FacilitatorRegistry(facilitatorConfig);
30880
30889
  const primaryFacilitator = this.registry.get(facilitatorConfig.primary);
30881
- const networkName = this.useMainnet ? "Base mainnet" : "Base Sepolia (testnet)";
30882
30890
  console.log(`[MoltsPay] Loaded ${this.manifest.services.length} services from ${servicesPath}`);
30883
30891
  console.log(`[MoltsPay] Provider: ${this.manifest.provider.name}`);
30884
30892
  console.log(`[MoltsPay] Receive wallet: ${this.manifest.provider.wallet}`);
30885
- console.log(`[MoltsPay] Network: ${this.networkId} (${networkName})`);
30893
+ const chains = this.manifest.provider.chains;
30894
+ if (chains && chains.length > 0) {
30895
+ const chainNames = chains.map((c) => c.chain || c.network).join(", ");
30896
+ console.log(`[MoltsPay] Chains: ${chainNames} (multi-chain enabled)`);
30897
+ } else {
30898
+ const networkName = this.useMainnet ? "Base mainnet" : "Base Sepolia (testnet)";
30899
+ console.log(`[MoltsPay] Network: ${this.networkId} (${networkName})`);
30900
+ }
30886
30901
  console.log(`[MoltsPay] Facilitator: ${primaryFacilitator.displayName} (${facilitatorConfig.strategy || "failover"})`);
30887
30902
  console.log(`[MoltsPay] Protocol: x402 (gasless for both client AND server)`);
30888
30903
  }
@@ -30897,6 +30912,42 @@ var MoltsPayServer = class {
30897
30912
  this.skills.set(serviceId, { id: serviceId, config, handler });
30898
30913
  return this;
30899
30914
  }
30915
+ /**
30916
+ * Get all configured chains for this provider
30917
+ * Returns array of { network, wallet, tokens } for each chain
30918
+ */
30919
+ getProviderChains() {
30920
+ const provider = this.manifest.provider;
30921
+ if (provider.chains && provider.chains.length > 0) {
30922
+ return provider.chains.map((c) => ({
30923
+ network: c.network || CHAIN_TO_NETWORK[c.chain] || "eip155:8453",
30924
+ wallet: c.wallet || provider.wallet,
30925
+ tokens: c.tokens || ["USDC"]
30926
+ }));
30927
+ }
30928
+ const chain2 = provider.chain || "base";
30929
+ const network = CHAIN_TO_NETWORK[chain2] || this.networkId;
30930
+ return [{
30931
+ network,
30932
+ wallet: provider.wallet,
30933
+ tokens: ["USDC"]
30934
+ }];
30935
+ }
30936
+ /**
30937
+ * Get wallet address for a specific network
30938
+ */
30939
+ getWalletForNetwork(network) {
30940
+ const chains = this.getProviderChains();
30941
+ const chain2 = chains.find((c) => c.network === network);
30942
+ return chain2?.wallet || this.manifest.provider.wallet;
30943
+ }
30944
+ /**
30945
+ * Check if a network is accepted by this provider
30946
+ */
30947
+ isNetworkAccepted(network) {
30948
+ const chains = this.getProviderChains();
30949
+ return chains.some((c) => c.network === network);
30950
+ }
30900
30951
  /**
30901
30952
  * Start HTTP server
30902
30953
  */
@@ -31079,7 +31130,9 @@ var MoltsPayServer = class {
31079
31130
  error: `Token ${paymentToken} not accepted. Accepted: ${accepted.join(", ")}`
31080
31131
  });
31081
31132
  }
31082
- const requirements = this.buildPaymentRequirements(skill.config, paymentToken);
31133
+ const paymentNetwork = payment.accepted?.network || payment.network || this.networkId;
31134
+ const paymentWallet = this.getWalletForNetwork(paymentNetwork);
31135
+ const requirements = this.buildPaymentRequirements(skill.config, paymentNetwork, paymentWallet, paymentToken);
31083
31136
  console.log(`[MoltsPay] Verifying payment...`);
31084
31137
  const verifyResult = await this.registry.verify(payment, requirements);
31085
31138
  if (!verifyResult.valid) {
@@ -31134,15 +31187,29 @@ var MoltsPayServer = class {
31134
31187
  }
31135
31188
  /**
31136
31189
  * Return 402 with x402 payment requirements (v2 format)
31137
- * Includes requirements for all accepted currencies
31190
+ * Includes requirements for all chains and all accepted currencies
31138
31191
  */
31139
31192
  sendPaymentRequired(config, res) {
31140
31193
  const acceptedTokens = getAcceptedCurrencies(config);
31141
- const accepts = acceptedTokens.map((token) => this.buildPaymentRequirements(config, token));
31194
+ const providerChains = this.getProviderChains();
31195
+ const accepts = [];
31196
+ for (const chainConfig of providerChains) {
31197
+ for (const token of acceptedTokens) {
31198
+ if (chainConfig.tokens.includes(token)) {
31199
+ accepts.push(this.buildPaymentRequirements(config, chainConfig.network, chainConfig.wallet, token));
31200
+ }
31201
+ }
31202
+ }
31203
+ const acceptedChains = providerChains.map((c) => {
31204
+ if (c.network === "eip155:8453") return "base";
31205
+ if (c.network === "eip155:137") return "polygon";
31206
+ return c.network;
31207
+ });
31142
31208
  const paymentRequired = {
31143
31209
  x402Version: X402_VERSION2,
31144
31210
  accepts,
31145
31211
  acceptedCurrencies: acceptedTokens,
31212
+ acceptedChains,
31146
31213
  resource: {
31147
31214
  url: `/execute?service=${config.id}`,
31148
31215
  description: `${config.name} - $${config.price} ${config.currency}`,
@@ -31158,6 +31225,7 @@ var MoltsPayServer = class {
31158
31225
  error: "Payment required",
31159
31226
  message: `Service requires $${config.price} ${config.currency}`,
31160
31227
  acceptedCurrencies: acceptedTokens,
31228
+ acceptedChains,
31161
31229
  x402: paymentRequired
31162
31230
  }, null, 2));
31163
31231
  }
@@ -31169,46 +31237,50 @@ var MoltsPayServer = class {
31169
31237
  return { valid: false, error: `Unsupported x402 version: ${payment.x402Version}` };
31170
31238
  }
31171
31239
  const scheme = payment.accepted?.scheme || payment.scheme;
31172
- const network = payment.accepted?.network || payment.network;
31240
+ const network = payment.accepted?.network || payment.network || this.networkId;
31173
31241
  if (scheme !== "exact") {
31174
31242
  return { valid: false, error: `Unsupported scheme: ${scheme}` };
31175
31243
  }
31176
- if (network !== this.networkId) {
31177
- return { valid: false, error: `Network mismatch: expected ${this.networkId}, got ${network}` };
31244
+ if (!this.isNetworkAccepted(network)) {
31245
+ const acceptedChains = this.getProviderChains().map((c) => c.network).join(", ");
31246
+ return { valid: false, error: `Network not accepted: ${network}. Accepted: ${acceptedChains}` };
31178
31247
  }
31179
31248
  return { valid: true };
31180
31249
  }
31181
31250
  /**
31182
31251
  * Build payment requirements for facilitator
31183
- * Returns requirements for the primary currency (USDC by default)
31184
- * Server accepts any of the acceptedCurrencies
31252
+ * Now supports multi-chain: takes network and wallet as parameters
31185
31253
  */
31186
- buildPaymentRequirements(config, token) {
31254
+ buildPaymentRequirements(config, network, wallet, token) {
31187
31255
  const amountInUnits = Math.floor(config.price * 1e6).toString();
31188
31256
  const acceptedTokens = getAcceptedCurrencies(config);
31257
+ const selectedNetwork = network || this.networkId;
31258
+ const selectedWallet = wallet || this.manifest.provider.wallet;
31189
31259
  const selectedToken = token && acceptedTokens.includes(token) ? token : acceptedTokens[0];
31190
- const tokenAddresses = TOKEN_ADDRESSES[this.networkId] || {};
31260
+ const tokenAddresses = TOKEN_ADDRESSES[selectedNetwork] || {};
31191
31261
  const tokenAddress = tokenAddresses[selectedToken];
31192
31262
  const tokenDomain = TOKEN_DOMAINS[selectedToken] || TOKEN_DOMAINS.USDC;
31193
31263
  return {
31194
31264
  scheme: "exact",
31195
- network: this.networkId,
31265
+ network: selectedNetwork,
31196
31266
  asset: tokenAddress,
31197
31267
  amount: amountInUnits,
31198
- payTo: this.manifest.provider.wallet,
31268
+ payTo: selectedWallet,
31199
31269
  maxTimeoutSeconds: 300,
31200
31270
  extra: tokenDomain
31201
31271
  };
31202
31272
  }
31203
31273
  /**
31204
31274
  * Detect which token is being used in the payment
31275
+ * Checks across all supported networks
31205
31276
  */
31206
31277
  detectPaymentToken(payment) {
31207
31278
  const asset = payment.accepted?.asset || payment.payload?.asset;
31208
31279
  if (!asset) return void 0;
31209
- const tokenAddresses = TOKEN_ADDRESSES[this.networkId] || {};
31280
+ const paymentNetwork = payment.accepted?.network || payment.network || this.networkId;
31281
+ const tokenAddresses = TOKEN_ADDRESSES[paymentNetwork] || {};
31210
31282
  for (const [symbol, address] of Object.entries(tokenAddresses)) {
31211
- if (address.toLowerCase() === asset.toLowerCase()) {
31283
+ if (address && address.toLowerCase() === asset.toLowerCase()) {
31212
31284
  return symbol;
31213
31285
  }
31214
31286
  }
@@ -31283,6 +31355,10 @@ var MoltsPayServer = class {
31283
31355
  if (isNaN(amountNum) || amountNum <= 0) {
31284
31356
  return this.sendJson(res, 400, { error: "Invalid amount" });
31285
31357
  }
31358
+ const supportedChains = ["base", "polygon", "base_sepolia"];
31359
+ if (chain2 && !supportedChains.includes(chain2)) {
31360
+ return this.sendJson(res, 400, { error: `Unsupported chain: ${chain2}. Supported: ${supportedChains.join(", ")}` });
31361
+ }
31286
31362
  const proxyConfig = {
31287
31363
  id: serviceId || "proxy",
31288
31364
  name: description || "Proxy Payment",
@@ -31294,9 +31370,9 @@ var MoltsPayServer = class {
31294
31370
  input: {},
31295
31371
  output: {}
31296
31372
  };
31297
- const requirements = this.buildProxyPaymentRequirements(proxyConfig, wallet);
31373
+ const requirements = this.buildProxyPaymentRequirements(proxyConfig, wallet, currency, chain2);
31298
31374
  if (!paymentHeader) {
31299
- return this.sendProxyPaymentRequired(proxyConfig, wallet, memo, res);
31375
+ return this.sendProxyPaymentRequired(proxyConfig, wallet, memo, chain2, res);
31300
31376
  }
31301
31377
  let payment;
31302
31378
  try {
@@ -31313,8 +31389,9 @@ var MoltsPayServer = class {
31313
31389
  if (scheme !== "exact") {
31314
31390
  return this.sendJson(res, 402, { error: `Unsupported scheme: ${scheme}` });
31315
31391
  }
31316
- if (network !== this.networkId) {
31317
- return this.sendJson(res, 402, { error: `Network mismatch: expected ${this.networkId}, got ${network}` });
31392
+ const expectedNetwork = chain2 ? CHAIN_TO_NETWORK[chain2] || this.networkId : this.networkId;
31393
+ if (network !== expectedNetwork) {
31394
+ return this.sendJson(res, 402, { error: `Network mismatch: expected ${expectedNetwork}, got ${network}` });
31318
31395
  }
31319
31396
  console.log(`[MoltsPay] /proxy: Verifying payment for ${wallet}...`);
31320
31397
  const verifyResult = await this.registry.verify(payment, requirements);
@@ -31420,16 +31497,17 @@ var MoltsPayServer = class {
31420
31497
  /**
31421
31498
  * Build payment requirements for proxy endpoint (uses provided wallet)
31422
31499
  */
31423
- buildProxyPaymentRequirements(config, wallet, token) {
31500
+ buildProxyPaymentRequirements(config, wallet, token, chain2) {
31424
31501
  const amountInUnits = Math.floor(config.price * 1e6).toString();
31425
31502
  const acceptedTokens = getAcceptedCurrencies(config);
31503
+ const networkId = chain2 ? CHAIN_TO_NETWORK[chain2] || this.networkId : this.networkId;
31426
31504
  const selectedToken = token && acceptedTokens.includes(token) ? token : acceptedTokens[0];
31427
- const tokenAddresses = TOKEN_ADDRESSES[this.networkId] || {};
31505
+ const tokenAddresses = TOKEN_ADDRESSES[networkId] || TOKEN_ADDRESSES[this.networkId] || {};
31428
31506
  const tokenAddress = tokenAddresses[selectedToken];
31429
31507
  const tokenDomain = TOKEN_DOMAINS[selectedToken] || TOKEN_DOMAINS.USDC;
31430
31508
  return {
31431
31509
  scheme: "exact",
31432
- network: this.networkId,
31510
+ network: networkId,
31433
31511
  asset: tokenAddress,
31434
31512
  amount: amountInUnits,
31435
31513
  payTo: wallet,
@@ -31441,8 +31519,8 @@ var MoltsPayServer = class {
31441
31519
  /**
31442
31520
  * Return 402 with x402 payment requirements for proxy endpoint
31443
31521
  */
31444
- sendProxyPaymentRequired(config, wallet, memo, res) {
31445
- const requirements = this.buildProxyPaymentRequirements(config, wallet);
31522
+ sendProxyPaymentRequired(config, wallet, memo, chain2, res) {
31523
+ const requirements = this.buildProxyPaymentRequirements(config, wallet, config.currency, chain2);
31446
31524
  const paymentRequired = {
31447
31525
  x402Version: X402_VERSION2,
31448
31526
  accepts: [requirements],
@@ -31502,7 +31580,7 @@ var CHAINS = {
31502
31580
  polygon: {
31503
31581
  name: "Polygon",
31504
31582
  chainId: 137,
31505
- rpc: "https://polygon-rpc.com",
31583
+ rpc: "https://polygon-bor-rpc.publicnode.com",
31506
31584
  tokens: {
31507
31585
  USDC: {
31508
31586
  address: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
@@ -31700,10 +31778,14 @@ var MoltsPayClient = class {
31700
31778
  throw new Error("Client not initialized. Run: npx moltspay init");
31701
31779
  }
31702
31780
  console.log(`[MoltsPay] Requesting service: ${service}`);
31781
+ const requestBody = { service, params };
31782
+ if (options.chain) {
31783
+ requestBody.chain = options.chain;
31784
+ }
31703
31785
  const initialRes = await fetch(`${serverUrl}/execute`, {
31704
31786
  method: "POST",
31705
31787
  headers: { "Content-Type": "application/json" },
31706
- body: JSON.stringify({ service, params })
31788
+ body: JSON.stringify(requestBody)
31707
31789
  });
31708
31790
  if (initialRes.status !== 402) {
31709
31791
  const data = await initialRes.json();
@@ -31730,11 +31812,41 @@ var MoltsPayClient = class {
31730
31812
  } catch {
31731
31813
  throw new Error("Invalid x-payment-required header");
31732
31814
  }
31733
- const chain2 = getChain(this.config.chain);
31815
+ const networkToChainName = (network2) => {
31816
+ const match = network2.match(/^eip155:(\d+)$/);
31817
+ if (!match) return null;
31818
+ const chainId = parseInt(match[1]);
31819
+ if (chainId === 8453) return "base";
31820
+ if (chainId === 137) return "polygon";
31821
+ if (chainId === 84532) return "base_sepolia";
31822
+ return null;
31823
+ };
31824
+ const serverChains = requirements.map((r) => networkToChainName(r.network)).filter((c) => c !== null);
31825
+ let chainName;
31826
+ const userSpecifiedChain = options.chain;
31827
+ if (userSpecifiedChain) {
31828
+ if (!serverChains.includes(userSpecifiedChain)) {
31829
+ throw new Error(
31830
+ `Server doesn't accept '${userSpecifiedChain}'.
31831
+ Server accepts: ${serverChains.join(", ")}`
31832
+ );
31833
+ }
31834
+ chainName = userSpecifiedChain;
31835
+ } else {
31836
+ if (serverChains.length === 1 && serverChains[0] === "base") {
31837
+ chainName = "base";
31838
+ } else {
31839
+ throw new Error(
31840
+ `Server accepts: ${serverChains.join(", ")}
31841
+ Please specify: --chain base or --chain polygon`
31842
+ );
31843
+ }
31844
+ }
31845
+ const chain2 = getChain(chainName);
31734
31846
  const network = `eip155:${chain2.chainId}`;
31735
31847
  const req = requirements.find((r) => r.scheme === "exact" && r.network === network);
31736
31848
  if (!req) {
31737
- throw new Error(`No matching payment option for ${network}`);
31849
+ throw new Error(`Failed to find payment requirement for ${chainName}`);
31738
31850
  }
31739
31851
  const amountRaw = req.amount || req.maxAmountRequired;
31740
31852
  if (!amountRaw) {
@@ -31753,7 +31865,17 @@ var MoltsPayClient = class {
31753
31865
  throw new Error(`Insufficient balance: need $${amount}, have ${balances.usdc} USDC / ${balances.usdt} USDT`);
31754
31866
  }
31755
31867
  }
31756
- console.log(`[MoltsPay] Signing payment: $${amount} ${token} (gasless)`);
31868
+ if (token === "USDT") {
31869
+ const balances = await this.getBalance();
31870
+ if (balances.native < 1e-4) {
31871
+ throw new Error(
31872
+ `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).`
31873
+ );
31874
+ }
31875
+ console.log(`[MoltsPay] \u26A0\uFE0F USDT requires gas (~$0.01). Proceeding with payment...`);
31876
+ } else {
31877
+ console.log(`[MoltsPay] Signing payment: $${amount} ${token} (gasless)`);
31878
+ }
31757
31879
  const payTo = req.payTo || req.resource;
31758
31880
  if (!payTo) {
31759
31881
  throw new Error("Missing payTo address in payment requirements");
@@ -31777,13 +31899,17 @@ var MoltsPayClient = class {
31777
31899
  };
31778
31900
  const paymentHeader = Buffer.from(JSON.stringify(payload)).toString("base64");
31779
31901
  console.log(`[MoltsPay] Sending request with payment...`);
31902
+ const paidRequestBody = { service, params };
31903
+ if (options.chain) {
31904
+ paidRequestBody.chain = options.chain;
31905
+ }
31780
31906
  const paidRes = await fetch(`${serverUrl}/execute`, {
31781
31907
  method: "POST",
31782
31908
  headers: {
31783
31909
  "Content-Type": "application/json",
31784
31910
  [PAYMENT_HEADER2]: paymentHeader
31785
31911
  },
31786
- body: JSON.stringify({ service, params })
31912
+ body: JSON.stringify(paidRequestBody)
31787
31913
  });
31788
31914
  const result = await paidRes.json();
31789
31915
  if (!paidRes.ok) {
@@ -31952,7 +32078,7 @@ var MoltsPayClient = class {
31952
32078
  return { address: wallet.address, configDir };
31953
32079
  }
31954
32080
  /**
31955
- * Get wallet balance (USDC, USDT, and native token)
32081
+ * Get wallet balance (USDC, USDT, and native token) on default chain
31956
32082
  */
31957
32083
  async getBalance() {
31958
32084
  if (!this.wallet) {
@@ -31977,6 +32103,38 @@ var MoltsPayClient = class {
31977
32103
  native: parseFloat(ethers.formatEther(nativeBalance))
31978
32104
  };
31979
32105
  }
32106
+ /**
32107
+ * Get wallet balances on all supported chains (Base + Polygon)
32108
+ */
32109
+ async getAllBalances() {
32110
+ if (!this.wallet) {
32111
+ throw new Error("Client not initialized");
32112
+ }
32113
+ const supportedChains = ["base", "polygon"];
32114
+ const tokenAbi = ["function balanceOf(address) view returns (uint256)"];
32115
+ const results = {};
32116
+ await Promise.all(
32117
+ supportedChains.map(async (chainName) => {
32118
+ try {
32119
+ const chain2 = getChain(chainName);
32120
+ const provider = new ethers.JsonRpcProvider(chain2.rpc);
32121
+ const [nativeBalance, usdcBalance, usdtBalance] = await Promise.all([
32122
+ provider.getBalance(this.wallet.address),
32123
+ new ethers.Contract(chain2.tokens.USDC.address, tokenAbi, provider).balanceOf(this.wallet.address),
32124
+ new ethers.Contract(chain2.tokens.USDT.address, tokenAbi, provider).balanceOf(this.wallet.address)
32125
+ ]);
32126
+ results[chainName] = {
32127
+ usdc: parseFloat(ethers.formatUnits(usdcBalance, chain2.tokens.USDC.decimals)),
32128
+ usdt: parseFloat(ethers.formatUnits(usdtBalance, chain2.tokens.USDT.decimals)),
32129
+ native: parseFloat(ethers.formatEther(nativeBalance))
32130
+ };
32131
+ } catch (err) {
32132
+ results[chainName] = { usdc: 0, usdt: 0, native: 0 };
32133
+ }
32134
+ })
32135
+ );
32136
+ return results;
32137
+ }
31980
32138
  };
31981
32139
 
31982
32140
  // src/wallet/index.ts