@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.
- package/dist/{TransactionService-Djonkbp4.d.ts → TransactionService-BtWUjKt_.d.ts} +14 -2
- package/dist/{TransactionService-1Jt8ZRqO.d.mts → TransactionService-Lr_WS6iR.d.mts} +14 -2
- package/dist/{WalletManager-DfvFJ-mk.d.ts → WalletManager-DQQwVkoa.d.ts} +4 -0
- package/dist/{WalletManager-j0tgNIKi.d.mts → WalletManager-Sbpx4E1-.d.mts} +4 -0
- package/dist/{contracts-BahTuxZj.d.mts → contracts-B842YprC.d.mts} +2 -2
- package/dist/{contracts-D7rVmNJy.d.ts → contracts-s_CDIruh.d.ts} +2 -2
- package/dist/index.d.mts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +305 -23
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +306 -24
- package/dist/index.mjs.map +1 -1
- package/dist/protocols/index.js +2 -2
- package/dist/protocols/index.js.map +1 -1
- package/dist/protocols/index.mjs +2 -2
- package/dist/protocols/index.mjs.map +1 -1
- package/dist/react/index.d.mts +2 -2
- package/dist/react/index.d.ts +2 -2
- package/dist/react/index.js +303 -21
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +304 -22
- package/dist/react/index.mjs.map +1 -1
- package/dist/services/index.d.mts +1 -1
- package/dist/services/index.d.ts +1 -1
- package/dist/services/index.js +132 -8
- package/dist/services/index.js.map +1 -1
- package/dist/services/index.mjs +132 -8
- package/dist/services/index.mjs.map +1 -1
- package/dist/wallet/index.d.mts +2 -2
- package/dist/wallet/index.d.ts +2 -2
- package/dist/wallet/index.js +303 -21
- package/dist/wallet/index.js.map +1 -1
- package/dist/wallet/index.mjs +304 -22
- package/dist/wallet/index.mjs.map +1 -1
- 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: "
|
|
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 (
|
|
1036
|
-
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
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
|
|
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
|
|
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
|
/**
|