@zubari/sdk 0.4.5 → 0.5.1

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 (35) hide show
  1. package/dist/{TransactionService-Djonkbp4.d.ts → TransactionService-BtWUjKt_.d.ts} +14 -2
  2. package/dist/{TransactionService-1Jt8ZRqO.d.mts → TransactionService-Lr_WS6iR.d.mts} +14 -2
  3. package/dist/{WalletManager-DfvFJ-mk.d.ts → WalletManager-DQQwVkoa.d.ts} +4 -0
  4. package/dist/{WalletManager-j0tgNIKi.d.mts → WalletManager-Sbpx4E1-.d.mts} +4 -0
  5. package/dist/{contracts-BahTuxZj.d.mts → contracts-B842YprC.d.mts} +2 -2
  6. package/dist/{contracts-D7rVmNJy.d.ts → contracts-s_CDIruh.d.ts} +2 -2
  7. package/dist/index.d.mts +3 -3
  8. package/dist/index.d.ts +3 -3
  9. package/dist/index.js +305 -23
  10. package/dist/index.js.map +1 -1
  11. package/dist/index.mjs +306 -24
  12. package/dist/index.mjs.map +1 -1
  13. package/dist/protocols/index.js +2 -2
  14. package/dist/protocols/index.js.map +1 -1
  15. package/dist/protocols/index.mjs +2 -2
  16. package/dist/protocols/index.mjs.map +1 -1
  17. package/dist/react/index.d.mts +2 -2
  18. package/dist/react/index.d.ts +2 -2
  19. package/dist/react/index.js +303 -21
  20. package/dist/react/index.js.map +1 -1
  21. package/dist/react/index.mjs +304 -22
  22. package/dist/react/index.mjs.map +1 -1
  23. package/dist/services/index.d.mts +1 -1
  24. package/dist/services/index.d.ts +1 -1
  25. package/dist/services/index.js +132 -8
  26. package/dist/services/index.js.map +1 -1
  27. package/dist/services/index.mjs +132 -8
  28. package/dist/services/index.mjs.map +1 -1
  29. package/dist/wallet/index.d.mts +2 -2
  30. package/dist/wallet/index.d.ts +2 -2
  31. package/dist/wallet/index.js +303 -21
  32. package/dist/wallet/index.js.map +1 -1
  33. package/dist/wallet/index.mjs +304 -22
  34. package/dist/wallet/index.mjs.map +1 -1
  35. package/package.json +1 -1
package/dist/index.mjs CHANGED
@@ -5,7 +5,7 @@ import { HDKey } from '@scure/bip32';
5
5
  import { bech32, base58check } from '@scure/base';
6
6
  import { sha256 } from '@noble/hashes/sha256';
7
7
  import { ripemd160 } from '@noble/hashes/ripemd160';
8
- import { createPublicClient, http, formatEther } from 'viem';
8
+ import { createPublicClient, http, formatEther, getAddress } from 'viem';
9
9
  import { mainnet, sepolia } from 'viem/chains';
10
10
 
11
11
  var __defProp = Object.defineProperty;
@@ -119,6 +119,38 @@ var TESTNET_NETWORKS = {
119
119
  name: "Solana Devnet",
120
120
  rpcUrl: "https://api.devnet.solana.com",
121
121
  explorerUrl: "https://solscan.io?cluster=devnet"
122
+ },
123
+ tron: {
124
+ name: "TRON Nile Testnet",
125
+ chainId: 3448148188,
126
+ rpcUrl: "https://nile.trongrid.io",
127
+ explorerUrl: "https://nile.tronscan.org"
128
+ },
129
+ ton: {
130
+ name: "TON Testnet",
131
+ rpcUrl: "https://testnet.toncenter.com/api/v2",
132
+ explorerUrl: "https://testnet.tonscan.org"
133
+ }
134
+ };
135
+ var USDT_ADDRESSES = {
136
+ ethereum: {
137
+ mainnet: "0xdAC17F958D2ee523a2206206994597C13D831ec7",
138
+ testnet: "0x7169D38820dfd117C3FA1f22a697dBA58d90BA06"
139
+ // Sepolia (Test Tether USD)
140
+ },
141
+ tron: {
142
+ mainnet: "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t",
143
+ testnet: "TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf"
144
+ // Nile testnet
145
+ },
146
+ solana: {
147
+ mainnet: "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB",
148
+ testnet: ""
149
+ // No official USDT on devnet
150
+ },
151
+ ton: {
152
+ mainnet: "EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs",
153
+ testnet: "kQD0GKBM8ZbryVk2aESmzfU6b9b_8era_IkvBSELujFZPsyy"
122
154
  }
123
155
  };
