@swapkit/toolboxes 4.0.0-beta.50 → 4.0.0-beta.52
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/src/cosmos/index.cjs +2 -2
- package/dist/src/cosmos/index.cjs.map +10 -6
- package/dist/src/cosmos/index.js +2 -2
- package/dist/src/cosmos/index.js.map +10 -6
- package/dist/src/evm/index.cjs +2 -2
- package/dist/src/evm/index.cjs.map +10 -8
- package/dist/src/evm/index.js +2 -2
- package/dist/src/evm/index.js.map +10 -8
- package/dist/src/index.cjs +4 -2
- package/dist/src/index.cjs.map +54 -4
- package/dist/src/index.js +4 -2
- package/dist/src/index.js.map +54 -4
- package/dist/src/near/index.cjs +2 -2
- package/dist/src/near/index.cjs.map +7 -5
- package/dist/src/near/index.js +2 -2
- package/dist/src/near/index.js.map +7 -5
- package/dist/src/radix/index.cjs +2 -2
- package/dist/src/radix/index.cjs.map +2 -2
- package/dist/src/radix/index.js +2 -2
- package/dist/src/radix/index.js.map +2 -2
- package/dist/src/ripple/index.cjs +2 -2
- package/dist/src/ripple/index.cjs.map +2 -2
- package/dist/src/ripple/index.js +2 -2
- package/dist/src/ripple/index.js.map +2 -2
- package/dist/src/solana/index.cjs +2 -2
- package/dist/src/solana/index.cjs.map +5 -4
- package/dist/src/solana/index.js +2 -2
- package/dist/src/solana/index.js.map +5 -4
- package/dist/src/substrate/index.cjs +2 -2
- package/dist/src/substrate/index.cjs.map +6 -5
- package/dist/src/substrate/index.js +2 -2
- package/dist/src/substrate/index.js.map +6 -5
- package/dist/src/tron/index.cjs +2 -2
- package/dist/src/tron/index.cjs.map +6 -5
- package/dist/src/tron/index.js +2 -2
- package/dist/src/tron/index.js.map +6 -5
- package/dist/src/utxo/index.cjs +4 -4
- package/dist/src/utxo/index.cjs.map +10 -7
- package/dist/src/utxo/index.js +4 -4
- package/dist/src/utxo/index.js.map +10 -7
- package/{src/cosmos/index.ts → dist/types/cosmos/index.d.ts} +1 -0
- package/dist/types/cosmos/index.d.ts.map +1 -0
- package/dist/types/cosmos/thorchainUtils/addressFormat.d.ts +5 -0
- package/dist/types/cosmos/thorchainUtils/addressFormat.d.ts.map +1 -0
- package/{src/cosmos/thorchainUtils/index.ts → dist/types/cosmos/thorchainUtils/index.d.ts} +1 -0
- package/dist/types/cosmos/thorchainUtils/index.d.ts.map +1 -0
- package/dist/types/cosmos/thorchainUtils/messages.d.ts +208 -0
- package/dist/types/cosmos/thorchainUtils/messages.d.ts.map +1 -0
- package/dist/types/cosmos/thorchainUtils/registry.d.ts +4 -0
- package/dist/types/cosmos/thorchainUtils/registry.d.ts.map +1 -0
- package/dist/types/cosmos/thorchainUtils/types/MsgCompiled.d.ts +2 -0
- package/dist/types/cosmos/thorchainUtils/types/MsgCompiled.d.ts.map +1 -0
- package/dist/types/cosmos/thorchainUtils/types/client-types.d.ts +66 -0
- package/dist/types/cosmos/thorchainUtils/types/client-types.d.ts.map +1 -0
- package/dist/types/cosmos/thorchainUtils/types/index.d.ts +2 -0
- package/dist/types/cosmos/thorchainUtils/types/index.d.ts.map +1 -0
- package/dist/types/cosmos/toolbox/cosmos.d.ts +93 -0
- package/dist/types/cosmos/toolbox/cosmos.d.ts.map +1 -0
- package/dist/types/cosmos/toolbox/index.d.ts +14 -0
- package/dist/types/cosmos/toolbox/index.d.ts.map +1 -0
- package/dist/types/cosmos/toolbox/thorchain.d.ts +158 -0
- package/dist/types/cosmos/toolbox/thorchain.d.ts.map +1 -0
- package/{src/cosmos/types.ts → dist/types/cosmos/types.d.ts} +24 -29
- package/dist/types/cosmos/types.d.ts.map +1 -0
- package/dist/types/cosmos/util.d.ts +68 -0
- package/dist/types/cosmos/util.d.ts.map +1 -0
- package/dist/types/evm/api.d.ts +8 -0
- package/dist/types/evm/api.d.ts.map +1 -0
- package/dist/types/evm/contracts/eth/multicall.d.ts +36 -0
- package/dist/types/evm/contracts/eth/multicall.d.ts.map +1 -0
- package/dist/types/evm/contracts/op/gasOracle.d.ts +40 -0
- package/dist/types/evm/contracts/op/gasOracle.d.ts.map +1 -0
- package/dist/types/evm/helpers.d.ts +20 -0
- package/dist/types/evm/helpers.d.ts.map +1 -0
- package/{src/evm/index.ts → dist/types/evm/index.d.ts} +1 -0
- package/dist/types/evm/index.d.ts.map +1 -0
- package/dist/types/evm/toolbox/baseEVMToolbox.d.ts +82 -0
- package/dist/types/evm/toolbox/baseEVMToolbox.d.ts.map +1 -0
- package/dist/types/evm/toolbox/evm.d.ts +367 -0
- package/dist/types/evm/toolbox/evm.d.ts.map +1 -0
- package/dist/types/evm/toolbox/index.d.ts +89 -0
- package/dist/types/evm/toolbox/index.d.ts.map +1 -0
- package/dist/types/evm/toolbox/op.d.ts +62 -0
- package/dist/types/evm/toolbox/op.d.ts.map +1 -0
- package/dist/types/evm/types.d.ts +98 -0
- package/dist/types/evm/types.d.ts.map +1 -0
- package/dist/types/index.d.ts +63 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/near/helpers/core.d.ts +15 -0
- package/dist/types/near/helpers/core.d.ts.map +1 -0
- package/dist/types/near/helpers/gasEstimation.d.ts +41 -0
- package/dist/types/near/helpers/gasEstimation.d.ts.map +1 -0
- package/dist/types/near/helpers/nep141.d.ts +72 -0
- package/dist/types/near/helpers/nep141.d.ts.map +1 -0
- package/dist/types/near/index.d.ts +10 -0
- package/dist/types/near/index.d.ts.map +1 -0
- package/dist/types/near/toolbox.d.ts +4 -0
- package/dist/types/near/toolbox.d.ts.map +1 -0
- package/dist/types/near/types/contract.d.ts +38 -0
- package/dist/types/near/types/contract.d.ts.map +1 -0
- package/dist/types/near/types/nep141.d.ts +56 -0
- package/dist/types/near/types/nep141.d.ts.map +1 -0
- package/dist/types/near/types/toolbox.d.ts +57 -0
- package/dist/types/near/types/toolbox.d.ts.map +1 -0
- package/dist/types/near/types.d.ts +44 -0
- package/dist/types/near/types.d.ts.map +1 -0
- package/dist/types/radix/index.d.ts +14 -0
- package/dist/types/radix/index.d.ts.map +1 -0
- package/dist/types/ripple/index.d.ts +43 -0
- package/dist/types/ripple/index.d.ts.map +1 -0
- package/dist/types/solana/index.d.ts +37 -0
- package/dist/types/solana/index.d.ts.map +1 -0
- package/dist/types/solana/toolbox.d.ts +41 -0
- package/dist/types/solana/toolbox.d.ts.map +1 -0
- package/dist/types/substrate/balance.d.ts +17 -0
- package/dist/types/substrate/balance.d.ts.map +1 -0
- package/{src/substrate/index.ts → dist/types/substrate/index.d.ts} +1 -0
- package/dist/types/substrate/index.d.ts.map +1 -0
- package/dist/types/substrate/substrate.d.ts +148 -0
- package/dist/types/substrate/substrate.d.ts.map +1 -0
- package/dist/types/substrate/types.d.ts +100 -0
- package/dist/types/substrate/types.d.ts.map +1 -0
- package/dist/types/tron/helpers/trc20.abi.d.ts +156 -0
- package/dist/types/tron/helpers/trc20.abi.d.ts.map +1 -0
- package/dist/types/tron/helpers/trongrid.d.ts +8 -0
- package/dist/types/tron/helpers/trongrid.d.ts.map +1 -0
- package/dist/types/tron/index.d.ts +6 -0
- package/dist/types/tron/index.d.ts.map +1 -0
- package/dist/types/tron/toolbox.d.ts +26 -0
- package/dist/types/tron/toolbox.d.ts.map +1 -0
- package/dist/types/tron/types.d.ts +101 -0
- package/dist/types/tron/types.d.ts.map +1 -0
- package/dist/types/types.d.ts +18 -0
- package/dist/types/types.d.ts.map +1 -0
- package/dist/types/utils.d.ts +4 -0
- package/dist/types/utils.d.ts.map +1 -0
- package/dist/types/utxo/helpers/api.d.ts +133 -0
- package/dist/types/utxo/helpers/api.d.ts.map +1 -0
- package/dist/types/utxo/helpers/bchaddrjs.d.ts +10 -0
- package/dist/types/utxo/helpers/bchaddrjs.d.ts.map +1 -0
- package/dist/types/utxo/helpers/coinselect.d.ts +16 -0
- package/dist/types/utxo/helpers/coinselect.d.ts.map +1 -0
- package/{src/utxo/helpers/index.ts → dist/types/utxo/helpers/index.d.ts} +1 -0
- package/dist/types/utxo/helpers/index.d.ts.map +1 -0
- package/dist/types/utxo/helpers/txSize.d.ts +21 -0
- package/dist/types/utxo/helpers/txSize.d.ts.map +1 -0
- package/{src/utxo/index.ts → dist/types/utxo/index.d.ts} +1 -0
- package/dist/types/utxo/index.d.ts.map +1 -0
- package/dist/types/utxo/toolbox/bitcoinCash.d.ts +104 -0
- package/dist/types/utxo/toolbox/bitcoinCash.d.ts.map +1 -0
- package/dist/types/utxo/toolbox/index.d.ts +50 -0
- package/dist/types/utxo/toolbox/index.d.ts.map +1 -0
- package/dist/types/utxo/toolbox/utxo.d.ts +102 -0
- package/dist/types/utxo/toolbox/utxo.d.ts.map +1 -0
- package/dist/types/utxo/toolbox/zcash.d.ts +83 -0
- package/dist/types/utxo/toolbox/zcash.d.ts.map +1 -0
- package/dist/types/utxo/types.d.ts +46 -0
- package/dist/types/utxo/types.d.ts.map +1 -0
- package/package.json +15 -18
- package/dist/chunk-0h4xdrwz.js +0 -5
- package/dist/chunk-0h4xdrwz.js.map +0 -10
- package/dist/chunk-4yap1fvd.js +0 -4
- package/dist/chunk-4yap1fvd.js.map +0 -10
- package/dist/chunk-9bqegm61.js +0 -4
- package/dist/chunk-9bqegm61.js.map +0 -10
- package/dist/chunk-fazw0jvt.js +0 -4
- package/dist/chunk-fazw0jvt.js.map +0 -9
- package/dist/chunk-fjfxga2v.js +0 -4
- package/dist/chunk-fjfxga2v.js.map +0 -10
- package/dist/chunk-s47y8512.js +0 -5
- package/dist/chunk-s47y8512.js.map +0 -9
- package/dist/chunk-vtd17cje.js +0 -4
- package/dist/chunk-vtd17cje.js.map +0 -10
- package/dist/chunk-zcdeg6h9.js +0 -5
- package/dist/chunk-zcdeg6h9.js.map +0 -10
- package/src/cosmos/thorchainUtils/addressFormat.ts +0 -26
- package/src/cosmos/thorchainUtils/messages.ts +0 -262
- package/src/cosmos/thorchainUtils/registry.ts +0 -44
- package/src/cosmos/thorchainUtils/types/MsgCompiled.ts +0 -2800
- package/src/cosmos/thorchainUtils/types/client-types.ts +0 -73
- package/src/cosmos/thorchainUtils/types/index.ts +0 -1
- package/src/cosmos/toolbox/cosmos.ts +0 -375
- package/src/cosmos/toolbox/index.ts +0 -33
- package/src/cosmos/toolbox/thorchain.ts +0 -313
- package/src/cosmos/util.ts +0 -266
- package/src/evm/__tests__/address-validation.test.ts +0 -86
- package/src/evm/__tests__/ethereum.test.ts +0 -141
- package/src/evm/api.ts +0 -21
- package/src/evm/contracts/eth/multicall.ts +0 -165
- package/src/evm/contracts/op/gasOracle.ts +0 -151
- package/src/evm/helpers.ts +0 -194
- package/src/evm/toolbox/baseEVMToolbox.ts +0 -762
- package/src/evm/toolbox/evm.ts +0 -66
- package/src/evm/toolbox/index.ts +0 -52
- package/src/evm/toolbox/op.ts +0 -131
- package/src/evm/types.ts +0 -146
- package/src/index.ts +0 -263
- package/src/near/__tests__/core.test.ts +0 -80
- package/src/near/helpers/contractFactory.ts +0 -22
- package/src/near/helpers/core.ts +0 -91
- package/src/near/helpers/gasEstimation.ts +0 -110
- package/src/near/helpers/index.ts +0 -5
- package/src/near/helpers/nep141.ts +0 -110
- package/src/near/index.ts +0 -24
- package/src/near/toolbox.ts +0 -509
- package/src/near/types/contract.ts +0 -48
- package/src/near/types/nep141.ts +0 -66
- package/src/near/types.ts +0 -57
- package/src/radix/index.ts +0 -156
- package/src/ripple/index.ts +0 -192
- package/src/solana/index.ts +0 -55
- package/src/solana/toolbox.ts +0 -433
- package/src/substrate/balance.ts +0 -92
- package/src/substrate/substrate.ts +0 -320
- package/src/substrate/types.ts +0 -120
- package/src/tron/__tests__/toolbox.test.ts +0 -147
- package/src/tron/helpers/trc20.abi.ts +0 -107
- package/src/tron/helpers/trongrid.ts +0 -54
- package/src/tron/index.ts +0 -17
- package/src/tron/toolbox.ts +0 -650
- package/src/tron/types.ts +0 -120
- package/src/utils.ts +0 -27
- package/src/utxo/__tests__/zcash-integration.test.ts +0 -114
- package/src/utxo/helpers/api.ts +0 -560
- package/src/utxo/helpers/bchaddrjs.ts +0 -183
- package/src/utxo/helpers/coinselect.ts +0 -98
- package/src/utxo/helpers/txSize.ts +0 -104
- package/src/utxo/toolbox/bitcoinCash.ts +0 -320
- package/src/utxo/toolbox/index.ts +0 -90
- package/src/utxo/toolbox/utxo.ts +0 -525
- package/src/utxo/toolbox/zcash.ts +0 -208
- package/src/utxo/types.ts +0 -57
package/src/tron/toolbox.ts
DELETED
|
@@ -1,650 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
AssetValue,
|
|
3
|
-
Chain,
|
|
4
|
-
NetworkDerivationPath,
|
|
5
|
-
SKConfig,
|
|
6
|
-
SwapKitError,
|
|
7
|
-
derivationPathToString,
|
|
8
|
-
updateDerivationPath,
|
|
9
|
-
warnOnce,
|
|
10
|
-
} from "@swapkit/helpers";
|
|
11
|
-
import { P, match } from "ts-pattern";
|
|
12
|
-
|
|
13
|
-
import { trc20ABI } from "./helpers/trc20.abi.js";
|
|
14
|
-
import { fetchAccountFromTronGrid } from "./helpers/trongrid.js";
|
|
15
|
-
import type {
|
|
16
|
-
ApproveParams,
|
|
17
|
-
ApprovedParams,
|
|
18
|
-
IsApprovedParams,
|
|
19
|
-
TronCreateTransactionParams,
|
|
20
|
-
TronSignedTransaction,
|
|
21
|
-
TronSigner,
|
|
22
|
-
TronToolboxOptions,
|
|
23
|
-
TronTransaction,
|
|
24
|
-
TronTransferParams,
|
|
25
|
-
} from "./types.js";
|
|
26
|
-
|
|
27
|
-
import { TronWeb } from "tronweb";
|
|
28
|
-
|
|
29
|
-
// Constants for TRON resource calculation
|
|
30
|
-
const TRX_TRANSFER_BANDWIDTH = 268; // Bandwidth consumed by a TRX transfer
|
|
31
|
-
const TRC20_TRANSFER_ENERGY = 13000; // Average energy consumed by TRC20 transfer
|
|
32
|
-
const TRC20_TRANSFER_BANDWIDTH = 345; // Bandwidth consumed by TRC20 transfer
|
|
33
|
-
|
|
34
|
-
// Known TRON tokens
|
|
35
|
-
const TRON_USDT_CONTRACT = "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t";
|
|
36
|
-
|
|
37
|
-
const MAX_APPROVAL = "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
|
|
38
|
-
|
|
39
|
-
export async function getTronAddressValidator() {
|
|
40
|
-
return (address: string) => {
|
|
41
|
-
return TronWeb.isAddress(address);
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export async function getTronPrivateKeyFromMnemonic({
|
|
46
|
-
phrase,
|
|
47
|
-
derivationPath: customPath,
|
|
48
|
-
index,
|
|
49
|
-
}: {
|
|
50
|
-
phrase: string;
|
|
51
|
-
derivationPath?: string;
|
|
52
|
-
index?: number;
|
|
53
|
-
}) {
|
|
54
|
-
const derivationPathToUse =
|
|
55
|
-
customPath ||
|
|
56
|
-
derivationPathToString(
|
|
57
|
-
updateDerivationPath(NetworkDerivationPath[Chain.Tron], {
|
|
58
|
-
index: index || 0,
|
|
59
|
-
}),
|
|
60
|
-
);
|
|
61
|
-
|
|
62
|
-
const { HDKey } = await import("@scure/bip32");
|
|
63
|
-
const { mnemonicToSeedSync } = await import("@scure/bip39");
|
|
64
|
-
|
|
65
|
-
const seed = mnemonicToSeedSync(phrase);
|
|
66
|
-
const hdKey = HDKey.fromMasterSeed(seed);
|
|
67
|
-
const derived = hdKey.derive(derivationPathToUse);
|
|
68
|
-
|
|
69
|
-
if (!derived.privateKey) {
|
|
70
|
-
throw new SwapKitError("toolbox_tron_no_signer");
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
return Buffer.from(derived.privateKey).toString("hex");
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
async function createKeysForPath({
|
|
77
|
-
phrase,
|
|
78
|
-
derivationPath,
|
|
79
|
-
tronWeb,
|
|
80
|
-
}: {
|
|
81
|
-
phrase: string;
|
|
82
|
-
derivationPath: string;
|
|
83
|
-
tronWeb: TronWeb;
|
|
84
|
-
}) {
|
|
85
|
-
const { HDKey } = await import("@scure/bip32");
|
|
86
|
-
const { mnemonicToSeedSync } = await import("@scure/bip39");
|
|
87
|
-
|
|
88
|
-
const seed = mnemonicToSeedSync(phrase);
|
|
89
|
-
const hdKey = HDKey.fromMasterSeed(seed);
|
|
90
|
-
const derived = hdKey.derive(derivationPath);
|
|
91
|
-
|
|
92
|
-
if (!derived.privateKey) {
|
|
93
|
-
throw new SwapKitError("toolbox_tron_no_signer");
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// Convert private key to hex string for TronWeb
|
|
97
|
-
const privateKeyHex = Buffer.from(derived.privateKey).toString("hex");
|
|
98
|
-
|
|
99
|
-
tronWeb.setPrivateKey(privateKeyHex);
|
|
100
|
-
|
|
101
|
-
const address = tronWeb?.address.fromPrivateKey(privateKeyHex);
|
|
102
|
-
|
|
103
|
-
return {
|
|
104
|
-
getAddress: () => Promise.resolve(typeof address === "string" ? address : ""),
|
|
105
|
-
signTransaction: async (transaction: TronTransaction) => {
|
|
106
|
-
const signedTx = await tronWeb.trx.sign(transaction, privateKeyHex);
|
|
107
|
-
return signedTx;
|
|
108
|
-
},
|
|
109
|
-
};
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
export const createTronToolbox = async (options: TronToolboxOptions = {}) => {
|
|
113
|
-
// Always get configuration from SKConfig
|
|
114
|
-
const rpcUrl = SKConfig.get("rpcUrls")[Chain.Tron];
|
|
115
|
-
// Note: TRON API key support can be added to SKConfig apiKeys when needed
|
|
116
|
-
const headers = undefined; // No API key needed for basic TronGrid access
|
|
117
|
-
|
|
118
|
-
const tronWeb = new TronWeb({
|
|
119
|
-
fullHost: rpcUrl,
|
|
120
|
-
headers,
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
// Handle derivation path and index
|
|
124
|
-
const index = "index" in options ? options.index || 0 : 0;
|
|
125
|
-
const derivationPath = derivationPathToString(
|
|
126
|
-
"derivationPath" in options && options.derivationPath
|
|
127
|
-
? options.derivationPath
|
|
128
|
-
: updateDerivationPath(NetworkDerivationPath[Chain.Tron], { index }),
|
|
129
|
-
);
|
|
130
|
-
|
|
131
|
-
// Create signer based on options using pattern matching
|
|
132
|
-
const signer: TronSigner | undefined = await match(options)
|
|
133
|
-
.with({ phrase: P.string }, async ({ phrase }) =>
|
|
134
|
-
createKeysForPath({ phrase, derivationPath, tronWeb }),
|
|
135
|
-
)
|
|
136
|
-
.with({ signer: P.any }, ({ signer }) => Promise.resolve(signer as TronSigner))
|
|
137
|
-
.otherwise(() => Promise.resolve(undefined));
|
|
138
|
-
|
|
139
|
-
const getAddress = async () => {
|
|
140
|
-
if (!signer) throw new SwapKitError("toolbox_tron_no_signer");
|
|
141
|
-
return await signer.getAddress();
|
|
142
|
-
};
|
|
143
|
-
|
|
144
|
-
const calculateFeeLimit = () => {
|
|
145
|
-
return 100_000_000; // 100 TRX in SUN
|
|
146
|
-
};
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* Get current chain parameters including resource prices
|
|
150
|
-
*/
|
|
151
|
-
const getChainParameters = async () => {
|
|
152
|
-
try {
|
|
153
|
-
const parameters = await tronWeb.trx.getChainParameters();
|
|
154
|
-
const paramMap: Record<string, number> = {};
|
|
155
|
-
|
|
156
|
-
for (const param of parameters) {
|
|
157
|
-
paramMap[param.key] = param.value;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
return {
|
|
161
|
-
energyFee: paramMap.getEnergyFee || 420, // SUN per energy unit
|
|
162
|
-
bandwidthFee: paramMap.getTransactionFee || 1000, // SUN per bandwidth unit
|
|
163
|
-
createAccountFee: paramMap.getCreateAccountFee || 100000, // 0.1 TRX in SUN
|
|
164
|
-
};
|
|
165
|
-
} catch {
|
|
166
|
-
// Return default values if unable to fetch
|
|
167
|
-
return {
|
|
168
|
-
energyFee: 420,
|
|
169
|
-
bandwidthFee: 1000,
|
|
170
|
-
createAccountFee: 100000,
|
|
171
|
-
};
|
|
172
|
-
}
|
|
173
|
-
};
|
|
174
|
-
|
|
175
|
-
/**
|
|
176
|
-
* Check if an address exists on the blockchain
|
|
177
|
-
*/
|
|
178
|
-
const accountExists = async (address: string) => {
|
|
179
|
-
try {
|
|
180
|
-
const account = await tronWeb.trx.getAccount(address);
|
|
181
|
-
return account && Object.keys(account).length > 0;
|
|
182
|
-
} catch {
|
|
183
|
-
return false;
|
|
184
|
-
}
|
|
185
|
-
};
|
|
186
|
-
|
|
187
|
-
/**
|
|
188
|
-
* Get account resources (bandwidth and energy)
|
|
189
|
-
*/
|
|
190
|
-
const getAccountResources = async (address: string) => {
|
|
191
|
-
try {
|
|
192
|
-
const resources = await tronWeb.trx.getAccountResources(address);
|
|
193
|
-
|
|
194
|
-
return {
|
|
195
|
-
bandwidth: {
|
|
196
|
-
free: resources.freeNetLimit - resources.freeNetUsed,
|
|
197
|
-
total: resources.NetLimit || 0,
|
|
198
|
-
used: resources.NetUsed || 0,
|
|
199
|
-
},
|
|
200
|
-
energy: {
|
|
201
|
-
total: resources.EnergyLimit || 0,
|
|
202
|
-
used: resources.EnergyUsed || 0,
|
|
203
|
-
},
|
|
204
|
-
};
|
|
205
|
-
} catch {
|
|
206
|
-
// Return default structure if unable to fetch
|
|
207
|
-
return {
|
|
208
|
-
bandwidth: { free: 600, total: 0, used: 0 }, // 600 free bandwidth daily
|
|
209
|
-
energy: { total: 0, used: 0 },
|
|
210
|
-
};
|
|
211
|
-
}
|
|
212
|
-
};
|
|
213
|
-
|
|
214
|
-
/**
|
|
215
|
-
* Get token balance and info directly from contract
|
|
216
|
-
*/
|
|
217
|
-
const fetchTokenBalance = async (address: string, contractAddress: string) => {
|
|
218
|
-
try {
|
|
219
|
-
const contract = tronWeb.contract(trc20ABI, contractAddress);
|
|
220
|
-
|
|
221
|
-
if (!contract.methods?.balanceOf) {
|
|
222
|
-
return 0n;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
const balance = (await contract.methods.balanceOf(address).call())[0] as string;
|
|
226
|
-
|
|
227
|
-
return BigInt(balance || 0); // Convert to BigInt for consistency
|
|
228
|
-
} catch (err) {
|
|
229
|
-
console.warn(`balanceOf() failed for ${contractAddress}:`, err);
|
|
230
|
-
return 0n;
|
|
231
|
-
}
|
|
232
|
-
};
|
|
233
|
-
|
|
234
|
-
/**
|
|
235
|
-
* Get token balance and info directly from contract
|
|
236
|
-
*/
|
|
237
|
-
const fetchTokenMetadata = async (contractAddress: string, address: string) => {
|
|
238
|
-
try {
|
|
239
|
-
tronWeb.setAddress(address); // Set address for contract calls
|
|
240
|
-
const contract = tronWeb.contract(trc20ABI, contractAddress);
|
|
241
|
-
|
|
242
|
-
const [symbolRaw, decimalsRaw] = await Promise.all([
|
|
243
|
-
contract
|
|
244
|
-
.symbol()
|
|
245
|
-
.call()
|
|
246
|
-
.catch(() => "UNKNOWN"),
|
|
247
|
-
contract
|
|
248
|
-
.decimals()
|
|
249
|
-
.call()
|
|
250
|
-
.catch(() => "18"),
|
|
251
|
-
]);
|
|
252
|
-
|
|
253
|
-
return {
|
|
254
|
-
symbol: symbolRaw ?? "UNKNOWN",
|
|
255
|
-
decimals: Number(decimalsRaw ?? 18),
|
|
256
|
-
};
|
|
257
|
-
} catch (error) {
|
|
258
|
-
warnOnce(
|
|
259
|
-
true,
|
|
260
|
-
`Failed to get token balance for ${contractAddress}: ${error instanceof Error ? error.message : error}`,
|
|
261
|
-
);
|
|
262
|
-
return null;
|
|
263
|
-
}
|
|
264
|
-
};
|
|
265
|
-
|
|
266
|
-
// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: <explanation>
|
|
267
|
-
const getBalance = async (address: string, _scamFilter = true) => {
|
|
268
|
-
const fallbackBalance = [
|
|
269
|
-
AssetValue.from({
|
|
270
|
-
chain: Chain.Tron,
|
|
271
|
-
}),
|
|
272
|
-
];
|
|
273
|
-
// Try primary source (TronGrid)
|
|
274
|
-
try {
|
|
275
|
-
const accountData = await fetchAccountFromTronGrid(address);
|
|
276
|
-
if (accountData) {
|
|
277
|
-
const balances: AssetValue[] = [];
|
|
278
|
-
|
|
279
|
-
// Add TRX balance
|
|
280
|
-
balances.push(
|
|
281
|
-
AssetValue.from({
|
|
282
|
-
chain: Chain.Tron,
|
|
283
|
-
value: accountData.balance,
|
|
284
|
-
fromBaseDecimal: 6,
|
|
285
|
-
}),
|
|
286
|
-
);
|
|
287
|
-
|
|
288
|
-
// Add TRC20 balances
|
|
289
|
-
|
|
290
|
-
for (const token of accountData.trc20) {
|
|
291
|
-
const [contractAddress, balance] = Object.entries(token)[0] || [];
|
|
292
|
-
|
|
293
|
-
if (!(contractAddress && balance)) continue;
|
|
294
|
-
|
|
295
|
-
const tokenMetaData = await fetchTokenMetadata(contractAddress, address);
|
|
296
|
-
|
|
297
|
-
if (!tokenMetaData) continue;
|
|
298
|
-
|
|
299
|
-
balances.push(
|
|
300
|
-
AssetValue.from({
|
|
301
|
-
asset: `TRX.${tokenMetaData.symbol}-${contractAddress}`,
|
|
302
|
-
value: BigInt(balance || 0),
|
|
303
|
-
fromBaseDecimal: tokenMetaData.decimals,
|
|
304
|
-
}),
|
|
305
|
-
);
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
return balances;
|
|
309
|
-
}
|
|
310
|
-
return fallbackBalance;
|
|
311
|
-
} catch (error) {
|
|
312
|
-
warnOnce(
|
|
313
|
-
true,
|
|
314
|
-
`Tron API getBalance failed: ${error instanceof Error ? error.message : error}`,
|
|
315
|
-
);
|
|
316
|
-
|
|
317
|
-
// Fallback: get TRX and USDT directly
|
|
318
|
-
const balances: AssetValue[] = [];
|
|
319
|
-
|
|
320
|
-
const trxBalanceInSun = await tronWeb.trx.getBalance(address);
|
|
321
|
-
if (trxBalanceInSun && Number(trxBalanceInSun) > 0) {
|
|
322
|
-
balances.push(
|
|
323
|
-
AssetValue.from({
|
|
324
|
-
chain: Chain.Tron,
|
|
325
|
-
value: trxBalanceInSun,
|
|
326
|
-
fromBaseDecimal: 6,
|
|
327
|
-
}),
|
|
328
|
-
);
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
const usdtBalance = await fetchTokenBalance(address, TRON_USDT_CONTRACT);
|
|
332
|
-
if (usdtBalance) {
|
|
333
|
-
balances.push(
|
|
334
|
-
AssetValue.from({
|
|
335
|
-
asset: `TRX.USDT-${TRON_USDT_CONTRACT}`,
|
|
336
|
-
value: usdtBalance,
|
|
337
|
-
fromBaseDecimal: 6,
|
|
338
|
-
}),
|
|
339
|
-
);
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
return balances;
|
|
343
|
-
}
|
|
344
|
-
};
|
|
345
|
-
|
|
346
|
-
const transfer = async ({ recipient, assetValue, memo }: TronTransferParams) => {
|
|
347
|
-
if (!signer) throw new SwapKitError("toolbox_tron_no_signer");
|
|
348
|
-
|
|
349
|
-
const from = await getAddress();
|
|
350
|
-
tronWeb.setAddress(from);
|
|
351
|
-
const isNative = assetValue.isGasAsset;
|
|
352
|
-
|
|
353
|
-
if (isNative) {
|
|
354
|
-
// Native TRX Transfer (amount in SUN - base units)
|
|
355
|
-
const transaction = await tronWeb.transactionBuilder.sendTrx(
|
|
356
|
-
recipient,
|
|
357
|
-
assetValue.getBaseValue("number"),
|
|
358
|
-
from,
|
|
359
|
-
);
|
|
360
|
-
|
|
361
|
-
// Add memo if provided
|
|
362
|
-
if (memo) {
|
|
363
|
-
const transactionWithMemo = await tronWeb.transactionBuilder.addUpdateData(
|
|
364
|
-
transaction,
|
|
365
|
-
memo,
|
|
366
|
-
"utf8",
|
|
367
|
-
);
|
|
368
|
-
const signedTx = await signer.signTransaction(transactionWithMemo);
|
|
369
|
-
const { txid } = await tronWeb.trx.sendRawTransaction(signedTx);
|
|
370
|
-
return txid;
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
const signedTx = await signer.signTransaction(transaction);
|
|
374
|
-
const { txid } = await tronWeb.trx.sendRawTransaction(signedTx);
|
|
375
|
-
return txid;
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
// TRC20 Token Transfer - always use createTransaction + sign pattern
|
|
379
|
-
const transaction = await createTransaction({
|
|
380
|
-
recipient,
|
|
381
|
-
assetValue,
|
|
382
|
-
memo,
|
|
383
|
-
sender: from,
|
|
384
|
-
});
|
|
385
|
-
|
|
386
|
-
const signedTx = await signer.signTransaction(transaction);
|
|
387
|
-
const { txid } = await tronWeb.trx.sendRawTransaction(signedTx);
|
|
388
|
-
|
|
389
|
-
if (!txid) {
|
|
390
|
-
throw new SwapKitError("toolbox_tron_token_transfer_failed");
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
return txid;
|
|
394
|
-
};
|
|
395
|
-
|
|
396
|
-
const estimateTransactionFee = async ({
|
|
397
|
-
assetValue,
|
|
398
|
-
recipient,
|
|
399
|
-
sender,
|
|
400
|
-
// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: <explanation>
|
|
401
|
-
}: TronTransferParams & { sender?: string }) => {
|
|
402
|
-
const isNative = assetValue.isGasAsset;
|
|
403
|
-
|
|
404
|
-
try {
|
|
405
|
-
// Get sender address
|
|
406
|
-
const senderAddress = sender ? sender : signer ? await getAddress() : undefined;
|
|
407
|
-
if (!senderAddress) {
|
|
408
|
-
// If no signer, return conservative estimate
|
|
409
|
-
return isNative
|
|
410
|
-
? AssetValue.from({ chain: Chain.Tron, value: 0.1, fromBaseDecimal: 0 })
|
|
411
|
-
: AssetValue.from({ chain: Chain.Tron, value: 15, fromBaseDecimal: 0 });
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
// Get chain parameters for current resource prices
|
|
415
|
-
const chainParams = await getChainParameters();
|
|
416
|
-
|
|
417
|
-
// Check if recipient account exists (new accounts require activation fee)
|
|
418
|
-
const recipientExists = await accountExists(recipient);
|
|
419
|
-
const activationFee = recipientExists ? 0 : chainParams.createAccountFee;
|
|
420
|
-
|
|
421
|
-
// Get account resources
|
|
422
|
-
const resources = await getAccountResources(senderAddress);
|
|
423
|
-
|
|
424
|
-
if (isNative) {
|
|
425
|
-
// Calculate bandwidth needed for TRX transfer
|
|
426
|
-
const bandwidthNeeded = TRX_TRANSFER_BANDWIDTH;
|
|
427
|
-
const availableBandwidth =
|
|
428
|
-
resources.bandwidth.free + (resources.bandwidth.total - resources.bandwidth.used);
|
|
429
|
-
|
|
430
|
-
let bandwidthFee = 0;
|
|
431
|
-
if (bandwidthNeeded > availableBandwidth) {
|
|
432
|
-
// Need to burn TRX for bandwidth
|
|
433
|
-
const bandwidthToBuy = bandwidthNeeded - availableBandwidth;
|
|
434
|
-
bandwidthFee = bandwidthToBuy * chainParams.bandwidthFee;
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
// Total fee in SUN
|
|
438
|
-
const totalFeeSun = activationFee + bandwidthFee;
|
|
439
|
-
|
|
440
|
-
return AssetValue.from({
|
|
441
|
-
chain: Chain.Tron,
|
|
442
|
-
value: totalFeeSun,
|
|
443
|
-
fromBaseDecimal: 6, // SUN to TRX
|
|
444
|
-
});
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
// TRC20 Transfer - needs both bandwidth and energy
|
|
448
|
-
const bandwidthNeeded = TRC20_TRANSFER_BANDWIDTH;
|
|
449
|
-
const energyNeeded = TRC20_TRANSFER_ENERGY;
|
|
450
|
-
|
|
451
|
-
const availableBandwidth =
|
|
452
|
-
resources.bandwidth.free + (resources.bandwidth.total - resources.bandwidth.used);
|
|
453
|
-
const availableEnergy = resources.energy.total - resources.energy.used;
|
|
454
|
-
|
|
455
|
-
let bandwidthFee = 0;
|
|
456
|
-
if (bandwidthNeeded > availableBandwidth) {
|
|
457
|
-
const bandwidthToBuy = bandwidthNeeded - availableBandwidth;
|
|
458
|
-
bandwidthFee = bandwidthToBuy * chainParams.bandwidthFee;
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
let energyFee = 0;
|
|
462
|
-
if (energyNeeded > availableEnergy) {
|
|
463
|
-
const energyToBuy = energyNeeded - availableEnergy;
|
|
464
|
-
energyFee = energyToBuy * chainParams.energyFee;
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
// Total fee in SUN
|
|
468
|
-
const totalFeeSun = activationFee + bandwidthFee + energyFee;
|
|
469
|
-
|
|
470
|
-
return AssetValue.from({
|
|
471
|
-
chain: Chain.Tron,
|
|
472
|
-
value: totalFeeSun,
|
|
473
|
-
fromBaseDecimal: 6, // SUN to TRX
|
|
474
|
-
});
|
|
475
|
-
} catch (error) {
|
|
476
|
-
// Fallback to conservative estimates if calculation fails
|
|
477
|
-
warnOnce(
|
|
478
|
-
true,
|
|
479
|
-
`Failed to calculate exact fee, using conservative estimate: ${error instanceof Error ? error.message : error}`,
|
|
480
|
-
);
|
|
481
|
-
|
|
482
|
-
throw new SwapKitError("toolbox_tron_fee_estimation_failed", { error });
|
|
483
|
-
}
|
|
484
|
-
};
|
|
485
|
-
|
|
486
|
-
const createTransaction = async (params: TronCreateTransactionParams) => {
|
|
487
|
-
const { recipient, assetValue, memo, sender } = params;
|
|
488
|
-
const isNative = assetValue.isGasAsset;
|
|
489
|
-
|
|
490
|
-
if (isNative) {
|
|
491
|
-
const transaction = await tronWeb.transactionBuilder.sendTrx(
|
|
492
|
-
recipient,
|
|
493
|
-
assetValue.getBaseValue("number"),
|
|
494
|
-
sender,
|
|
495
|
-
);
|
|
496
|
-
|
|
497
|
-
if (memo) {
|
|
498
|
-
return tronWeb.transactionBuilder.addUpdateData(transaction, memo, "utf8");
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
return transaction;
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
tronWeb.setAddress(sender); // Set address for contract calls
|
|
505
|
-
// For TRC20, we would need to build the transaction manually
|
|
506
|
-
// This is a simplified version - in practice, you'd build the contract call transaction
|
|
507
|
-
const contractAddress = assetValue.address;
|
|
508
|
-
if (!contractAddress) {
|
|
509
|
-
throw new SwapKitError("toolbox_tron_invalid_token_identifier", {
|
|
510
|
-
identifier: assetValue.toString(),
|
|
511
|
-
});
|
|
512
|
-
}
|
|
513
|
-
|
|
514
|
-
// Build TRC20 transfer transaction
|
|
515
|
-
// First, try using triggerSmartContract (might work despite the known bug)
|
|
516
|
-
try {
|
|
517
|
-
const functionSelector = "transfer(address,uint256)";
|
|
518
|
-
const parameter = [
|
|
519
|
-
{ type: "address", value: recipient },
|
|
520
|
-
{ type: "uint256", value: assetValue.getBaseValue("string") },
|
|
521
|
-
];
|
|
522
|
-
|
|
523
|
-
const options = {
|
|
524
|
-
feeLimit: calculateFeeLimit(),
|
|
525
|
-
callValue: 0,
|
|
526
|
-
};
|
|
527
|
-
|
|
528
|
-
const result = await tronWeb.transactionBuilder.triggerSmartContract(
|
|
529
|
-
contractAddress,
|
|
530
|
-
functionSelector,
|
|
531
|
-
options,
|
|
532
|
-
parameter,
|
|
533
|
-
sender,
|
|
534
|
-
);
|
|
535
|
-
|
|
536
|
-
return result.transaction;
|
|
537
|
-
} catch (error) {
|
|
538
|
-
// If both methods fail, throw a descriptive error
|
|
539
|
-
throw new SwapKitError("toolbox_tron_transaction_creation_failed", {
|
|
540
|
-
message:
|
|
541
|
-
"Failed to create TRC20 transaction. This might be due to TronWeb 6.0.3 bug. Use the transfer method directly instead.",
|
|
542
|
-
originalError: error instanceof Error ? error.message : String(error),
|
|
543
|
-
});
|
|
544
|
-
}
|
|
545
|
-
};
|
|
546
|
-
|
|
547
|
-
const signTransaction = async (transaction: TronTransaction) => {
|
|
548
|
-
if (!signer) throw new SwapKitError("toolbox_tron_no_signer");
|
|
549
|
-
return await signer.signTransaction(transaction);
|
|
550
|
-
};
|
|
551
|
-
|
|
552
|
-
const broadcastTransaction = async (signedTx: TronSignedTransaction) => {
|
|
553
|
-
const { txid } = await tronWeb.trx.sendRawTransaction(signedTx);
|
|
554
|
-
return txid;
|
|
555
|
-
};
|
|
556
|
-
|
|
557
|
-
/**
|
|
558
|
-
* Check the current allowance for a spender on a token
|
|
559
|
-
*/
|
|
560
|
-
const getApprovedAmount = async ({ assetAddress, spenderAddress, from }: ApprovedParams) => {
|
|
561
|
-
try {
|
|
562
|
-
const contract = tronWeb.contract(trc20ABI, assetAddress);
|
|
563
|
-
|
|
564
|
-
if (!contract.methods?.allowance) {
|
|
565
|
-
throw new SwapKitError("toolbox_tron_invalid_token_contract");
|
|
566
|
-
}
|
|
567
|
-
|
|
568
|
-
const allowance = (
|
|
569
|
-
await contract.methods.allowance(from, spenderAddress).call()
|
|
570
|
-
)[0] as string;
|
|
571
|
-
return BigInt(allowance || 0);
|
|
572
|
-
} catch (error) {
|
|
573
|
-
throw new SwapKitError("toolbox_tron_allowance_check_failed", { error });
|
|
574
|
-
}
|
|
575
|
-
};
|
|
576
|
-
|
|
577
|
-
/**
|
|
578
|
-
* Check if a spender is approved for a specific amount
|
|
579
|
-
*/
|
|
580
|
-
const isApproved = async ({ assetAddress, spenderAddress, from, amount }: IsApprovedParams) => {
|
|
581
|
-
const allowance = await getApprovedAmount({ assetAddress, spenderAddress, from });
|
|
582
|
-
|
|
583
|
-
if (!amount) {
|
|
584
|
-
// If no amount specified, check if there's any approval
|
|
585
|
-
return allowance > 0n;
|
|
586
|
-
}
|
|
587
|
-
|
|
588
|
-
const amountBigInt = BigInt(amount);
|
|
589
|
-
return allowance >= amountBigInt;
|
|
590
|
-
};
|
|
591
|
-
|
|
592
|
-
/**
|
|
593
|
-
* Approve a spender to transfer tokens
|
|
594
|
-
*/
|
|
595
|
-
const approve = async ({ assetAddress, spenderAddress, amount, from }: ApproveParams) => {
|
|
596
|
-
if (!signer) throw new SwapKitError("toolbox_tron_no_signer");
|
|
597
|
-
|
|
598
|
-
const fromAddress = from || (await getAddress());
|
|
599
|
-
const approvalAmount = amount !== undefined ? BigInt(amount).toString() : MAX_APPROVAL;
|
|
600
|
-
|
|
601
|
-
// Build approve transaction using triggerSmartContract
|
|
602
|
-
const functionSelector = "approve(address,uint256)";
|
|
603
|
-
const parameter = [
|
|
604
|
-
{ type: "address", value: spenderAddress },
|
|
605
|
-
{ type: "uint256", value: approvalAmount },
|
|
606
|
-
];
|
|
607
|
-
|
|
608
|
-
const feeLimit = calculateFeeLimit();
|
|
609
|
-
const options = {
|
|
610
|
-
feeLimit,
|
|
611
|
-
callValue: 0,
|
|
612
|
-
};
|
|
613
|
-
|
|
614
|
-
try {
|
|
615
|
-
const { transaction } = await tronWeb.transactionBuilder.triggerSmartContract(
|
|
616
|
-
assetAddress,
|
|
617
|
-
functionSelector,
|
|
618
|
-
options,
|
|
619
|
-
parameter,
|
|
620
|
-
fromAddress,
|
|
621
|
-
);
|
|
622
|
-
|
|
623
|
-
const signedTx = await signer.signTransaction(transaction);
|
|
624
|
-
const { txid } = await tronWeb.trx.sendRawTransaction(signedTx);
|
|
625
|
-
|
|
626
|
-
if (!txid) {
|
|
627
|
-
throw new SwapKitError("toolbox_tron_approve_failed");
|
|
628
|
-
}
|
|
629
|
-
|
|
630
|
-
return txid;
|
|
631
|
-
} catch (error) {
|
|
632
|
-
throw new SwapKitError("toolbox_tron_approve_failed", { error });
|
|
633
|
-
}
|
|
634
|
-
};
|
|
635
|
-
|
|
636
|
-
return {
|
|
637
|
-
tronWeb,
|
|
638
|
-
getAddress,
|
|
639
|
-
validateAddress: await getTronAddressValidator(),
|
|
640
|
-
getBalance,
|
|
641
|
-
transfer,
|
|
642
|
-
estimateTransactionFee,
|
|
643
|
-
createTransaction,
|
|
644
|
-
signTransaction,
|
|
645
|
-
broadcastTransaction,
|
|
646
|
-
approve,
|
|
647
|
-
isApproved,
|
|
648
|
-
getApprovedAmount,
|
|
649
|
-
};
|
|
650
|
-
};
|