@stableflow/wallet-tron 3.0.0-beta-02a59f37a0-20260515
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/README.md +29 -0
- package/dist/index.d.mts +91 -0
- package/dist/index.d.ts +91 -0
- package/dist/index.js +884 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +875 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +45 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,884 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var core = require('@stableflow/core');
|
|
6
|
+
var bridges = require('@stableflow/bridges');
|
|
7
|
+
var utilsEvm = require('@stableflow/utils-evm');
|
|
8
|
+
var utilsSolana = require('@stableflow/utils-solana');
|
|
9
|
+
var ethers = require('ethers');
|
|
10
|
+
var Big = require('big.js');
|
|
11
|
+
var tronweb = require('tronweb');
|
|
12
|
+
|
|
13
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
14
|
+
|
|
15
|
+
var Big__default = /*#__PURE__*/_interopDefault(Big);
|
|
16
|
+
|
|
17
|
+
// src/tron.ts
|
|
18
|
+
var DefaultTronWalletAddress = core.DefaultAddresses["tron"];
|
|
19
|
+
var getCustomTronWeb = () => {
|
|
20
|
+
return new tronweb.TronWeb({
|
|
21
|
+
fullHost: core.getChainRpcUrl("tron").rpcUrl,
|
|
22
|
+
headers: {},
|
|
23
|
+
privateKey: ""
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
var TronWallet = class {
|
|
27
|
+
constructor(options) {
|
|
28
|
+
this.signAndSendTransaction = options.signAndSendTransaction;
|
|
29
|
+
this.address = options.address;
|
|
30
|
+
const customTronWeb = getCustomTronWeb();
|
|
31
|
+
customTronWeb.setAddress(this.address || DefaultTronWalletAddress);
|
|
32
|
+
this.tronWeb = customTronWeb;
|
|
33
|
+
const cs = new core.Csl(core.OpenAPI.DEBUG);
|
|
34
|
+
this.csl = cs.log;
|
|
35
|
+
}
|
|
36
|
+
async waitForTronWeb() {
|
|
37
|
+
return new Promise((resolve) => {
|
|
38
|
+
if (this.tronWeb) {
|
|
39
|
+
const address = this.tronWeb.defaultAddress.base58 || DefaultTronWalletAddress;
|
|
40
|
+
const customTronWeb = getCustomTronWeb();
|
|
41
|
+
customTronWeb.setAddress(address);
|
|
42
|
+
this.tronWeb = customTronWeb;
|
|
43
|
+
resolve(this.tronWeb);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const checkTronWeb = () => {
|
|
47
|
+
if (window.tronWeb) {
|
|
48
|
+
this.tronWeb = window.tronWeb;
|
|
49
|
+
const address = this.tronWeb.defaultAddress.base58 || DefaultTronWalletAddress;
|
|
50
|
+
const customTronWeb = getCustomTronWeb();
|
|
51
|
+
customTronWeb.setAddress(address);
|
|
52
|
+
this.tronWeb = customTronWeb;
|
|
53
|
+
resolve(this.tronWeb);
|
|
54
|
+
} else {
|
|
55
|
+
setTimeout(checkTronWeb, 100);
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
checkTronWeb();
|
|
59
|
+
setTimeout(() => {
|
|
60
|
+
const customTronWeb = getCustomTronWeb();
|
|
61
|
+
customTronWeb.setAddress(DefaultTronWalletAddress);
|
|
62
|
+
this.tronWeb = customTronWeb;
|
|
63
|
+
resolve(this.tronWeb);
|
|
64
|
+
this.csl("TronWallet waitForTronWeb", "red-500", "TronWeb initialization timeout");
|
|
65
|
+
}, 1e4);
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
async transfer(data) {
|
|
69
|
+
const { originAsset, depositAddress, amount } = data;
|
|
70
|
+
await this.waitForTronWeb();
|
|
71
|
+
if (originAsset === "TRX" || originAsset === "trx") {
|
|
72
|
+
return await this.transferTRX(depositAddress, amount);
|
|
73
|
+
}
|
|
74
|
+
return await this.transferToken(originAsset, depositAddress, amount);
|
|
75
|
+
}
|
|
76
|
+
async transferTRX(to, amount) {
|
|
77
|
+
await this.waitForTronWeb();
|
|
78
|
+
const transaction = await this.tronWeb.transactionBuilder.sendTrx(
|
|
79
|
+
to,
|
|
80
|
+
this.tronWeb.toSun(amount)
|
|
81
|
+
);
|
|
82
|
+
return this.sendTransaction({ tx: { transaction } });
|
|
83
|
+
}
|
|
84
|
+
async transferToken(contractAddress, to, amount) {
|
|
85
|
+
await this.waitForTronWeb();
|
|
86
|
+
const functionSelector = "transfer(address,uint256)";
|
|
87
|
+
const parameter = [{ type: "address", value: to }, { type: "uint256", value: amount }];
|
|
88
|
+
const tx = await this.tronWeb.transactionBuilder.triggerSmartContract(contractAddress, functionSelector, {}, parameter);
|
|
89
|
+
return this.sendTransaction({ tx });
|
|
90
|
+
}
|
|
91
|
+
async getBalance(token, account, options) {
|
|
92
|
+
await this.waitForTronWeb();
|
|
93
|
+
if (token.symbol === "TRX" || token.symbol === "trx" || token.symbol === "native") {
|
|
94
|
+
return await this.getTRXBalance(account, options);
|
|
95
|
+
}
|
|
96
|
+
return await this.getTokenBalance(token.contractAddress, account, options);
|
|
97
|
+
}
|
|
98
|
+
async getTRXBalance(account, options) {
|
|
99
|
+
const { isCatchError = false } = options || {};
|
|
100
|
+
await this.waitForTronWeb();
|
|
101
|
+
try {
|
|
102
|
+
const balance = await this.tronWeb.trx.getBalance(account);
|
|
103
|
+
return balance.toString();
|
|
104
|
+
} catch (error) {
|
|
105
|
+
this.csl("Tron getTRXBalance", "red-500", "Get TRX balance failed: %o", error);
|
|
106
|
+
if (isCatchError) {
|
|
107
|
+
throw error;
|
|
108
|
+
}
|
|
109
|
+
return "0";
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
async getTokenBalance(contractAddress, account, options) {
|
|
113
|
+
const { isCatchError = false } = options || {};
|
|
114
|
+
await this.waitForTronWeb();
|
|
115
|
+
try {
|
|
116
|
+
const contract = await this.tronWeb.contract().at(contractAddress);
|
|
117
|
+
const balance = await contract.balanceOf(account).call();
|
|
118
|
+
return balance.toString();
|
|
119
|
+
} catch (error) {
|
|
120
|
+
this.csl("Tron getTokenBalance", "red-500", "Get token balance failed: %o", error);
|
|
121
|
+
if (isCatchError) {
|
|
122
|
+
throw error;
|
|
123
|
+
}
|
|
124
|
+
return "0";
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
async balanceOf(token, account, options) {
|
|
128
|
+
return await this.getBalance(token, account, options);
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Estimate gas limit for transfer transaction
|
|
132
|
+
* @param data Transfer data
|
|
133
|
+
* @returns Gas limit estimate (bandwidth or energy), gas price, and estimated gas cost
|
|
134
|
+
*/
|
|
135
|
+
async estimateTransferGas(data) {
|
|
136
|
+
const { fromToken } = data;
|
|
137
|
+
const originAsset = fromToken.contractAddress;
|
|
138
|
+
let gasLimit;
|
|
139
|
+
if (originAsset === "TRX" || originAsset === "trx") {
|
|
140
|
+
gasLimit = 268n;
|
|
141
|
+
} else {
|
|
142
|
+
gasLimit = 30000n;
|
|
143
|
+
}
|
|
144
|
+
gasLimit = gasLimit * 120n / 100n;
|
|
145
|
+
let gasPrice = 100n;
|
|
146
|
+
const estimateGas = gasLimit * gasPrice;
|
|
147
|
+
return {
|
|
148
|
+
gasLimit,
|
|
149
|
+
gasPrice,
|
|
150
|
+
estimateGas
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
async getEstimateGas(params) {
|
|
154
|
+
const { gasLimit, price, nativeToken } = params;
|
|
155
|
+
const energyPrice = BigInt(100);
|
|
156
|
+
const estimateGas = Big__default.default(gasLimit.toString()).times(energyPrice.toString());
|
|
157
|
+
const estimateGasAmount = Big__default.default(estimateGas).div(10 ** nativeToken.decimals);
|
|
158
|
+
const estimateGasUsd = Big__default.default(estimateGasAmount).times(price || 1);
|
|
159
|
+
return {
|
|
160
|
+
gasPrice: energyPrice,
|
|
161
|
+
usd: core.numberRemoveEndZero(Big__default.default(estimateGasUsd).toFixed(20)),
|
|
162
|
+
wei: BigInt(estimateGas.toFixed(0)),
|
|
163
|
+
amount: core.numberRemoveEndZero(Big__default.default(estimateGasAmount).toFixed(nativeToken.decimals))
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
async estimateTransaction(params) {
|
|
167
|
+
const {
|
|
168
|
+
dry,
|
|
169
|
+
transactionParams,
|
|
170
|
+
fromToken,
|
|
171
|
+
prices,
|
|
172
|
+
defaultEnergyUsed,
|
|
173
|
+
defaultRawDataHexLength,
|
|
174
|
+
buffer
|
|
175
|
+
} = params;
|
|
176
|
+
const nativeTokenPrice = core.getPrice(prices, fromToken.nativeToken.symbol);
|
|
177
|
+
let energyUsed = defaultEnergyUsed || 2e5;
|
|
178
|
+
let rawDataHexLength = defaultRawDataHexLength || 1e3;
|
|
179
|
+
try {
|
|
180
|
+
const transaction = await this.tronWeb.transactionBuilder.triggerConstantContract(...transactionParams);
|
|
181
|
+
energyUsed = transaction.energy_used || 2e5;
|
|
182
|
+
rawDataHexLength = transaction.transaction.raw_data_hex.length || 1e3;
|
|
183
|
+
} catch (error) {
|
|
184
|
+
this.csl("Usdt0 Tron", "red-500", "estimateTransaction triggerConstantContract error: %o, action: %o", error, transactionParams?.[1]);
|
|
185
|
+
}
|
|
186
|
+
const bandwidthAmount = Big__default.default(Big__default.default(rawDataHexLength).div(2).plus(bridges.DATA_HEX_PROTOBUF_EXTRA).plus(bridges.SIGNATURE_SIZE)).times(1e-3);
|
|
187
|
+
const bandwidthUsed = Big__default.default(bandwidthAmount).div(100).times(10 ** fromToken.nativeToken.decimals);
|
|
188
|
+
let totalUsed = Big__default.default(energyUsed).plus(bandwidthUsed);
|
|
189
|
+
if (buffer) {
|
|
190
|
+
totalUsed = Big__default.default(totalUsed).times(Big__default.default(1).plus(buffer));
|
|
191
|
+
}
|
|
192
|
+
const { usd, wei } = await this.getEstimateGas({
|
|
193
|
+
gasLimit: totalUsed.toFixed(0),
|
|
194
|
+
price: nativeTokenPrice,
|
|
195
|
+
nativeToken: fromToken.nativeToken
|
|
196
|
+
});
|
|
197
|
+
const result = {
|
|
198
|
+
estimateSourceGasLimit: energyUsed,
|
|
199
|
+
estimateSourceGas: wei,
|
|
200
|
+
estimateSourceGasUsd: usd
|
|
201
|
+
};
|
|
202
|
+
return result;
|
|
203
|
+
}
|
|
204
|
+
async estimateApprove(params) {
|
|
205
|
+
const {
|
|
206
|
+
dry,
|
|
207
|
+
spender,
|
|
208
|
+
amountWei,
|
|
209
|
+
fromToken,
|
|
210
|
+
prices
|
|
211
|
+
} = params;
|
|
212
|
+
const approveParams = [
|
|
213
|
+
fromToken.contractAddress,
|
|
214
|
+
"approve(address,uint256)",
|
|
215
|
+
{},
|
|
216
|
+
[
|
|
217
|
+
{ type: "address", value: spender },
|
|
218
|
+
{ type: "uint256", value: amountWei }
|
|
219
|
+
]
|
|
220
|
+
];
|
|
221
|
+
return this.estimateTransaction({
|
|
222
|
+
dry,
|
|
223
|
+
transactionParams: approveParams,
|
|
224
|
+
fromToken,
|
|
225
|
+
prices,
|
|
226
|
+
defaultEnergyUsed: 1e5,
|
|
227
|
+
defaultRawDataHexLength: 500,
|
|
228
|
+
// +10%
|
|
229
|
+
buffer: 0.1
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
async pollingTransactionStatus(txHash, options) {
|
|
233
|
+
await this.waitForTronWeb();
|
|
234
|
+
const { maxPolls = 60, pollInterval = 2e3, isTRX } = options || {};
|
|
235
|
+
let pollCount = 0;
|
|
236
|
+
return new Promise((resolve) => {
|
|
237
|
+
const poll = async () => {
|
|
238
|
+
pollCount++;
|
|
239
|
+
this.csl("TronWallet pollingTransactionStatus", "teal-400", "polling transaction status (%s), %d times", txHash, pollCount);
|
|
240
|
+
try {
|
|
241
|
+
const txInfo = await this.tronWeb.trx.getTransactionInfo(txHash);
|
|
242
|
+
this.csl("TronWallet pollingTransactionStatus", "teal-400", "transaction info (%s): %o", txHash, txInfo);
|
|
243
|
+
if (txInfo && txInfo.receipt) {
|
|
244
|
+
if (isTRX) {
|
|
245
|
+
resolve(true);
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
const result = txInfo.receipt.result;
|
|
249
|
+
if (result === "SUCCESS") {
|
|
250
|
+
this.csl("TronWallet pollingTransactionStatus", "teal-400", "transaction success (%s)", txHash);
|
|
251
|
+
resolve(true);
|
|
252
|
+
return;
|
|
253
|
+
} else if (result === "FAILED" || result === "REVERT") {
|
|
254
|
+
this.csl("TronWallet pollingTransactionStatus", "red-500", "transaction failed (%s), result: %s", txHash, result);
|
|
255
|
+
resolve(false);
|
|
256
|
+
return;
|
|
257
|
+
} else {
|
|
258
|
+
this.csl("TronWallet pollingTransactionStatus", "teal-400", "unknown transaction status (%s), result: %s, continue polling...", txHash, result);
|
|
259
|
+
}
|
|
260
|
+
} else {
|
|
261
|
+
this.csl("TronWallet pollingTransactionStatus", "teal-400", "transaction not confirmed (%s), continue polling...", txHash);
|
|
262
|
+
}
|
|
263
|
+
} catch (error) {
|
|
264
|
+
const errorMessage = error?.message || String(error);
|
|
265
|
+
if (errorMessage.includes("not found") || errorMessage.includes("does not exist") || errorMessage.includes("not exist")) {
|
|
266
|
+
this.csl("TronWallet pollingTransactionStatus", "teal-400", "transaction not on-chain (%s), continue polling...", txHash);
|
|
267
|
+
} else {
|
|
268
|
+
console.warn(`query transaction status error (${txHash}): %o`, errorMessage);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
if (pollCount >= maxPolls) {
|
|
272
|
+
console.error(`polling timeout (${txHash}), maximum polling times reached: ${maxPolls}`);
|
|
273
|
+
resolve(false);
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
setTimeout(poll, pollInterval);
|
|
277
|
+
};
|
|
278
|
+
poll();
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
async checkTransactionStatus(txHash) {
|
|
282
|
+
await this.waitForTronWeb();
|
|
283
|
+
try {
|
|
284
|
+
const txInfo = await this.tronWeb.trx.getTransactionInfo(txHash);
|
|
285
|
+
if (txInfo && txInfo.receipt) {
|
|
286
|
+
return txInfo.receipt.result === "SUCCESS";
|
|
287
|
+
}
|
|
288
|
+
return false;
|
|
289
|
+
} catch (error) {
|
|
290
|
+
return false;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
async getTransactionResult(txHash) {
|
|
294
|
+
await this.waitForTronWeb();
|
|
295
|
+
try {
|
|
296
|
+
const txInfo = await this.tronWeb.trx.getTransactionInfo(txHash);
|
|
297
|
+
return txInfo;
|
|
298
|
+
} catch (error) {
|
|
299
|
+
return {};
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
async allowance(params) {
|
|
303
|
+
const {
|
|
304
|
+
dry,
|
|
305
|
+
contractAddress,
|
|
306
|
+
spender,
|
|
307
|
+
address,
|
|
308
|
+
amountWei,
|
|
309
|
+
strict = false
|
|
310
|
+
} = params;
|
|
311
|
+
const contract = await this.tronWeb.contract().at(contractAddress);
|
|
312
|
+
if (dry) {
|
|
313
|
+
return {
|
|
314
|
+
contract,
|
|
315
|
+
allowance: "0",
|
|
316
|
+
needApprove: false
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
await this.waitForTronWeb();
|
|
320
|
+
try {
|
|
321
|
+
let allowance = "0";
|
|
322
|
+
try {
|
|
323
|
+
const allowanceResult = await contract.allowance(address, spender).call();
|
|
324
|
+
allowance = allowanceResult.toString();
|
|
325
|
+
} catch (error) {
|
|
326
|
+
this.csl("TronWallet allowance", "red-500", "Error getting allowance: %o", error);
|
|
327
|
+
if (strict) {
|
|
328
|
+
throw error;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
return {
|
|
332
|
+
contract,
|
|
333
|
+
allowance,
|
|
334
|
+
needApprove: Big__default.default(amountWei || 0).gt(allowance || 0)
|
|
335
|
+
};
|
|
336
|
+
} catch (error) {
|
|
337
|
+
this.csl("TronWallet allowance", "red-500", "Error in allowance: %o", error);
|
|
338
|
+
if (strict) {
|
|
339
|
+
throw error;
|
|
340
|
+
}
|
|
341
|
+
return {
|
|
342
|
+
contract: null,
|
|
343
|
+
allowance: "0",
|
|
344
|
+
needApprove: true
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
async approve(params) {
|
|
349
|
+
const {
|
|
350
|
+
contractAddress,
|
|
351
|
+
spender,
|
|
352
|
+
amountWei,
|
|
353
|
+
isApproveMax = false,
|
|
354
|
+
isDetails = false,
|
|
355
|
+
isWaitTxReceipt = true
|
|
356
|
+
} = params;
|
|
357
|
+
await this.waitForTronWeb();
|
|
358
|
+
const detailResult = {
|
|
359
|
+
success: false,
|
|
360
|
+
data: {},
|
|
361
|
+
message: null
|
|
362
|
+
};
|
|
363
|
+
try {
|
|
364
|
+
let _amountWei = amountWei;
|
|
365
|
+
if (isApproveMax) {
|
|
366
|
+
_amountWei = "115792089237316195423570985008687907853269984665640564039457584007913129639935";
|
|
367
|
+
}
|
|
368
|
+
const functionSelector = "approve(address,uint256)";
|
|
369
|
+
const parameter = [
|
|
370
|
+
{ type: "address", value: spender },
|
|
371
|
+
{ type: "uint256", value: _amountWei }
|
|
372
|
+
];
|
|
373
|
+
const tx = await this.tronWeb.transactionBuilder.triggerSmartContract(
|
|
374
|
+
contractAddress,
|
|
375
|
+
functionSelector,
|
|
376
|
+
{},
|
|
377
|
+
parameter
|
|
378
|
+
);
|
|
379
|
+
const txHash = await this.sendTransaction({ tx });
|
|
380
|
+
let txInfo = null;
|
|
381
|
+
if (isWaitTxReceipt) {
|
|
382
|
+
const pollingResult = await this.pollingTransactionStatus(txHash, {
|
|
383
|
+
maxPolls: 120,
|
|
384
|
+
pollInterval: 2e3
|
|
385
|
+
});
|
|
386
|
+
if (!pollingResult) {
|
|
387
|
+
this.csl("TronWallet approve", "red-500", "Failed polling approve transaction status");
|
|
388
|
+
if (isDetails) {
|
|
389
|
+
detailResult.message = "Failed to get approve result";
|
|
390
|
+
return detailResult;
|
|
391
|
+
}
|
|
392
|
+
return false;
|
|
393
|
+
}
|
|
394
|
+
txInfo = await this.getTransactionResult(txHash);
|
|
395
|
+
}
|
|
396
|
+
if (isDetails) {
|
|
397
|
+
const txReceipt = txInfo?.receipt;
|
|
398
|
+
detailResult.success = true;
|
|
399
|
+
detailResult.data = {
|
|
400
|
+
txHash,
|
|
401
|
+
txInfo,
|
|
402
|
+
receiptResult: txReceipt?.result,
|
|
403
|
+
blockNumber: txInfo?.blockNumber,
|
|
404
|
+
blockTimeStamp: txInfo?.blockTimeStamp
|
|
405
|
+
};
|
|
406
|
+
return detailResult;
|
|
407
|
+
}
|
|
408
|
+
return txHash;
|
|
409
|
+
} catch (error) {
|
|
410
|
+
this.csl("TronWallet approve", "red-500", "Error approve: %o", error);
|
|
411
|
+
if (isDetails) {
|
|
412
|
+
detailResult.message = error.message;
|
|
413
|
+
return detailResult;
|
|
414
|
+
}
|
|
415
|
+
return false;
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
toBytes32(addr) {
|
|
419
|
+
const hex = this.tronWeb.address.toHex(addr).slice(2);
|
|
420
|
+
return "0x" + hex.padStart(64, "0");
|
|
421
|
+
}
|
|
422
|
+
async quoteOFT(params) {
|
|
423
|
+
const {
|
|
424
|
+
dry,
|
|
425
|
+
abi,
|
|
426
|
+
dstEid,
|
|
427
|
+
recipient,
|
|
428
|
+
amountWei,
|
|
429
|
+
slippageTolerance,
|
|
430
|
+
payInLzToken,
|
|
431
|
+
fromToken,
|
|
432
|
+
toToken,
|
|
433
|
+
prices,
|
|
434
|
+
originLayerzeroAddress,
|
|
435
|
+
destinationLayerzeroAddress,
|
|
436
|
+
excludeFees,
|
|
437
|
+
refundTo,
|
|
438
|
+
multiHopComposer,
|
|
439
|
+
isMultiHopComposer,
|
|
440
|
+
isOriginLegacy,
|
|
441
|
+
isDestinationLegacy,
|
|
442
|
+
originLayerzero,
|
|
443
|
+
destinationLayerzero
|
|
444
|
+
} = params;
|
|
445
|
+
const { Options } = await import('@layerzerolabs/lz-v2-utilities');
|
|
446
|
+
const result = {
|
|
447
|
+
needApprove: false,
|
|
448
|
+
approveSpender: originLayerzeroAddress,
|
|
449
|
+
sendParam: void 0,
|
|
450
|
+
quoteParam: {
|
|
451
|
+
...params,
|
|
452
|
+
originLayerzeroAddress,
|
|
453
|
+
destinationLayerzeroAddress
|
|
454
|
+
},
|
|
455
|
+
fees: {},
|
|
456
|
+
totalFeesUsd: void 0,
|
|
457
|
+
estimateSourceGas: void 0,
|
|
458
|
+
totalEstimateSourceGas: 0n,
|
|
459
|
+
estimateSourceGasUsd: void 0,
|
|
460
|
+
estimateTime: 0,
|
|
461
|
+
// seconds - dynamically calculated using LayerZero formula
|
|
462
|
+
outputAmount: core.numberRemoveEndZero(Big__default.default(amountWei || 0).div(10 ** params.fromToken.decimals).toFixed(params.fromToken.decimals, 0))
|
|
463
|
+
};
|
|
464
|
+
const execTime = new core.ExecTime({ type: "USDT0 Tron", logStyle: "indigo-300", isDebug: core.OpenAPI.DEBUG });
|
|
465
|
+
await this.waitForTronWeb();
|
|
466
|
+
execTime.log("waitForTronWeb");
|
|
467
|
+
execTime.breakpoint();
|
|
468
|
+
const oftContract = await this.tronWeb.contract(abi, originLayerzeroAddress);
|
|
469
|
+
execTime.log("tronWeb.contract originLayerzeroAddress");
|
|
470
|
+
execTime.breakpoint();
|
|
471
|
+
const userAddress = refundTo || this.tronWeb.defaultAddress.base58;
|
|
472
|
+
const approvalRequired = isOriginLegacy ? originLayerzero.oftLegacyApprovalRequired : originLayerzero.oftApprovalRequired;
|
|
473
|
+
execTime.log("approvalRequired");
|
|
474
|
+
const lzReceiveOptionGas = isDestinationLegacy ? destinationLayerzero.lzReceiveOptionGasLegacy : destinationLayerzero.lzReceiveOptionGas;
|
|
475
|
+
let lzReceiveOptionValue = 0;
|
|
476
|
+
execTime.breakpoint();
|
|
477
|
+
const destATA = await utilsSolana.getDestinationAssociatedTokenAddress({
|
|
478
|
+
recipient,
|
|
479
|
+
toToken
|
|
480
|
+
});
|
|
481
|
+
execTime.log("getDestinationAssociatedTokenAddress");
|
|
482
|
+
if (destATA.needCreateTokenAccount) {
|
|
483
|
+
lzReceiveOptionValue = bridges.LZ_RECEIVE_VALUE[toToken.chainName] || 0;
|
|
484
|
+
}
|
|
485
|
+
let unMultiHopExtraOptions = Options.newOptions().toHex();
|
|
486
|
+
if (!isMultiHopComposer && lzReceiveOptionValue) {
|
|
487
|
+
unMultiHopExtraOptions = Options.newOptions().addExecutorLzReceiveOption(lzReceiveOptionGas, lzReceiveOptionValue).toHex();
|
|
488
|
+
}
|
|
489
|
+
const sendParam = [
|
|
490
|
+
// dstEid
|
|
491
|
+
dstEid,
|
|
492
|
+
// to
|
|
493
|
+
// "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
494
|
+
core.addressToBytes32(toToken.chainType, recipient),
|
|
495
|
+
// amountLD
|
|
496
|
+
amountWei,
|
|
497
|
+
// minAmountLD
|
|
498
|
+
"0",
|
|
499
|
+
// extraOptions
|
|
500
|
+
unMultiHopExtraOptions,
|
|
501
|
+
// composeMsg
|
|
502
|
+
"0x",
|
|
503
|
+
// oftCmd
|
|
504
|
+
"0x"
|
|
505
|
+
];
|
|
506
|
+
if (isMultiHopComposer) {
|
|
507
|
+
sendParam[0] = multiHopComposer.eid;
|
|
508
|
+
sendParam[1] = core.addressToBytes32("evm", multiHopComposer.oftMultiHopComposer);
|
|
509
|
+
}
|
|
510
|
+
if (!dry) {
|
|
511
|
+
execTime.breakpoint();
|
|
512
|
+
const oftData = await oftContract.quoteOFT(sendParam).call();
|
|
513
|
+
execTime.log("quoteOFT");
|
|
514
|
+
const [, , oftReceipt] = oftData;
|
|
515
|
+
sendParam[3] = Big__default.default(oftReceipt[1].toString()).times(Big__default.default(1).minus(Big__default.default(slippageTolerance || 0).div(100))).toFixed(0);
|
|
516
|
+
}
|
|
517
|
+
if (isMultiHopComposer) {
|
|
518
|
+
let multiHopExtraOptions = Options.newOptions().toHex();
|
|
519
|
+
if (lzReceiveOptionValue) {
|
|
520
|
+
multiHopExtraOptions = Options.newOptions().addExecutorLzReceiveOption(lzReceiveOptionGas, lzReceiveOptionValue).toHex();
|
|
521
|
+
}
|
|
522
|
+
const composeMsgSendParam = {
|
|
523
|
+
dstEid,
|
|
524
|
+
to: core.addressToBytes32(toToken.chainType, recipient),
|
|
525
|
+
amountLD: sendParam[2],
|
|
526
|
+
minAmountLD: sendParam[3],
|
|
527
|
+
extraOptions: multiHopExtraOptions,
|
|
528
|
+
composeMsg: "0x",
|
|
529
|
+
oftCmd: "0x"
|
|
530
|
+
};
|
|
531
|
+
execTime.breakpoint();
|
|
532
|
+
const hopMsgFee = await bridges.getHopMsgFee({
|
|
533
|
+
sendParam: composeMsgSendParam,
|
|
534
|
+
toToken
|
|
535
|
+
});
|
|
536
|
+
execTime.log("getHopMsgFee");
|
|
537
|
+
sendParam[4] = Options.newOptions().addExecutorComposeOption(0, originLayerzero.composeOptionGas || 8e5, hopMsgFee).toHex();
|
|
538
|
+
const abiCoder = ethers.ethers.AbiCoder.defaultAbiCoder();
|
|
539
|
+
sendParam[5] = abiCoder.encode(
|
|
540
|
+
["tuple(uint32 dstEid, bytes32 to, uint256 amountLD, uint256 minAmountLD, bytes extraOptions, bytes composeMsg, bytes oftCmd)"],
|
|
541
|
+
[Object.values(composeMsgSendParam)]
|
|
542
|
+
);
|
|
543
|
+
}
|
|
544
|
+
execTime.breakpoint();
|
|
545
|
+
const mergedCalls = [
|
|
546
|
+
oftContract.quoteSend(sendParam, payInLzToken).call()
|
|
547
|
+
];
|
|
548
|
+
if (approvalRequired) {
|
|
549
|
+
mergedCalls.push(
|
|
550
|
+
this.allowance({
|
|
551
|
+
dry,
|
|
552
|
+
contractAddress: fromToken.contractAddress,
|
|
553
|
+
spender: originLayerzeroAddress,
|
|
554
|
+
address: userAddress,
|
|
555
|
+
amountWei
|
|
556
|
+
})
|
|
557
|
+
);
|
|
558
|
+
}
|
|
559
|
+
const [msgFee, allowanceResult] = await Promise.all(mergedCalls);
|
|
560
|
+
if (approvalRequired) {
|
|
561
|
+
result.needApprove = allowanceResult.needApprove;
|
|
562
|
+
}
|
|
563
|
+
execTime.log("quoteSend & allowance", "allowanceResult: %o", allowanceResult);
|
|
564
|
+
let nativeMsgFee = msgFee[0]["nativeFee"];
|
|
565
|
+
this.csl("Tron quoteOFT", "red-600", "nativeFee: %o", nativeMsgFee);
|
|
566
|
+
if (nativeMsgFee) {
|
|
567
|
+
nativeMsgFee = BigInt(Big__default.default(nativeMsgFee.toString()).times(Number(utilsEvm.NATIVE_MSG_FEE_BUFFER) / 100).toFixed(0));
|
|
568
|
+
}
|
|
569
|
+
this.csl("Tron quoteOFT", "red-600", "nativeFee after buffer: %o", nativeMsgFee);
|
|
570
|
+
result.totalEstimateSourceGas = nativeMsgFee;
|
|
571
|
+
this.csl("TronWallet quoteOFT", "teal-400", "MsgFee: %o", msgFee);
|
|
572
|
+
result.sendParam = {
|
|
573
|
+
param: [
|
|
574
|
+
// sendParam
|
|
575
|
+
sendParam,
|
|
576
|
+
// feeParam
|
|
577
|
+
[
|
|
578
|
+
// nativeFee
|
|
579
|
+
nativeMsgFee.toString(),
|
|
580
|
+
// lzTokenFee
|
|
581
|
+
msgFee[0]["lzTokenFee"].toString()
|
|
582
|
+
],
|
|
583
|
+
// refundAddress
|
|
584
|
+
refundTo
|
|
585
|
+
],
|
|
586
|
+
options: { callValue: nativeMsgFee.toString() }
|
|
587
|
+
};
|
|
588
|
+
const nativeFeeUsd = Big__default.default(nativeMsgFee?.toString() || 0).div(10 ** fromToken.nativeToken.decimals).times(core.getPrice(prices, fromToken.nativeToken.symbol));
|
|
589
|
+
result.fees.nativeFee = core.numberRemoveEndZero(Big__default.default(nativeMsgFee?.toString() || 0).div(10 ** fromToken.nativeToken.decimals).toFixed(fromToken.nativeToken.decimals));
|
|
590
|
+
result.fees.nativeFeeUsd = core.numberRemoveEndZero(Big__default.default(nativeFeeUsd).toFixed(20));
|
|
591
|
+
result.fees.lzTokenFeeUsd = core.numberRemoveEndZero(Big__default.default(msgFee[0]["lzTokenFee"]?.toString() || 0).div(10 ** fromToken.decimals).toFixed(20));
|
|
592
|
+
if (isOriginLegacy || isDestinationLegacy) {
|
|
593
|
+
result.fees.legacyMeshFeeUsd = core.numberRemoveEndZero(Big__default.default(amountWei || 0).div(10 ** fromToken.decimals).times(bridges.USDT0_LEGACY_MESH_TRANSFTER_FEE).toFixed(fromToken.decimals));
|
|
594
|
+
result.outputAmount = core.numberRemoveEndZero(Big__default.default(Big__default.default(amountWei || 0).div(10 ** params.fromToken.decimals)).minus(result.fees.legacyMeshFeeUsd || 0).toFixed(params.fromToken.decimals, 0));
|
|
595
|
+
}
|
|
596
|
+
const transactionParams = [
|
|
597
|
+
originLayerzeroAddress,
|
|
598
|
+
"send((uint32,bytes32,uint256,uint256,bytes,bytes,bytes),(uint256,uint256),address)",
|
|
599
|
+
result.sendParam.options,
|
|
600
|
+
[
|
|
601
|
+
{
|
|
602
|
+
type: "tuple(uint32,bytes32,uint256,uint256,bytes,bytes,bytes)",
|
|
603
|
+
value: result.sendParam.param[0]
|
|
604
|
+
},
|
|
605
|
+
{
|
|
606
|
+
type: "tuple(uint256,uint256)",
|
|
607
|
+
value: result.sendParam.param[1]
|
|
608
|
+
},
|
|
609
|
+
{
|
|
610
|
+
type: "address",
|
|
611
|
+
value: result.sendParam.param[2]
|
|
612
|
+
}
|
|
613
|
+
],
|
|
614
|
+
this.tronWeb.defaultAddress.base58 || refundTo
|
|
615
|
+
];
|
|
616
|
+
if (!dry) {
|
|
617
|
+
execTime.breakpoint();
|
|
618
|
+
const tx = await this.tronWeb.transactionBuilder.triggerSmartContract(...transactionParams);
|
|
619
|
+
execTime.log("transactionBuilder.triggerSmartContract");
|
|
620
|
+
result.sendParam.tx = tx;
|
|
621
|
+
}
|
|
622
|
+
execTime.breakpoint();
|
|
623
|
+
const ett = await this.estimateTransaction({
|
|
624
|
+
dry,
|
|
625
|
+
transactionParams,
|
|
626
|
+
fromToken,
|
|
627
|
+
prices,
|
|
628
|
+
defaultEnergyUsed: 3e5,
|
|
629
|
+
defaultRawDataHexLength: 1e3
|
|
630
|
+
});
|
|
631
|
+
execTime.log("estimateTransaction");
|
|
632
|
+
result.fees.estimateGasUsd = ett.estimateSourceGasUsd;
|
|
633
|
+
result.estimateSourceGas = ett.estimateSourceGas;
|
|
634
|
+
result.totalEstimateSourceGas += ett.estimateSourceGas;
|
|
635
|
+
result.estimateSourceGasUsd = ett.estimateSourceGasUsd;
|
|
636
|
+
if (result.needApprove) {
|
|
637
|
+
execTime.breakpoint();
|
|
638
|
+
const estApproveGas = await this.estimateApprove({
|
|
639
|
+
dry,
|
|
640
|
+
amountWei,
|
|
641
|
+
spender: result.approveSpender,
|
|
642
|
+
fromToken,
|
|
643
|
+
prices
|
|
644
|
+
});
|
|
645
|
+
result.estimateApproveGas = estApproveGas.estimateSourceGas;
|
|
646
|
+
execTime.log("estimateApprove");
|
|
647
|
+
}
|
|
648
|
+
for (const feeKey in result.fees) {
|
|
649
|
+
if (excludeFees.includes(feeKey) || !/Usd$/.test(feeKey)) {
|
|
650
|
+
continue;
|
|
651
|
+
}
|
|
652
|
+
result.totalFeesUsd = Big__default.default(result.totalFeesUsd || 0).plus(result.fees[feeKey] || 0);
|
|
653
|
+
}
|
|
654
|
+
result.totalFeesUsd = core.numberRemoveEndZero(Big__default.default(result.totalFeesUsd).toFixed(20));
|
|
655
|
+
result.sendParam.transactionParams = transactionParams;
|
|
656
|
+
execTime.log("quoteOFT");
|
|
657
|
+
return result;
|
|
658
|
+
}
|
|
659
|
+
async sendTransaction(params) {
|
|
660
|
+
const {
|
|
661
|
+
tx
|
|
662
|
+
} = params;
|
|
663
|
+
const transaction = tx?.transaction;
|
|
664
|
+
if (!transaction?.raw_data) {
|
|
665
|
+
throw new Error("Invalid transaction");
|
|
666
|
+
}
|
|
667
|
+
this.csl("Tron sendTransaction", "red-400", "transaction: %o", transaction);
|
|
668
|
+
const startTimestamp = Date.now();
|
|
669
|
+
const expirationDuration = 5 * 60 * 1e3;
|
|
670
|
+
const expiration = startTimestamp + expirationDuration;
|
|
671
|
+
let transactionWithExpiration = {
|
|
672
|
+
...transaction,
|
|
673
|
+
raw_data: {
|
|
674
|
+
...transaction.raw_data,
|
|
675
|
+
expiration
|
|
676
|
+
}
|
|
677
|
+
};
|
|
678
|
+
try {
|
|
679
|
+
await this.waitForTronWeb();
|
|
680
|
+
transactionWithExpiration = await this.tronWeb.transactionBuilder.newTxID(transactionWithExpiration, { txLocal: true });
|
|
681
|
+
} catch (error) {
|
|
682
|
+
console.warn("Failed to refresh transaction ID after extending expiration:", error);
|
|
683
|
+
}
|
|
684
|
+
this.csl("Tron sendTransaction", "red-400", "override transaction: %o", transactionWithExpiration);
|
|
685
|
+
const result = await this.signAndSendTransaction(transactionWithExpiration);
|
|
686
|
+
this.csl("Tron sendTransaction", "red-400", "Transaction sent with result: %o", result);
|
|
687
|
+
if (typeof result === "object") {
|
|
688
|
+
const code = result.code ? String(result.code) : "";
|
|
689
|
+
const message = result.message ? String(result.message) : "";
|
|
690
|
+
const combined = `${code} ${message}`.toUpperCase();
|
|
691
|
+
if (combined.includes("TRANSACTION_EXPIRATION_ERROR") || combined.includes("TRANSACTION_EXPIRED") || combined.includes("EXPIRED")) {
|
|
692
|
+
throw new Error("Transaction expired. Try again.");
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
this.csl("Tron sendTransaction", "red-400", "success: %o", result);
|
|
696
|
+
if (typeof result === "string") {
|
|
697
|
+
return result;
|
|
698
|
+
}
|
|
699
|
+
return result?.txid || result?.txID || transactionWithExpiration.txID;
|
|
700
|
+
}
|
|
701
|
+
/**
|
|
702
|
+
* Unified quote method that routes to specific quote methods based on type
|
|
703
|
+
* @param type Service type from Service
|
|
704
|
+
* @param params Parameters for the quote
|
|
705
|
+
*/
|
|
706
|
+
async quote(type, params) {
|
|
707
|
+
switch (type) {
|
|
708
|
+
case core.Service.Usdt0:
|
|
709
|
+
return await this.quoteOFT(params);
|
|
710
|
+
case core.Service.OneClick:
|
|
711
|
+
return await this.quoteOneClickProxy(params);
|
|
712
|
+
default:
|
|
713
|
+
throw new Error(`Unsupported quote type: ${type}`);
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
/**
|
|
717
|
+
* Unified send method that routes to specific send methods based on type
|
|
718
|
+
* @param type Send type from SendType enum
|
|
719
|
+
* @param params Parameters for the send transaction
|
|
720
|
+
*/
|
|
721
|
+
async send(type, params) {
|
|
722
|
+
switch (type) {
|
|
723
|
+
case core.SendType.SEND:
|
|
724
|
+
return await this.sendTransaction(params);
|
|
725
|
+
case core.SendType.TRANSFER:
|
|
726
|
+
return await this.transfer(params);
|
|
727
|
+
default:
|
|
728
|
+
throw new Error(`Unsupported send type: ${type}`);
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
async quoteOneClickProxy(params) {
|
|
732
|
+
const {
|
|
733
|
+
dry,
|
|
734
|
+
proxyAddress,
|
|
735
|
+
abi,
|
|
736
|
+
fromToken,
|
|
737
|
+
refundTo,
|
|
738
|
+
depositAddress,
|
|
739
|
+
amountWei,
|
|
740
|
+
prices
|
|
741
|
+
} = params;
|
|
742
|
+
const result = { fees: {} };
|
|
743
|
+
const execTime = new core.ExecTime({ type: "Oneclick Tron", logStyle: "indigo-400", isDebug: core.OpenAPI.DEBUG });
|
|
744
|
+
await this.waitForTronWeb();
|
|
745
|
+
execTime.log("waitForTronWeb");
|
|
746
|
+
const userAddress = refundTo || this.tronWeb.defaultAddress.base58;
|
|
747
|
+
execTime.breakpoint();
|
|
748
|
+
const allowance = await this.allowance({
|
|
749
|
+
dry,
|
|
750
|
+
contractAddress: fromToken.contractAddress,
|
|
751
|
+
address: userAddress,
|
|
752
|
+
spender: proxyAddress,
|
|
753
|
+
amountWei
|
|
754
|
+
});
|
|
755
|
+
result.needApprove = allowance.needApprove;
|
|
756
|
+
result.approveSpender = proxyAddress;
|
|
757
|
+
execTime.log("allowance");
|
|
758
|
+
const proxyParam = [
|
|
759
|
+
// tokenAddress
|
|
760
|
+
fromToken.contractAddress,
|
|
761
|
+
// recipient
|
|
762
|
+
depositAddress,
|
|
763
|
+
// amount
|
|
764
|
+
amountWei
|
|
765
|
+
];
|
|
766
|
+
result.sendParam = {
|
|
767
|
+
param: proxyParam
|
|
768
|
+
};
|
|
769
|
+
const transactionParams = [
|
|
770
|
+
proxyAddress,
|
|
771
|
+
"proxyTransfer(address,address,uint256)",
|
|
772
|
+
{},
|
|
773
|
+
[
|
|
774
|
+
{
|
|
775
|
+
type: "address",
|
|
776
|
+
value: result.sendParam.param[0]
|
|
777
|
+
// tokenAddress
|
|
778
|
+
},
|
|
779
|
+
{
|
|
780
|
+
type: "address",
|
|
781
|
+
value: result.sendParam.param[1]
|
|
782
|
+
// recipient
|
|
783
|
+
},
|
|
784
|
+
{
|
|
785
|
+
type: "uint256",
|
|
786
|
+
value: result.sendParam.param[2]
|
|
787
|
+
// amount
|
|
788
|
+
}
|
|
789
|
+
],
|
|
790
|
+
this.tronWeb.defaultAddress.base58 || refundTo
|
|
791
|
+
];
|
|
792
|
+
execTime.breakpoint();
|
|
793
|
+
const tx = await this.tronWeb.transactionBuilder.triggerSmartContract(...transactionParams);
|
|
794
|
+
execTime.log("transactionBuilder.triggerSmartContract");
|
|
795
|
+
result.sendParam.tx = tx;
|
|
796
|
+
execTime.breakpoint();
|
|
797
|
+
const ett = await this.estimateTransaction({
|
|
798
|
+
dry,
|
|
799
|
+
transactionParams,
|
|
800
|
+
fromToken,
|
|
801
|
+
prices,
|
|
802
|
+
defaultEnergyUsed: 2e5,
|
|
803
|
+
defaultRawDataHexLength: 500
|
|
804
|
+
});
|
|
805
|
+
execTime.log("estimateTransaction");
|
|
806
|
+
result.fees.estimateGasUsd = ett.estimateSourceGasUsd;
|
|
807
|
+
result.estimateSourceGas = ett.estimateSourceGas;
|
|
808
|
+
result.totalEstimateSourceGas = ett.estimateSourceGas;
|
|
809
|
+
result.estimateSourceGasUsd = ett.estimateSourceGasUsd;
|
|
810
|
+
if (result.needApprove) {
|
|
811
|
+
execTime.breakpoint();
|
|
812
|
+
const estApproveGas = await this.estimateApprove({
|
|
813
|
+
dry,
|
|
814
|
+
amountWei,
|
|
815
|
+
spender: result.approveSpender,
|
|
816
|
+
fromToken,
|
|
817
|
+
prices
|
|
818
|
+
});
|
|
819
|
+
result.estimateApproveGas = estApproveGas.estimateSourceGas;
|
|
820
|
+
execTime.log("estimateApprove");
|
|
821
|
+
}
|
|
822
|
+
result.sendParam.transactionParams = transactionParams;
|
|
823
|
+
execTime.logTotal("quoteOneClickPorxy");
|
|
824
|
+
return result;
|
|
825
|
+
}
|
|
826
|
+
async getAccountResources(params) {
|
|
827
|
+
const { account } = params;
|
|
828
|
+
const result = {
|
|
829
|
+
energy: 0,
|
|
830
|
+
bandwidth: 0,
|
|
831
|
+
success: false,
|
|
832
|
+
error: "TronWeb is not initialized or the wallet is not connected"
|
|
833
|
+
};
|
|
834
|
+
await this.waitForTronWeb();
|
|
835
|
+
if (!this.tronWeb || !account) {
|
|
836
|
+
return result;
|
|
837
|
+
}
|
|
838
|
+
try {
|
|
839
|
+
let availableEnergy;
|
|
840
|
+
let availableBandwidth;
|
|
841
|
+
try {
|
|
842
|
+
if (this.tronWeb.trx.getAccountResources) {
|
|
843
|
+
const resources = await this.tronWeb.trx.getAccountResources(account);
|
|
844
|
+
this.csl("TronWallet getAccountResources", "teal-400", "resources: %o", resources);
|
|
845
|
+
if (resources) {
|
|
846
|
+
availableEnergy = (resources.EnergyLimit || 0) - (resources.EnergyUsed || 0);
|
|
847
|
+
availableBandwidth = (resources.freeNetLimit || 0) - (resources.freeNetUsed || 0);
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
} catch (resourcesErr) {
|
|
851
|
+
console.warn("getAccountResources API is not available, try other way:", resourcesErr);
|
|
852
|
+
}
|
|
853
|
+
if (availableEnergy === void 0 && availableBandwidth === void 0) {
|
|
854
|
+
const accountInfo = await this.tronWeb.trx.getAccount(account);
|
|
855
|
+
if (accountInfo.account_resource) {
|
|
856
|
+
const accountResource = accountInfo.account_resource;
|
|
857
|
+
availableEnergy = (accountResource.EnergyLimit || 0) - (accountResource.EnergyUsed || 0);
|
|
858
|
+
availableBandwidth = (accountResource.NetLimit || 0) - (accountResource.NetUsed || 0);
|
|
859
|
+
} else if (accountInfo.energy !== void 0) {
|
|
860
|
+
availableEnergy = accountInfo.energy || 0;
|
|
861
|
+
}
|
|
862
|
+
if (accountInfo.bandwidth !== void 0) {
|
|
863
|
+
if (typeof accountInfo.bandwidth === "number") {
|
|
864
|
+
availableBandwidth = accountInfo.bandwidth;
|
|
865
|
+
} else if (accountInfo.bandwidth) {
|
|
866
|
+
availableBandwidth = accountInfo.bandwidth.available || accountInfo.bandwidth.freeNetUsage || 0;
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
result.energy = Math.max(0, availableEnergy);
|
|
871
|
+
result.bandwidth = Math.max(0, availableBandwidth);
|
|
872
|
+
result.success = true;
|
|
873
|
+
result.error = null;
|
|
874
|
+
} catch (error) {
|
|
875
|
+
console.error("Failed to get account resources:", error);
|
|
876
|
+
}
|
|
877
|
+
return result;
|
|
878
|
+
}
|
|
879
|
+
};
|
|
880
|
+
|
|
881
|
+
exports.TronWallet = TronWallet;
|
|
882
|
+
exports.default = TronWallet;
|
|
883
|
+
//# sourceMappingURL=index.js.map
|
|
884
|
+
//# sourceMappingURL=index.js.map
|