moltspay 0.9.7 → 1.1.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 +42 -3
  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 +5028 -109
  11. package/dist/cli/index.js.map +1 -1
  12. package/dist/cli/index.mjs +5019 -96
  13. package/dist/cli/index.mjs.map +1 -1
  14. package/dist/client/index.d.mts +18 -3
  15. package/dist/client/index.d.ts +18 -3
  16. package/dist/client/index.js +89 -10
  17. package/dist/client/index.js.map +1 -1
  18. package/dist/client/index.mjs +89 -10
  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 +193 -36
  25. package/dist/index.js.map +1 -1
  26. package/dist/index.mjs +193 -36
  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 +3 -2
  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",
@@ -31678,11 +31756,20 @@ var MoltsPayClient = class {
31678
31756
  * Get services from a provider
31679
31757
  */
31680
31758
  async getServices(serverUrl) {
31681
- const res = await fetch(`${serverUrl}/services`);
31682
- if (!res.ok) {
31683
- throw new Error(`Failed to get services: ${res.statusText}`);
31759
+ const normalizedUrl = serverUrl.replace(/\/(services|api\/services|registry\/services)\/?$/, "");
31760
+ const endpoints = ["/services", "/api/services", "/registry/services"];
31761
+ for (const endpoint of endpoints) {
31762
+ try {
31763
+ const res = await fetch(`${normalizedUrl}${endpoint}`);
31764
+ if (!res.ok) continue;
31765
+ const contentType = res.headers.get("content-type") || "";
31766
+ if (!contentType.includes("application/json")) continue;
31767
+ return await res.json();
31768
+ } catch {
31769
+ continue;
31770
+ }
31684
31771
  }
31685
- return res.json();
31772
+ throw new Error(`Failed to get services: no valid endpoint found at ${normalizedUrl}`);
31686
31773
  }
31687
31774
  /**
31688
31775
  * Pay for a service and get the result (x402 protocol)
@@ -31700,10 +31787,14 @@ var MoltsPayClient = class {
31700
31787
  throw new Error("Client not initialized. Run: npx moltspay init");
31701
31788
  }
31702
31789
  console.log(`[MoltsPay] Requesting service: ${service}`);
31790
+ const requestBody = { service, params };
31791
+ if (options.chain) {
31792
+ requestBody.chain = options.chain;
31793
+ }
31703
31794
  const initialRes = await fetch(`${serverUrl}/execute`, {
31704
31795
  method: "POST",
31705
31796
  headers: { "Content-Type": "application/json" },
31706
- body: JSON.stringify({ service, params })
31797
+ body: JSON.stringify(requestBody)
31707
31798
  });
31708
31799
  if (initialRes.status !== 402) {
31709
31800
  const data = await initialRes.json();
@@ -31730,11 +31821,41 @@ var MoltsPayClient = class {
31730
31821
  } catch {
31731
31822
  throw new Error("Invalid x-payment-required header");
31732
31823
  }
31733
- const chain2 = getChain(this.config.chain);
31824
+ const networkToChainName = (network2) => {
31825
+ const match = network2.match(/^eip155:(\d+)$/);
31826
+ if (!match) return null;
31827
+ const chainId = parseInt(match[1]);
31828
+ if (chainId === 8453) return "base";
31829
+ if (chainId === 137) return "polygon";
31830
+ if (chainId === 84532) return "base_sepolia";
31831
+ return null;
31832
+ };
31833
+ const serverChains = requirements.map((r) => networkToChainName(r.network)).filter((c) => c !== null);
31834
+ let chainName;
31835
+ const userSpecifiedChain = options.chain;
31836
+ if (userSpecifiedChain) {
31837
+ if (!serverChains.includes(userSpecifiedChain)) {
31838
+ throw new Error(
31839
+ `Server doesn't accept '${userSpecifiedChain}'.
31840
+ Server accepts: ${serverChains.join(", ")}`
31841
+ );
31842
+ }
31843
+ chainName = userSpecifiedChain;
31844
+ } else {
31845
+ if (serverChains.length === 1 && serverChains[0] === "base") {
31846
+ chainName = "base";
31847
+ } else {
31848
+ throw new Error(
31849
+ `Server accepts: ${serverChains.join(", ")}
31850
+ Please specify: --chain base or --chain polygon`
31851
+ );
31852
+ }
31853
+ }
31854
+ const chain2 = getChain(chainName);
31734
31855
  const network = `eip155:${chain2.chainId}`;
31735
31856
  const req = requirements.find((r) => r.scheme === "exact" && r.network === network);
31736
31857
  if (!req) {
31737
- throw new Error(`No matching payment option for ${network}`);
31858
+ throw new Error(`Failed to find payment requirement for ${chainName}`);
31738
31859
  }
31739
31860
  const amountRaw = req.amount || req.maxAmountRequired;
31740
31861
  if (!amountRaw) {
@@ -31787,13 +31908,17 @@ var MoltsPayClient = class {
31787
31908
  };
31788
31909
  const paymentHeader = Buffer.from(JSON.stringify(payload)).toString("base64");
31789
31910
  console.log(`[MoltsPay] Sending request with payment...`);
31911
+ const paidRequestBody = { service, params };
31912
+ if (options.chain) {
31913
+ paidRequestBody.chain = options.chain;
31914
+ }
31790
31915
  const paidRes = await fetch(`${serverUrl}/execute`, {
31791
31916
  method: "POST",
31792
31917
  headers: {
31793
31918
  "Content-Type": "application/json",
31794
31919
  [PAYMENT_HEADER2]: paymentHeader
31795
31920
  },
31796
- body: JSON.stringify({ service, params })
31921
+ body: JSON.stringify(paidRequestBody)
31797
31922
  });
31798
31923
  const result = await paidRes.json();
31799
31924
  if (!paidRes.ok) {
@@ -31962,7 +32087,7 @@ var MoltsPayClient = class {
31962
32087
  return { address: wallet.address, configDir };
31963
32088
  }
31964
32089
  /**
31965
- * Get wallet balance (USDC, USDT, and native token)
32090
+ * Get wallet balance (USDC, USDT, and native token) on default chain
31966
32091
  */
31967
32092
  async getBalance() {
31968
32093
  if (!this.wallet) {
@@ -31987,6 +32112,38 @@ var MoltsPayClient = class {
31987
32112
  native: parseFloat(ethers.formatEther(nativeBalance))
31988
32113
  };
31989
32114
  }
32115
+ /**
32116
+ * Get wallet balances on all supported chains (Base + Polygon)
32117
+ */
32118
+ async getAllBalances() {
32119
+ if (!this.wallet) {
32120
+ throw new Error("Client not initialized");
32121
+ }
32122
+ const supportedChains = ["base", "polygon"];
32123
+ const tokenAbi = ["function balanceOf(address) view returns (uint256)"];
32124
+ const results = {};
32125
+ await Promise.all(
32126
+ supportedChains.map(async (chainName) => {
32127
+ try {
32128
+ const chain2 = getChain(chainName);
32129
+ const provider = new ethers.JsonRpcProvider(chain2.rpc);
32130
+ const [nativeBalance, usdcBalance, usdtBalance] = await Promise.all([
32131
+ provider.getBalance(this.wallet.address),
32132
+ new ethers.Contract(chain2.tokens.USDC.address, tokenAbi, provider).balanceOf(this.wallet.address),
32133
+ new ethers.Contract(chain2.tokens.USDT.address, tokenAbi, provider).balanceOf(this.wallet.address)
32134
+ ]);
32135
+ results[chainName] = {
32136
+ usdc: parseFloat(ethers.formatUnits(usdcBalance, chain2.tokens.USDC.decimals)),
32137
+ usdt: parseFloat(ethers.formatUnits(usdtBalance, chain2.tokens.USDT.decimals)),
32138
+ native: parseFloat(ethers.formatEther(nativeBalance))
32139
+ };
32140
+ } catch (err) {
32141
+ results[chainName] = { usdc: 0, usdt: 0, native: 0 };
32142
+ }
32143
+ })
32144
+ );
32145
+ return results;
32146
+ }
31990
32147
  };
31991
32148
 
31992
32149
  // src/wallet/index.ts