@zubari/sdk 0.5.0 → 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-BJaLBfX5.d.ts → WalletManager-DQQwVkoa.d.ts} +52 -131
  4. package/dist/{WalletManager-pVFpurEi.d.mts → WalletManager-Sbpx4E1-.d.mts} +52 -131
  5. package/dist/{index-Da7SaweH.d.mts → contracts-B842YprC.d.mts} +152 -82
  6. package/dist/{index-ARbXbNI-.d.ts → contracts-s_CDIruh.d.ts} +152 -82
  7. package/dist/index.d.mts +65 -6
  8. package/dist/index.d.ts +65 -6
  9. package/dist/index.js +531 -73
  10. package/dist/index.js.map +1 -1
  11. package/dist/index.mjs +515 -75
  12. package/dist/index.mjs.map +1 -1
  13. package/dist/protocols/index.js +23 -5
  14. package/dist/protocols/index.js.map +1 -1
  15. package/dist/protocols/index.mjs +23 -5
  16. package/dist/protocols/index.mjs.map +1 -1
  17. package/dist/react/index.d.mts +3 -4
  18. package/dist/react/index.d.ts +3 -4
  19. package/dist/react/index.js +324 -34
  20. package/dist/react/index.js.map +1 -1
  21. package/dist/react/index.mjs +325 -35
  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 +151 -19
  26. package/dist/services/index.js.map +1 -1
  27. package/dist/services/index.mjs +151 -19
  28. package/dist/services/index.mjs.map +1 -1
  29. package/dist/wallet/index.d.mts +3 -4
  30. package/dist/wallet/index.d.ts +3 -4
  31. package/dist/wallet/index.js +354 -53
  32. package/dist/wallet/index.js.map +1 -1
  33. package/dist/wallet/index.mjs +355 -54
  34. package/dist/wallet/index.mjs.map +1 -1
  35. package/package.json +16 -14
@@ -1,8 +1,7 @@
1
1
  import { b as NetworkType } from '../index-CTyZlHKg.mjs';
2
- import { W as WalletManagerConfig, a as WalletState, C as ChainBalance, M as MultiChainAddresses, b as WalletManager } from '../WalletManager-pVFpurEi.mjs';
3
- export { S as SUPPORTED_CHAINS } from '../WalletManager-pVFpurEi.mjs';
4
- import 'node_modules/viem/_types/actions/siwe/verifySiweMessage';
5
- import 'node_modules/viem/_types/utils/ccip';
2
+ import { W as WalletManagerConfig, a as WalletState, C as ChainBalance, M as MultiChainAddresses, b as WalletManager } from '../WalletManager-Sbpx4E1-.mjs';
3
+ export { S as SUPPORTED_CHAINS } from '../WalletManager-Sbpx4E1-.mjs';
4
+ import 'abitype';
6
5
  import 'viem';
7
6
  import 'ethers';
8
7
  import '../SecureStorage-jO783AhC.mjs';
@@ -1,8 +1,7 @@
1
1
  import { b as NetworkType } from '../index-CTyZlHKg.js';
2
- import { W as WalletManagerConfig, a as WalletState, C as ChainBalance, M as MultiChainAddresses, b as WalletManager } from '../WalletManager-BJaLBfX5.js';
3
- export { S as SUPPORTED_CHAINS } from '../WalletManager-BJaLBfX5.js';
4
- import 'node_modules/viem/_types/actions/siwe/verifySiweMessage';
5
- import 'node_modules/viem/_types/utils/ccip';
2
+ import { W as WalletManagerConfig, a as WalletState, C as ChainBalance, M as MultiChainAddresses, b as WalletManager } from '../WalletManager-DQQwVkoa.js';
3
+ export { S as SUPPORTED_CHAINS } from '../WalletManager-DQQwVkoa.js';
4
+ import 'abitype';
6
5
  import 'viem';
7
6
  import 'ethers';
8
7
  import '../SecureStorage-jO783AhC.js';