124
156
  var DERIVATION_PATHS = {
@@ -282,8 +314,8 @@ var NFT_VOUCHER_TYPES = {
282
314
  var CURRENCY_ADDRESSES = {
283
315
  testnet: {
284
316
  ETH: ZERO_ADDRESS,
285
- USDT: "0xaA8E23Fb1079EA71e0a56F48a2aA51851D8433D0"
286
- // USDT on Sepolia
317
+ USDT: "0x7169D38820dfd117C3FA1f22a697dBA58d90BA06"
318
+ // USDT on Sepolia (Test Tether USD)
287
319
  },
288
320
  mainnet: {
289
321
  ETH: ZERO_ADDRESS,
@@ -742,6 +774,60 @@ function generateSeedPhrase() {
742
774
 
743
775
  // src/services/ZubariWdkService.ts
744
776
  var DEFAULT_API_URL2 = "https://ckgwifsxka.us-east-2.awsapprunner.com";
777
+ var CHAIN_ERROR_MESSAGES = {
778
+ ethereum: {
779
+ "insufficient funds": "INSUFFICIENT_FUNDS",
780
+ "nonce too low": "NONCE_TOO_LOW",
781
+ "gas too low": "GAS_TOO_LOW",
782
+ "replacement transaction underpriced": "GAS_TOO_LOW",
783
+ "transaction underpriced": "GAS_TOO_LOW",
784
+ "invalid address": "INVALID_ADDRESS"
785
+ },
786
+ bitcoin: {
787
+ "insufficient funds": "INSUFFICIENT_FUNDS",
788
+ "dust": "DUST_AMOUNT",
789
+ "mempool": "MEMPOOL_FULL",
790
+ "invalid address": "INVALID_ADDRESS"
791
+ },
792
+ solana: {
793
+ "insufficient funds": "INSUFFICIENT_FUNDS",
794
+ "invalid account": "INVALID_ADDRESS",
795
+ "blockhash not found": "NETWORK_ERROR"
796
+ },
797
+ ton: {
798
+ "insufficient funds": "INSUFFICIENT_FUNDS",
799
+ "invalid address": "INVALID_ADDRESS"
800
+ },
801
+ tron: {
802
+ "insufficient funds": "INSUFFICIENT_FUNDS",
803
+ "invalid address": "INVALID_ADDRESS",
804
+ "bandwidth": "GAS_TOO_LOW"
805
+ },
806
+ spark: {
807
+ "insufficient funds": "INSUFFICIENT_FUNDS",
808
+ "invoice expired": "TIMEOUT",
809
+ "no route": "NETWORK_ERROR"
810
+ }
811
+ };
812
+ function parseChainError(chain, errorMessage) {
813
+ const errorLower = errorMessage.toLowerCase();
814
+ const chainErrors = CHAIN_ERROR_MESSAGES[chain];
815
+ for (const [pattern, code] of Object.entries(chainErrors)) {
816
+ if (errorLower.includes(pattern)) {
817
+ return code;
818
+ }
819
+ }
820
+ if (errorLower.includes("timeout") || errorLower.includes("timed out")) {
821
+ return "TIMEOUT";
822
+ }
823
+ if (errorLower.includes("network") || errorLower.includes("connection")) {
824
+ return "NETWORK_ERROR";
825
+ }
826
+ if (errorLower.includes("rejected") || errorLower.includes("denied")) {
827
+ return "REJECTED";
828
+ }
829
+ return "UNKNOWN";
830
+ }
745
831
  function isBrowser() {
746
832
  return typeof window !== "undefined" && typeof window.document !== "undefined";
747
833
  }
@@ -1016,47 +1102,117 @@ var ZubariWdkService = class {
1016
1102
  return { fee: "0", symbol: this.getChainSymbol(chain) };
1017
1103
  }
1018
1104
  /**
1019
- * Send a transaction
1105
+ * Send a transaction on any supported chain
1106
+ *
1107
+ * @param seed - BIP-39 seed phrase
1108
+ * @param chain - Target blockchain (ethereum, bitcoin, solana, ton, tron, spark)
1109
+ * @param to - Recipient address
1110
+ * @param amount - Amount to send (in native units: ETH, BTC, SOL, etc.)
1111
+ * @returns Transaction result with hash on success, or error details on failure
1020
1112
  */
1021
1113
  async sendTransaction(seed, chain, to, amount) {
1022
1114
  await this.initialize();
1115
+ const startTime = Date.now();
1116
+ console.log(`[ZubariWdkService] Sending ${chain} transaction`, {
1117
+ to: `${to.slice(0, 10)}...${to.slice(-6)}`,
1118
+ amount,
1119
+ network: this.config.network
1120
+ });
1023
1121
  try {
1024
1122
  const response = await fetch(`${this.config.apiUrl}/api/wallets/wdk/send`, {
1025
1123
  method: "POST",
1026
1124
  headers: { "Content-Type": "application/json" },
1027
1125
  body: JSON.stringify({ seed, chain, to, amount, network: this.config.network })
1028
1126
  });
1127
+ const elapsed = Date.now() - startTime;
1029
1128
  if (response.ok) {
1030
1129
  const data = await response.json();
1031
1130
  let txHash = data.txHash || data.transactionHash || data.hash;
1032
1131
  if (txHash && typeof txHash === "object" && "hash" in txHash) {
1033
1132
  txHash = txHash.hash;
1034
1133
  }
1035
- if (chain === "ethereum" && txHash && (typeof txHash !== "string" || !txHash.startsWith("0x") || txHash.length !== 66)) {
1036
- console.warn(`Invalid Ethereum tx hash format: ${txHash} (length: ${txHash?.length}, expected: 66)`);
1134
+ if (txHash) {
1135
+ const isValid = this.validateTxHash(chain, txHash);
1136
+ if (!isValid) {
1137
+ console.warn(`[ZubariWdkService] Invalid ${chain} tx hash format:`, txHash);
1138
+ }
1139
+ }
1140
+ console.log(`[ZubariWdkService] ${chain} transaction ${data.success ? "SUCCESS" : "FAILED"}`, {
1141
+ txHash: txHash ? `${txHash.slice(0, 16)}...` : "N/A",
1142
+ elapsed: `${elapsed}ms`
1143
+ });
1144
+ if (!data.success) {
1145
+ const errorCode2 = parseChainError(chain, data.error || "");
1146
+ return {
1147
+ success: false,
1148
+ error: data.error,
1149
+ errorCode: errorCode2,
1150
+ chain
1151
+ };
1037
1152
  }
1038
1153
  return {
1039
- success: data.success,
1154
+ success: true,
1040
1155
  txHash,
1041
1156
  from: data.from,
1042
1157
  to: data.to,
1043
1158
  amount: data.amount,
1044
- chain: data.chain,
1045
- network: data.network
1159
+ chain: data.chain || chain,
1160
+ network: data.network || this.config.network
1046
1161
  };
1047
1162
  }
1048
1163
  const errorData = await response.json().catch(() => ({}));
1164
+ const errorMessage = errorData.error || `HTTP ${response.status}`;
1165
+ const errorCode = parseChainError(chain, errorMessage);
1166
+ console.error(`[ZubariWdkService] ${chain} transaction FAILED`, {
1167
+ status: response.status,
1168
+ error: errorMessage,
1169
+ errorCode,
1170
+ elapsed: `${elapsed}ms`
1171
+ });
1049
1172
  return {
1050
1173
  success: false,
1051
- error: errorData.error || `HTTP ${response.status}`
1174
+ error: errorMessage,
1175
+ errorCode,
1176
+ chain
1052
1177
  };
1053
1178
  } catch (error) {
1179
+ const elapsed = Date.now() - startTime;
1180
+ const errorMessage = error instanceof Error ? error.message : "Transaction failed";
1181
+ const errorCode = parseChainError(chain, errorMessage);
1182
+ console.error(`[ZubariWdkService] ${chain} transaction ERROR`, {
1183
+ error: errorMessage,
1184
+ errorCode,
1185
+ elapsed: `${elapsed}ms`
1186
+ });
1054
1187
  return {
1055
1188
  success: false,
1056
- error: error instanceof Error ? error.message : "Transaction failed"
1189
+ error: errorMessage,
1190
+ errorCode,
1191
+ chain
1057
1192
  };
1058
1193
  }
1059
1194
  }
1195
+ /**
1196
+ * Validate transaction hash format for a specific chain
1197
+ */
1198
+ validateTxHash(chain, txHash) {
1199
+ switch (chain) {
1200
+ case "ethereum":
1201
+ return /^0x[a-fA-F0-9]{64}$/.test(txHash);
1202
+ case "bitcoin":
1203
+ return /^[a-fA-F0-9]{64}$/.test(txHash);
1204
+ case "solana":
1205
+ return /^[1-9A-HJ-NP-Za-km-z]{80,90}$/.test(txHash);
1206
+ case "ton":
1207
+ return txHash.length >= 40;
1208
+ case "tron":
1209
+ return /^[a-fA-F0-9]{64}$/.test(txHash);
1210
+ case "spark":
1211
+ return txHash.length >= 32;
1212
+ default:
1213
+ return true;
1214
+ }
1215
+ }
1060
1216
  /**
1061
1217
  * Get the network configuration
1062
1218
  */
@@ -2046,6 +2202,19 @@ async function getPriceForChain(chain) {
2046
2202
  const prices = await fetchPrices();
2047
2203
  return prices[chain] || 0;
2048
2204
  }
2205
+ function tonFriendlyToRaw(addr) {
2206
+ if (addr.includes(":")) return addr;
2207
+ try {
2208
+ const b64 = addr.replace(/-/g, "+").replace(/_/g, "/");
2209
+ const bytes = Uint8Array.from(atob(b64), (c) => c.charCodeAt(0));
2210
+ if (bytes.length !== 36) return addr;
2211
+ const workchain = bytes[1] === 255 ? -1 : bytes[1];
2212
+ const hash = Array.from(bytes.slice(2, 34)).map((b) => b.toString(16).padStart(2, "0")).join("");
2213
+ return `${workchain}:${hash}`;
2214
+ } catch {
2215
+ return addr;
2216
+ }
2217
+ }
2049
2218
  var STORAGE_KEYS = {
2050
2219
  ENCRYPTED_SEED: "encrypted_seed",
2051
2220
  ACTIVE_WALLET: "active_wallet",
@@ -2550,26 +2719,53 @@ var WalletManager = class _WalletManager {
2550
2719
  }
2551
2720
  const networkConfig = this.getChainConfig(chain);
2552
2721
  let balance = "0";
2722
+ const tokenBalances = {};
2553
2723
  if (chain === "ethereum") {
2554
2724
  const viemChain = this.config.network === "mainnet" ? mainnet : sepolia;
2555
- console.log(`[WalletManager] Fetching ${chain} balance for ${address} using RPC: ${this.config.rpcUrl}`);
2725
+ const isTestnet2 = this.config.network !== "mainnet";
2556
2726
  const client = createPublicClient({
2557
2727
  chain: viemChain,
2558
2728
  transport: http(this.config.rpcUrl, {
2559
2729
  timeout: 15e3,
2560
- // 15 second timeout
2561
2730
  retryCount: 2,
2562
2731
  retryDelay: 1e3
2563
2732
  })
2564
2733
  });
2565
- try {
2566
- const rawBalance = await client.getBalance({
2567
- address
2568
- });
2569
- balance = formatEther(rawBalance);
2570
- console.log(`[WalletManager] ${chain} balance fetched: ${balance} (raw: ${rawBalance})`);
2571
- } catch (error) {
2572
- console.error(`[WalletManager] Failed to fetch ${chain} balance from ${this.config.rpcUrl}:`, error);
2734
+ const usdtAddr = USDT_ADDRESSES.ethereum?.[isTestnet2 ? "testnet" : "mainnet"];
2735
+ const erc20BalanceOfAbi = [{
2736
+ type: "function",
2737
+ name: "balanceOf",
2738
+ stateMutability: "view",
2739
+ inputs: [{ name: "account", type: "address" }],
2740
+ outputs: [{ name: "", type: "uint256" }]
2741
+ }];
2742
+ const checksumAddr = getAddress(address);
2743
+ const [ethResult, usdtResult] = await Promise.allSettled([
2744
+ client.getBalance({ address: checksumAddr }),
2745
+ usdtAddr ? client.readContract({
2746
+ address: getAddress(usdtAddr),
2747
+ abi: erc20BalanceOfAbi,
2748
+ functionName: "balanceOf",
2749
+ args: [checksumAddr]
2750
+ }) : Promise.resolve(null)
2751
+ ]);
2752
+ if (ethResult.status === "fulfilled") {
2753
+ balance = formatEther(ethResult.value);
2754
+ } else {
2755
+ console.error(`[WalletManager] Failed to fetch ETH balance:`, ethResult.reason);
2756
+ }
2757
+ if (usdtResult.status === "fulfilled" && usdtResult.value != null) {
2758
+ try {
2759
+ const rawUsdt = BigInt(usdtResult.value);
2760
+ const usdtAmount = Number(rawUsdt) / 1e6;
2761
+ if (usdtAmount > 0) {
2762
+ tokenBalances.USDT = { balance: usdtAmount.toFixed(6), balanceUsd: usdtAmount };
2763
+ }
2764
+ } catch (err) {
2765
+ console.warn("[WalletManager] Failed to parse ETH USDT balance:", err);
2766
+ }
2767
+ } else if (usdtResult.status === "rejected") {
2768
+ console.warn("[WalletManager] Failed to fetch ETH USDT balance:", usdtResult.reason);
2573
2769
  }
2574
2770
  } else if (chain === "bitcoin") {
2575
2771
  const isMainnet2 = this.config.network === "mainnet" || address.startsWith("bc1") || address.startsWith("1") || address.startsWith("3");
@@ -2625,8 +2821,41 @@ var WalletManager = class _WalletManager {
2625
2821
  } catch (error) {
2626
2822
  console.warn(`Failed to fetch ${chain} balance:`, error);
2627
2823
  }
2824
+ const isTestnet2 = this.config.network !== "mainnet";
2825
+ const usdtMint = USDT_ADDRESSES.solana?.[isTestnet2 ? "testnet" : "mainnet"];
2826
+ if (usdtMint) {
2827
+ try {
2828
+ const tokenResponse = await fetch(rpcUrl, {
2829
+ method: "POST",
2830
+ headers: { "Content-Type": "application/json" },
2831
+ body: JSON.stringify({
2832
+ jsonrpc: "2.0",
2833
+ id: 2,
2834
+ method: "getTokenAccountsByOwner",
2835
+ params: [
2836
+ address,
2837
+ { mint: usdtMint },
2838
+ { encoding: "jsonParsed" }
2839
+ ]
2840
+ })
2841
+ });
2842
+ if (tokenResponse.ok) {
2843
+ const tokenData = await tokenResponse.json();
2844
+ const accounts = tokenData.result?.value;
2845
+ if (accounts && accounts.length > 0) {
2846
+ const uiAmount = accounts[0].account?.data?.parsed?.info?.tokenAmount?.uiAmount;
2847
+ if (uiAmount && uiAmount > 0) {
2848
+ tokenBalances.USDT = { balance: uiAmount.toFixed(6), balanceUsd: uiAmount };
2849
+ }
2850
+ }
2851
+ }
2852
+ } catch (error) {
2853
+ console.warn("Failed to fetch Solana USDT balance:", error);
2854
+ }
2855
+ }
2628
2856
  } else if (chain === "tron") {
2629
- const baseUrl = this.config.network === "mainnet" ? "https://api.trongrid.io" : "https://api.shasta.trongrid.io";
2857
+ const tronConfig = getNetworkConfig("tron", this.config.network !== "mainnet");
2858
+ const baseUrl = tronConfig.rpcUrl;
2630
2859
  try {
2631
2860
  const response = await fetch(`${baseUrl}/v1/accounts/${address}`, {
2632
2861
  headers: { "Accept": "application/json" }
@@ -2636,12 +2865,28 @@ var WalletManager = class _WalletManager {
2636
2865
  if (data.data?.[0]?.balance !== void 0) {
2637
2866
  balance = (data.data[0].balance / 1e6).toFixed(6);
2638
2867
  }
2868
+ const isTestnet2 = this.config.network !== "mainnet";
2869
+ const usdtAddr = USDT_ADDRESSES.tron?.[isTestnet2 ? "testnet" : "mainnet"];
2870
+ if (usdtAddr && data.data?.[0]?.trc20) {
2871
+ const trc20List = data.data[0].trc20;
2872
+ for (const tokenObj of trc20List) {
2873
+ if (tokenObj[usdtAddr]) {
2874
+ const rawUsdtBalance = BigInt(tokenObj[usdtAddr]);
2875
+ const usdtAmount = Number(rawUsdtBalance) / 1e6;
2876
+ if (usdtAmount > 0) {
2877
+ tokenBalances.USDT = { balance: usdtAmount.toFixed(6), balanceUsd: usdtAmount };
2878
+ }
2879
+ break;
2880
+ }
2881
+ }
2882
+ }
2639
2883
  }
2640
2884
  } catch (error) {
2641
2885
  console.warn(`Failed to fetch ${chain} balance:`, error);
2642
2886
  }
2643
2887
  } else if (chain === "ton") {
2644
- const baseUrl = this.config.network === "mainnet" ? "https://toncenter.com/api/v2" : "https://testnet.toncenter.com/api/v2";
2888
+ const isTestnet2 = this.config.network !== "mainnet";
2889
+ const baseUrl = isTestnet2 ? "https://testnet.toncenter.com/api/v2" : "https://toncenter.com/api/v2";
2645
2890
  try {
2646
2891
  const response = await fetch(`${baseUrl}/getAddressBalance?address=${address}`, {
2647
2892
  headers: { "Accept": "application/json" }
@@ -2657,6 +2902,42 @@ var WalletManager = class _WalletManager {
2657
2902
  } catch (error) {
2658
2903
  console.warn(`Failed to fetch ${chain} balance:`, error);
2659
2904
  }
2905
+ const usdtJetton = USDT_ADDRESSES.ton?.[isTestnet2 ? "testnet" : "mainnet"];
2906
+ if (usdtJetton) {
2907
+ const tonapiBaseUrl = isTestnet2 ? "https://testnet.tonapi.io/v2" : "https://tonapi.io/v2";
2908
+ try {
2909
+ const rawAddr = tonFriendlyToRaw(address);
2910
+ const jettonResponse = await fetch(
2911
+ `${tonapiBaseUrl}/accounts/${encodeURIComponent(rawAddr)}/jettons?currencies=usd`,
2912
+ { headers: { "Accept": "application/json" } }
2913
+ );
2914
+ if (jettonResponse.ok) {
2915
+ const jettonData = await jettonResponse.json();
2916
+ const balances = jettonData.balances;
2917
+ if (balances && balances.length > 0) {
2918
+ for (const jb of balances) {
2919
+ const jettonAddr = jb.jetton?.address;
2920
+ if (jettonAddr) {
2921
+ const usdtRaw = tonFriendlyToRaw(usdtJetton);
2922
+ if (jettonAddr.toLowerCase() === usdtRaw.toLowerCase()) {
2923
+ const rawBalance = jb.balance;
2924
+ if (rawBalance) {
2925
+ const decimals = jb.jetton?.decimals || 6;
2926
+ const usdtAmount = Number(BigInt(rawBalance)) / Math.pow(10, decimals);
2927
+ if (usdtAmount > 0) {
2928
+ tokenBalances.USDT = { balance: usdtAmount.toFixed(6), balanceUsd: usdtAmount };
2929
+ }
2930
+ }
2931
+ break;
2932
+ }
2933
+ }
2934
+ }
2935
+ }
2936
+ }
2937
+ } catch (error) {
2938
+ console.warn("Failed to fetch TON USDT jetton balance:", error);
2939
+ }
2940
+ }
2660
2941
  } else if (chain === "spark") {
2661
2942
  try {
2662
2943
  const response = await fetch(`${this.config.apiUrl}/api/wallets/wdk/balance`, {
@@ -2688,7 +2969,8 @@ var WalletManager = class _WalletManager {
2688
2969
  balance,
2689
2970
  balanceUsd,
2690
2971
  address,
2691
- decimals: networkConfig.nativeCurrency.decimals
2972
+ decimals: networkConfig.nativeCurrency.decimals,
2973
+ ...Object.keys(tokenBalances).length > 0 ? { tokenBalances } : {}
2692
2974
  };
2693
2975
  }
2694
2976
  /**