@@ -34,7 +34,7 @@ var NETWORKS = {
34
34
  chainId: 1,
35
35
  coinType: 60,
36
36
  // m/44'/60'
37
- rpcUrl: "https://eth.llamarpc.com",
37
+ rpcUrl: "https://ethereum-rpc.publicnode.com",
38
38
  explorerUrl: "https://etherscan.io",
39
39
  nativeCurrency: {
40
40
  name: "Ether",
@@ -118,6 +118,38 @@ var TESTNET_NETWORKS = {
118
118
  name: "Solana Devnet",
119
119
  rpcUrl: "https://api.devnet.solana.com",
120
120
  explorerUrl: "https://solscan.io?cluster=devnet"
121
+ },
122
+ tron: {
123
+ name: "TRON Nile Testnet",
124
+ chainId: 3448148188,
125
+ rpcUrl: "https://nile.trongrid.io",
126
+ explorerUrl: "https://nile.tronscan.org"
127
+ },
128
+ ton: {
129
+ name: "TON Testnet",
130
+ rpcUrl: "https://testnet.toncenter.com/api/v2",
131
+ explorerUrl: "https://testnet.tonscan.org"
132
+ }
133
+ };
134
+ var USDT_ADDRESSES = {
135
+ ethereum: {
136
+ mainnet: "0xdAC17F958D2ee523a2206206994597C13D831ec7",
137
+ testnet: "0x7169D38820dfd117C3FA1f22a697dBA58d90BA06"
138
+ // Sepolia (Test Tether USD)
139
+ },
140
+ tron: {
141
+ mainnet: "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t",
142
+ testnet: "TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf"
143
+ // Nile testnet
144
+ },
145
+ solana: {
146
+ mainnet: "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB",
147
+ testnet: ""
148
+ // No official USDT on devnet
149
+ },
150
+ ton: {
151
+ mainnet: "EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs",
152
+ testnet: "kQD0GKBM8ZbryVk2aESmzfU6b9b_8era_IkvBSELujFZPsyy"
121
153
  }
122
154
  };
123
155
  var DERIVATION_PATHS = {
@@ -184,7 +216,7 @@ var WdkApiClient = class {
184
216
  /**
185
217
  * Derive address for a specific chain using Tether WDK
186
218
  */
187
- async deriveAddress(seed, chain, network = "testnet") {
219
+ async deriveAddress(seed, chain, network = "mainnet") {
188
220
  try {
189
221
  const response = await fetch(`${this.config.baseUrl}/api/wallets/wdk/derive-address`, {
190
222
  method: "POST",
@@ -204,7 +236,7 @@ var WdkApiClient = class {
204
236
  /**
205
237
  * Derive addresses for all chains using Tether WDK
206
238
  */
207
- async deriveAllAddresses(seed, network = "testnet") {
239
+ async deriveAllAddresses(seed, network = "mainnet") {
208
240
  try {
209
241
  const response = await fetch(`${this.config.baseUrl}/api/wallets/wdk/derive-all`, {
210
242
  method: "POST",
@@ -224,7 +256,7 @@ var WdkApiClient = class {
224
256
  /**
225
257
  * Send a transaction on a specific chain using Tether WDK
226
258
  */
227
- async sendTransaction(seed, chain, to, amount, network = "testnet") {
259
+ async sendTransaction(seed, chain, to, amount, network = "mainnet") {
228
260
  try {
229
261
  const response = await fetch(`${this.config.baseUrl}/api/wallets/wdk/send`, {
230
262
  method: "POST",
@@ -245,7 +277,7 @@ var WdkApiClient = class {
245
277
  * Get transaction history for an address on a specific chain
246
278
  * Fetches from blockchain explorers (Etherscan, mempool.space, etc.)
247
279
  */
248
- async getTransactionHistory(seed, chain, network = "testnet", limit = 10) {
280
+ async getTransactionHistory(seed, chain, network = "mainnet", limit = 10) {
249
281
  try {
250
282
  const response = await fetch(`${this.config.baseUrl}/api/wallets/wdk/history`, {
251
283
  method: "POST",
@@ -266,7 +298,7 @@ var WdkApiClient = class {
266
298
  * Get transaction status by hash
267
299
  * Fetches from blockchain explorers to check confirmation status
268
300
  */
269
- async getTransactionStatus(txHash, chain, network = "testnet") {
301
+ async getTransactionStatus(txHash, chain, network = "mainnet") {
270
302
  try {
271
303
  const response = await fetch(`${this.config.baseUrl}/api/wallets/wdk/tx-status`, {
272
304
  method: "POST",
@@ -307,7 +339,7 @@ function deriveEthereumAddress(seed) {
307
339
  const hdNode = ethers.HDNodeWallet.fromPhrase(seed, void 0, DERIVATION_PATHS2.ethereum);
308
340
  return hdNode.address;
309
341
  }
310
- function deriveBitcoinAddress(seed, network = "testnet") {
342
+ function deriveBitcoinAddress(seed, network = "mainnet") {
311
343
  try {
312
344
  const seedBytes = bip39.mnemonicToSeedSync(seed);
313
345
  const hdKey = bip32.HDKey.fromMasterSeed(seedBytes);
@@ -401,7 +433,7 @@ function deriveTronAddress(seed) {
401
433
  throw error;
402
434
  }
403
435
  }
404
- function deriveSparkAddress(seed, network = "testnet") {
436
+ function deriveSparkAddress(seed, network = "mainnet") {
405
437
  try {
406
438
  const seedBytes = bip39.mnemonicToSeedSync(seed);
407
439
  const hdKey = bip32.HDKey.fromMasterSeed(seedBytes);
@@ -421,7 +453,7 @@ function deriveSparkAddress(seed, network = "testnet") {
421
453
  throw error;
422
454
  }
423
455
  }
424
- async function deriveAllAddresses(seed, network = "testnet") {
456
+ async function deriveAllAddresses(seed, network = "mainnet") {
425
457
  const addresses = {
426
458
  ethereum: null,
427
459
  bitcoin: null,
@@ -475,6 +507,60 @@ function generateSeedPhrase() {
475
507
 
476
508
  // src/services/ZubariWdkService.ts
477
509
  var DEFAULT_API_URL2 = "https://ckgwifsxka.us-east-2.awsapprunner.com";
510
+ var CHAIN_ERROR_MESSAGES = {
511
+ ethereum: {
512
+ "insufficient funds": "INSUFFICIENT_FUNDS",
513
+ "nonce too low": "NONCE_TOO_LOW",
514
+ "gas too low": "GAS_TOO_LOW",
515
+ "replacement transaction underpriced": "GAS_TOO_LOW",
516
+ "transaction underpriced": "GAS_TOO_LOW",
517
+ "invalid address": "INVALID_ADDRESS"
518
+ },
519
+ bitcoin: {
520
+ "insufficient funds": "INSUFFICIENT_FUNDS",
521
+ "dust": "DUST_AMOUNT",
522
+ "mempool": "MEMPOOL_FULL",
523
+ "invalid address": "INVALID_ADDRESS"
524
+ },
525
+ solana: {
526
+ "insufficient funds": "INSUFFICIENT_FUNDS",
527
+ "invalid account": "INVALID_ADDRESS",
528
+ "blockhash not found": "NETWORK_ERROR"
529
+ },
530
+ ton: {
531
+ "insufficient funds": "INSUFFICIENT_FUNDS",
532
+ "invalid address": "INVALID_ADDRESS"
533
+ },
534
+ tron: {
535
+ "insufficient funds": "INSUFFICIENT_FUNDS",
536
+ "invalid address": "INVALID_ADDRESS",
537
+ "bandwidth": "GAS_TOO_LOW"
538
+ },
539
+ spark: {
540
+ "insufficient funds": "INSUFFICIENT_FUNDS",
541
+ "invoice expired": "TIMEOUT",
542
+ "no route": "NETWORK_ERROR"
543
+ }
544
+ };
545
+ function parseChainError(chain, errorMessage) {
546
+ const errorLower = errorMessage.toLowerCase();
547
+ const chainErrors = CHAIN_ERROR_MESSAGES[chain];
548
+ for (const [pattern, code] of Object.entries(chainErrors)) {
549
+ if (errorLower.includes(pattern)) {
550
+ return code;
551
+ }
552
+ }
553
+ if (errorLower.includes("timeout") || errorLower.includes("timed out")) {
554
+ return "TIMEOUT";
555
+ }
556
+ if (errorLower.includes("network") || errorLower.includes("connection")) {
557
+ return "NETWORK_ERROR";
558
+ }
559
+ if (errorLower.includes("rejected") || errorLower.includes("denied")) {
560
+ return "REJECTED";
561
+ }
562
+ return "UNKNOWN";
563
+ }
478
564
  function isBrowser() {
479
565
  return typeof window !== "undefined" && typeof window.document !== "undefined";
480
566
  }
@@ -498,7 +584,7 @@ var ZubariWdkService = class {
498
584
  useNativeWdk = false;
499
585
  constructor(config = {}) {
500
586
  this.config = {
501
- network: config.network || "testnet",
587
+ network: config.network || "mainnet",
502
588
  apiUrl: config.apiUrl || process.env.NEXT_PUBLIC_API_URL || DEFAULT_API_URL2,
503
589
  forceApi: config.forceApi ?? false,
504
590
  timeout: config.timeout || 3e4
@@ -649,7 +735,7 @@ var ZubariWdkService = class {
649
735
  }
650
736
  return null;
651
737
  };
652
- return {
738
+ const addresses = {
653
739
  ethereum: extractAddress(response.addresses.ethereum),
654
740
  bitcoin: extractAddress(response.addresses.bitcoin),
655
741
  ton: extractAddress(response.addresses.ton),
@@ -657,6 +743,14 @@ var ZubariWdkService = class {
657
743
  solana: extractAddress(response.addresses.solana),
658
744
  spark: extractAddress(response.addresses.spark)
659
745
  };
746
+ if (!addresses.spark) {
747
+ try {
748
+ addresses.spark = deriveSparkAddress(seed, this.config.network);
749
+ } catch (e) {
750
+ console.warn("Browser Spark derivation fallback failed:", e);
751
+ }
752
+ }
753
+ return addresses;
660
754
  }
661
755
  } catch (error) {
662
756
  console.warn("API address derivation failed:", error);
@@ -741,47 +835,117 @@ var ZubariWdkService = class {
741
835
  return { fee: "0", symbol: this.getChainSymbol(chain) };
742
836
  }
743
837
  /**
744
- * Send a transaction
838
+ * Send a transaction on any supported chain
839
+ *
840
+ * @param seed - BIP-39 seed phrase
841
+ * @param chain - Target blockchain (ethereum, bitcoin, solana, ton, tron, spark)
842
+ * @param to - Recipient address
843
+ * @param amount - Amount to send (in native units: ETH, BTC, SOL, etc.)
844
+ * @returns Transaction result with hash on success, or error details on failure
745
845
  */
746
846
  async sendTransaction(seed, chain, to, amount) {
747
847
  await this.initialize();
848
+ const startTime = Date.now();
849
+ console.log(`[ZubariWdkService] Sending ${chain} transaction`, {
850
+ to: `${to.slice(0, 10)}...${to.slice(-6)}`,
851
+ amount,
852
+ network: this.config.network
853
+ });
748
854
  try {
749
855
  const response = await fetch(`${this.config.apiUrl}/api/wallets/wdk/send`, {
750
856
  method: "POST",
751
857
  headers: { "Content-Type": "application/json" },
752
858
  body: JSON.stringify({ seed, chain, to, amount, network: this.config.network })
753
859
  });
860
+ const elapsed = Date.now() - startTime;
754
861
  if (response.ok) {
755
862
  const data = await response.json();
756
863
  let txHash = data.txHash || data.transactionHash || data.hash;
757
864
  if (txHash && typeof txHash === "object" && "hash" in txHash) {
758
865
  txHash = txHash.hash;
759
866
  }
760
- if (chain === "ethereum" && txHash && (typeof txHash !== "string" || !txHash.startsWith("0x") || txHash.length !== 66)) {
761
- console.warn(`Invalid Ethereum tx hash format: ${txHash} (length: ${txHash?.length}, expected: 66)`);
867
+ if (txHash) {
868
+ const isValid = this.validateTxHash(chain, txHash);
869
+ if (!isValid) {
870
+ console.warn(`[ZubariWdkService] Invalid ${chain} tx hash format:`, txHash);
871
+ }
872
+ }
873
+ console.log(`[ZubariWdkService] ${chain} transaction ${data.success ? "SUCCESS" : "FAILED"}`, {
874
+ txHash: txHash ? `${txHash.slice(0, 16)}...` : "N/A",
875
+ elapsed: `${elapsed}ms`
876
+ });
877
+ if (!data.success) {
878
+ const errorCode2 = parseChainError(chain, data.error || "");
879
+ return {
880
+ success: false,
881
+ error: data.error,
882
+ errorCode: errorCode2,
883
+ chain
884
+ };
762
885
  }
763
886
  return {
764
- success: data.success,
887
+ success: true,
765
888
  txHash,
766
889
  from: data.from,
767
890
  to: data.to,
768
891
  amount: data.amount,
769
- chain: data.chain,
770
- network: data.network
892
+ chain: data.chain || chain,
893
+ network: data.network || this.config.network
771
894
  };
772
895
  }
773
896
  const errorData = await response.json().catch(() => ({}));
897
+ const errorMessage = errorData.error || `HTTP ${response.status}`;
898
+ const errorCode = parseChainError(chain, errorMessage);
899
+ console.error(`[ZubariWdkService] ${chain} transaction FAILED`, {
900
+ status: response.status,
901
+ error: errorMessage,
902
+ errorCode,
903
+ elapsed: `${elapsed}ms`
904
+ });
774
905
  return {
775
906
  success: false,
776
- error: errorData.error || `HTTP ${response.status}`
907
+ error: errorMessage,
908
+ errorCode,
909
+ chain
777
910
  };
778
911
  } catch (error) {
912
+ const elapsed = Date.now() - startTime;
913
+ const errorMessage = error instanceof Error ? error.message : "Transaction failed";
914
+ const errorCode = parseChainError(chain, errorMessage);
915
+ console.error(`[ZubariWdkService] ${chain} transaction ERROR`, {
916
+ error: errorMessage,
917
+ errorCode,
918
+ elapsed: `${elapsed}ms`
919
+ });
779
920
  return {
780
921
  success: false,
781
- error: error instanceof Error ? error.message : "Transaction failed"
922
+ error: errorMessage,
923
+ errorCode,
924
+ chain
782
925
  };
783
926
  }
784
927
  }
928
+ /**
929
+ * Validate transaction hash format for a specific chain
930
+ */
931
+ validateTxHash(chain, txHash) {
932
+ switch (chain) {
933
+ case "ethereum":
934
+ return /^0x[a-fA-F0-9]{64}$/.test(txHash);
935
+ case "bitcoin":
936
+ return /^[a-fA-F0-9]{64}$/.test(txHash);
937
+ case "solana":
938
+ return /^[1-9A-HJ-NP-Za-km-z]{80,90}$/.test(txHash);
939
+ case "ton":
940
+ return txHash.length >= 40;
941
+ case "tron":
942
+ return /^[a-fA-F0-9]{64}$/.test(txHash);
943
+ case "spark":
944
+ return txHash.length >= 32;
945
+ default:
946
+ return true;
947
+ }
948
+ }
785
949
  /**
786
950
  * Get the network configuration
787
951
  */
@@ -1267,6 +1431,19 @@ async function getPriceForChain(chain) {
1267
1431
  const prices = await fetchPrices();
1268
1432
  return prices[chain] || 0;
1269
1433
  }
1434
+ function tonFriendlyToRaw(addr) {
1435
+ if (addr.includes(":")) return addr;
1436
+ try {
1437
+ const b64 = addr.replace(/-/g, "+").replace(/_/g, "/");
1438
+ const bytes = Uint8Array.from(atob(b64), (c) => c.charCodeAt(0));
1439
+ if (bytes.length !== 36) return addr;
1440
+ const workchain = bytes[1] === 255 ? -1 : bytes[1];
1441
+ const hash = Array.from(bytes.slice(2, 34)).map((b) => b.toString(16).padStart(2, "0")).join("");
1442
+ return `${workchain}:${hash}`;
1443
+ } catch {
1444
+ return addr;
1445
+ }
1446
+ }
1270
1447
  var STORAGE_KEYS = {
1271
1448
  ENCRYPTED_SEED: "encrypted_seed",
1272
1449
  ACTIVE_WALLET: "active_wallet",
@@ -1285,7 +1462,7 @@ var WalletManager = class _WalletManager {
1285
1462
  const isTestnet = config.network !== "mainnet";
1286
1463
  const ethereumConfig = getNetworkConfig("ethereum", isTestnet);
1287
1464
  this.config = {
1288
- network: config.network || "testnet",
1465
+ network: config.network || "mainnet",
1289
1466
  rpcUrl: config.rpcUrl || ethereumConfig.rpcUrl,
1290
1467
  storage: config.storage || createSecureStorage(),
1291
1468
  enabledChains: config.enabledChains || SUPPORTED_CHAINS,
@@ -1551,7 +1728,7 @@ var WalletManager = class _WalletManager {
1551
1728
  *
1552
1729
  * No fallback to placeholder addresses - WDK API is required for real addresses.
1553
1730
  */
1554
- static async deriveAddressForChainAsync(seed, chain, network = "testnet", apiUrl) {
1731
+ static async deriveAddressForChainAsync(seed, chain, network = "mainnet", apiUrl) {
1555
1732
  if (chain === "ethereum") {
1556
1733
  try {
1557
1734
  const wdkService2 = getZubariWdkService({ network, apiUrl });
@@ -1771,26 +1948,53 @@ var WalletManager = class _WalletManager {
1771
1948
  }
1772
1949
  const networkConfig = this.getChainConfig(chain);
1773
1950
  let balance = "0";
1951
+ const tokenBalances = {};
1774
1952
  if (chain === "ethereum") {
1775
1953
  const viemChain = this.config.network === "mainnet" ? chains.mainnet : chains.sepolia;
1776
- console.log(`[WalletManager] Fetching ${chain} balance for ${address} using RPC: ${this.config.rpcUrl}`);
1954
+ const isTestnet = this.config.network !== "mainnet";
1777
1955
  const client = viem.createPublicClient({
1778
1956
  chain: viemChain,
1779
1957
  transport: viem.http(this.config.rpcUrl, {
1780
1958
  timeout: 15e3,
1781
- // 15 second timeout
1782
1959
  retryCount: 2,
1783
1960
  retryDelay: 1e3
1784
1961
  })
1785
1962
  });
1786
- try {
1787
- const rawBalance = await client.getBalance({
1788
- address
1789
- });
1790
- balance = viem.formatEther(rawBalance);
1791
- console.log(`[WalletManager] ${chain} balance fetched: ${balance} (raw: ${rawBalance})`);
1792
- } catch (error) {
1793
- console.error(`[WalletManager] Failed to fetch ${chain} balance from ${this.config.rpcUrl}:`, error);
1963
+ const usdtAddr = USDT_ADDRESSES.ethereum?.[isTestnet ? "testnet" : "mainnet"];
1964
+ const erc20BalanceOfAbi = [{
1965
+ type: "function",
1966
+ name: "balanceOf",
1967
+ stateMutability: "view",
1968
+ inputs: [{ name: "account", type: "address" }],
1969
+ outputs: [{ name: "", type: "uint256" }]
1970
+ }];
1971
+ const checksumAddr = viem.getAddress(address);
1972
+ const [ethResult, usdtResult] = await Promise.allSettled([
1973
+ client.getBalance({ address: checksumAddr }),
1974
+ usdtAddr ? client.readContract({
1975
+ address: viem.getAddress(usdtAddr),
1976
+ abi: erc20BalanceOfAbi,
1977
+ functionName: "balanceOf",
1978
+ args: [checksumAddr]
1979
+ }) : Promise.resolve(null)
1980
+ ]);
1981
+ if (ethResult.status === "fulfilled") {
1982
+ balance = viem.formatEther(ethResult.value);
1983
+ } else {
1984
+ console.error(`[WalletManager] Failed to fetch ETH balance:`, ethResult.reason);
1985
+ }
1986
+ if (usdtResult.status === "fulfilled" && usdtResult.value != null) {
1987
+ try {
1988
+ const rawUsdt = BigInt(usdtResult.value);
1989
+ const usdtAmount = Number(rawUsdt) / 1e6;
1990
+ if (usdtAmount > 0) {
1991
+ tokenBalances.USDT = { balance: usdtAmount.toFixed(6), balanceUsd: usdtAmount };
1992
+ }
1993
+ } catch (err) {
1994
+ console.warn("[WalletManager] Failed to parse ETH USDT balance:", err);
1995
+ }
1996
+ } else if (usdtResult.status === "rejected") {
1997
+ console.warn("[WalletManager] Failed to fetch ETH USDT balance:", usdtResult.reason);
1794
1998
  }
1795
1999
  } else if (chain === "bitcoin") {
1796
2000
  const isMainnet = this.config.network === "mainnet" || address.startsWith("bc1") || address.startsWith("1") || address.startsWith("3");
@@ -1846,8 +2050,41 @@ var WalletManager = class _WalletManager {
1846
2050
  } catch (error) {
1847
2051
  console.warn(`Failed to fetch ${chain} balance:`, error);
1848
2052
  }
2053
+ const isTestnet = this.config.network !== "mainnet";
2054
+ const usdtMint = USDT_ADDRESSES.solana?.[isTestnet ? "testnet" : "mainnet"];
2055
+ if (usdtMint) {
2056
+ try {
2057
+ const tokenResponse = await fetch(rpcUrl, {
2058
+ method: "POST",
2059
+ headers: { "Content-Type": "application/json" },
2060
+ body: JSON.stringify({
2061
+ jsonrpc: "2.0",
2062
+ id: 2,
2063
+ method: "getTokenAccountsByOwner",
2064
+ params: [
2065
+ address,
2066
+ { mint: usdtMint },
2067
+ { encoding: "jsonParsed" }
2068
+ ]
2069
+ })
2070
+ });
2071
+ if (tokenResponse.ok) {
2072
+ const tokenData = await tokenResponse.json();
2073
+ const accounts = tokenData.result?.value;
2074
+ if (accounts && accounts.length > 0) {
2075
+ const uiAmount = accounts[0].account?.data?.parsed?.info?.tokenAmount?.uiAmount;
2076
+ if (uiAmount && uiAmount > 0) {
2077
+ tokenBalances.USDT = { balance: uiAmount.toFixed(6), balanceUsd: uiAmount };
2078
+ }
2079
+ }
2080
+ }
2081
+ } catch (error) {
2082
+ console.warn("Failed to fetch Solana USDT balance:", error);
2083
+ }
2084
+ }
1849
2085
  } else if (chain === "tron") {
1850
- const baseUrl = this.config.network === "mainnet" ? "https://api.trongrid.io" : "https://api.shasta.trongrid.io";
2086
+ const tronConfig = getNetworkConfig("tron", this.config.network !== "mainnet");
2087
+ const baseUrl = tronConfig.rpcUrl;
1851
2088
  try {
1852
2089
  const response = await fetch(`${baseUrl}/v1/accounts/${address}`, {
1853
2090
  headers: { "Accept": "application/json" }
@@ -1857,12 +2094,28 @@ var WalletManager = class _WalletManager {
1857
2094
  if (data.data?.[0]?.balance !== void 0) {
1858
2095
  balance = (data.data[0].balance / 1e6).toFixed(6);
1859
2096
  }
2097
+ const isTestnet = this.config.network !== "mainnet";
2098
+ const usdtAddr = USDT_ADDRESSES.tron?.[isTestnet ? "testnet" : "mainnet"];
2099
+ if (usdtAddr && data.data?.[0]?.trc20) {
2100
+ const trc20List = data.data[0].trc20;
2101
+ for (const tokenObj of trc20List) {
2102
+ if (tokenObj[usdtAddr]) {
2103
+ const rawUsdtBalance = BigInt(tokenObj[usdtAddr]);
2104
+ const usdtAmount = Number(rawUsdtBalance) / 1e6;
2105
+ if (usdtAmount > 0) {
2106
+ tokenBalances.USDT = { balance: usdtAmount.toFixed(6), balanceUsd: usdtAmount };
2107
+ }
2108
+ break;
2109
+ }
2110
+ }
2111
+ }
1860
2112
  }
1861
2113
  } catch (error) {
1862
2114
  console.warn(`Failed to fetch ${chain} balance:`, error);
1863
2115
  }
1864
2116
  } else if (chain === "ton") {
1865
- const baseUrl = this.config.network === "mainnet" ? "https://toncenter.com/api/v2" : "https://testnet.toncenter.com/api/v2";
2117
+ const isTestnet = this.config.network !== "mainnet";
2118
+ const baseUrl = isTestnet ? "https://testnet.toncenter.com/api/v2" : "https://toncenter.com/api/v2";
1866
2119
  try {
1867
2120
  const response = await fetch(`${baseUrl}/getAddressBalance?address=${address}`, {
1868
2121
  headers: { "Accept": "application/json" }
@@ -1878,6 +2131,42 @@ var WalletManager = class _WalletManager {
1878
2131
  } catch (error) {
1879
2132
  console.warn(`Failed to fetch ${chain} balance:`, error);
1880
2133
  }
2134
+ const usdtJetton = USDT_ADDRESSES.ton?.[isTestnet ? "testnet" : "mainnet"];
2135
+ if (usdtJetton) {
2136
+ const tonapiBaseUrl = isTestnet ? "https://testnet.tonapi.io/v2" : "https://tonapi.io/v2";
2137
+ try {
2138
+ const rawAddr = tonFriendlyToRaw(address);
2139
+ const jettonResponse = await fetch(
2140
+ `${tonapiBaseUrl}/accounts/${encodeURIComponent(rawAddr)}/jettons?currencies=usd`,
2141
+ { headers: { "Accept": "application/json" } }
2142
+ );
2143
+ if (jettonResponse.ok) {
2144
+ const jettonData = await jettonResponse.json();
2145
+ const balances = jettonData.balances;
2146
+ if (balances && balances.length > 0) {
2147
+ for (const jb of balances) {
2148
+ const jettonAddr = jb.jetton?.address;
2149
+ if (jettonAddr) {
2150
+ const usdtRaw = tonFriendlyToRaw(usdtJetton);
2151
+ if (jettonAddr.toLowerCase() === usdtRaw.toLowerCase()) {
2152
+ const rawBalance = jb.balance;
2153
+ if (rawBalance) {
2154
+ const decimals = jb.jetton?.decimals || 6;
2155
+ const usdtAmount = Number(BigInt(rawBalance)) / Math.pow(10, decimals);
2156
+ if (usdtAmount > 0) {
2157
+ tokenBalances.USDT = { balance: usdtAmount.toFixed(6), balanceUsd: usdtAmount };
2158
+ }
2159
+ }
2160
+ break;
2161
+ }
2162
+ }
2163
+ }
2164
+ }
2165
+ }
2166
+ } catch (error) {
2167
+ console.warn("Failed to fetch TON USDT jetton balance:", error);
2168
+ }
2169
+ }
1881
2170
  } else if (chain === "spark") {
1882
2171
  try {
1883
2172
  const response = await fetch(`${this.config.apiUrl}/api/wallets/wdk/balance`, {
@@ -1909,7 +2198,8 @@ var WalletManager = class _WalletManager {
1909
2198
  balance,
1910
2199
  balanceUsd,
1911
2200
  address,
1912
- decimals: networkConfig.nativeCurrency.decimals
2201
+ decimals: networkConfig.nativeCurrency.decimals,
2202
+ ...Object.keys(tokenBalances).length > 0 ? { tokenBalances } : {}
1913
2203
  };
1914
2204
  }
1915
2205
  /**