@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.
Files changed (232) hide show
  1. package/dist/src/cosmos/index.cjs +2 -2
  2. package/dist/src/cosmos/index.cjs.map +10 -6
  3. package/dist/src/cosmos/index.js +2 -2
  4. package/dist/src/cosmos/index.js.map +10 -6
  5. package/dist/src/evm/index.cjs +2 -2
  6. package/dist/src/evm/index.cjs.map +10 -8
  7. package/dist/src/evm/index.js +2 -2
  8. package/dist/src/evm/index.js.map +10 -8
  9. package/dist/src/index.cjs +4 -2
  10. package/dist/src/index.cjs.map +54 -4
  11. package/dist/src/index.js +4 -2
  12. package/dist/src/index.js.map +54 -4
  13. package/dist/src/near/index.cjs +2 -2
  14. package/dist/src/near/index.cjs.map +7 -5
  15. package/dist/src/near/index.js +2 -2
  16. package/dist/src/near/index.js.map +7 -5
  17. package/dist/src/radix/index.cjs +2 -2
  18. package/dist/src/radix/index.cjs.map +2 -2
  19. package/dist/src/radix/index.js +2 -2
  20. package/dist/src/radix/index.js.map +2 -2
  21. package/dist/src/ripple/index.cjs +2 -2
  22. package/dist/src/ripple/index.cjs.map +2 -2
  23. package/dist/src/ripple/index.js +2 -2
  24. package/dist/src/ripple/index.js.map +2 -2
  25. package/dist/src/solana/index.cjs +2 -2
  26. package/dist/src/solana/index.cjs.map +5 -4
  27. package/dist/src/solana/index.js +2 -2
  28. package/dist/src/solana/index.js.map +5 -4
  29. package/dist/src/substrate/index.cjs +2 -2
  30. package/dist/src/substrate/index.cjs.map +6 -5
  31. package/dist/src/substrate/index.js +2 -2
  32. package/dist/src/substrate/index.js.map +6 -5
  33. package/dist/src/tron/index.cjs +2 -2
  34. package/dist/src/tron/index.cjs.map +6 -5
  35. package/dist/src/tron/index.js +2 -2
  36. package/dist/src/tron/index.js.map +6 -5
  37. package/dist/src/utxo/index.cjs +4 -4
  38. package/dist/src/utxo/index.cjs.map +10 -7
  39. package/dist/src/utxo/index.js +4 -4
  40. package/dist/src/utxo/index.js.map +10 -7
  41. package/{src/cosmos/index.ts → dist/types/cosmos/index.d.ts} +1 -0
  42. package/dist/types/cosmos/index.d.ts.map +1 -0
  43. package/dist/types/cosmos/thorchainUtils/addressFormat.d.ts +5 -0
  44. package/dist/types/cosmos/thorchainUtils/addressFormat.d.ts.map +1 -0
  45. package/{src/cosmos/thorchainUtils/index.ts → dist/types/cosmos/thorchainUtils/index.d.ts} +1 -0
  46. package/dist/types/cosmos/thorchainUtils/index.d.ts.map +1 -0
  47. package/dist/types/cosmos/thorchainUtils/messages.d.ts +208 -0
  48. package/dist/types/cosmos/thorchainUtils/messages.d.ts.map +1 -0
  49. package/dist/types/cosmos/thorchainUtils/registry.d.ts +4 -0
  50. package/dist/types/cosmos/thorchainUtils/registry.d.ts.map +1 -0
  51. package/dist/types/cosmos/thorchainUtils/types/MsgCompiled.d.ts +2 -0
  52. package/dist/types/cosmos/thorchainUtils/types/MsgCompiled.d.ts.map +1 -0
  53. package/dist/types/cosmos/thorchainUtils/types/client-types.d.ts +66 -0
  54. package/dist/types/cosmos/thorchainUtils/types/client-types.d.ts.map +1 -0
  55. package/dist/types/cosmos/thorchainUtils/types/index.d.ts +2 -0
  56. package/dist/types/cosmos/thorchainUtils/types/index.d.ts.map +1 -0
  57. package/dist/types/cosmos/toolbox/cosmos.d.ts +93 -0
  58. package/dist/types/cosmos/toolbox/cosmos.d.ts.map +1 -0
  59. package/dist/types/cosmos/toolbox/index.d.ts +14 -0
  60. package/dist/types/cosmos/toolbox/index.d.ts.map +1 -0
  61. package/dist/types/cosmos/toolbox/thorchain.d.ts +158 -0
  62. package/dist/types/cosmos/toolbox/thorchain.d.ts.map +1 -0
  63. package/{src/cosmos/types.ts → dist/types/cosmos/types.d.ts} +24 -29
  64. package/dist/types/cosmos/types.d.ts.map +1 -0
  65. package/dist/types/cosmos/util.d.ts +68 -0
  66. package/dist/types/cosmos/util.d.ts.map +1 -0
  67. package/dist/types/evm/api.d.ts +8 -0
  68. package/dist/types/evm/api.d.ts.map +1 -0
  69. package/dist/types/evm/contracts/eth/multicall.d.ts +36 -0
  70. package/dist/types/evm/contracts/eth/multicall.d.ts.map +1 -0
  71. package/dist/types/evm/contracts/op/gasOracle.d.ts +40 -0
  72. package/dist/types/evm/contracts/op/gasOracle.d.ts.map +1 -0
  73. package/dist/types/evm/helpers.d.ts +20 -0
  74. package/dist/types/evm/helpers.d.ts.map +1 -0
  75. package/{src/evm/index.ts → dist/types/evm/index.d.ts} +1 -0
  76. package/dist/types/evm/index.d.ts.map +1 -0
  77. package/dist/types/evm/toolbox/baseEVMToolbox.d.ts +82 -0
  78. package/dist/types/evm/toolbox/baseEVMToolbox.d.ts.map +1 -0
  79. package/dist/types/evm/toolbox/evm.d.ts +367 -0
  80. package/dist/types/evm/toolbox/evm.d.ts.map +1 -0
  81. package/dist/types/evm/toolbox/index.d.ts +89 -0
  82. package/dist/types/evm/toolbox/index.d.ts.map +1 -0
  83. package/dist/types/evm/toolbox/op.d.ts +62 -0
  84. package/dist/types/evm/toolbox/op.d.ts.map +1 -0
  85. package/dist/types/evm/types.d.ts +98 -0
  86. package/dist/types/evm/types.d.ts.map +1 -0
  87. package/dist/types/index.d.ts +63 -0
  88. package/dist/types/index.d.ts.map +1 -0
  89. package/dist/types/near/helpers/core.d.ts +15 -0
  90. package/dist/types/near/helpers/core.d.ts.map +1 -0
  91. package/dist/types/near/helpers/gasEstimation.d.ts +41 -0
  92. package/dist/types/near/helpers/gasEstimation.d.ts.map +1 -0
  93. package/dist/types/near/helpers/nep141.d.ts +72 -0
  94. package/dist/types/near/helpers/nep141.d.ts.map +1 -0
  95. package/dist/types/near/index.d.ts +10 -0
  96. package/dist/types/near/index.d.ts.map +1 -0
  97. package/dist/types/near/toolbox.d.ts +4 -0
  98. package/dist/types/near/toolbox.d.ts.map +1 -0
  99. package/dist/types/near/types/contract.d.ts +38 -0
  100. package/dist/types/near/types/contract.d.ts.map +1 -0
  101. package/dist/types/near/types/nep141.d.ts +56 -0
  102. package/dist/types/near/types/nep141.d.ts.map +1 -0
  103. package/dist/types/near/types/toolbox.d.ts +57 -0
  104. package/dist/types/near/types/toolbox.d.ts.map +1 -0
  105. package/dist/types/near/types.d.ts +44 -0
  106. package/dist/types/near/types.d.ts.map +1 -0
  107. package/dist/types/radix/index.d.ts +14 -0
  108. package/dist/types/radix/index.d.ts.map +1 -0
  109. package/dist/types/ripple/index.d.ts +43 -0
  110. package/dist/types/ripple/index.d.ts.map +1 -0
  111. package/dist/types/solana/index.d.ts +37 -0
  112. package/dist/types/solana/index.d.ts.map +1 -0
  113. package/dist/types/solana/toolbox.d.ts +41 -0
  114. package/dist/types/solana/toolbox.d.ts.map +1 -0
  115. package/dist/types/substrate/balance.d.ts +17 -0
  116. package/dist/types/substrate/balance.d.ts.map +1 -0
  117. package/{src/substrate/index.ts → dist/types/substrate/index.d.ts} +1 -0
  118. package/dist/types/substrate/index.d.ts.map +1 -0
  119. package/dist/types/substrate/substrate.d.ts +148 -0
  120. package/dist/types/substrate/substrate.d.ts.map +1 -0
  121. package/dist/types/substrate/types.d.ts +100 -0
  122. package/dist/types/substrate/types.d.ts.map +1 -0
  123. package/dist/types/tron/helpers/trc20.abi.d.ts +156 -0
  124. package/dist/types/tron/helpers/trc20.abi.d.ts.map +1 -0
  125. package/dist/types/tron/helpers/trongrid.d.ts +8 -0
  126. package/dist/types/tron/helpers/trongrid.d.ts.map +1 -0
  127. package/dist/types/tron/index.d.ts +6 -0
  128. package/dist/types/tron/index.d.ts.map +1 -0
  129. package/dist/types/tron/toolbox.d.ts +26 -0
  130. package/dist/types/tron/toolbox.d.ts.map +1 -0
  131. package/dist/types/tron/types.d.ts +101 -0
  132. package/dist/types/tron/types.d.ts.map +1 -0
  133. package/dist/types/types.d.ts +18 -0
  134. package/dist/types/types.d.ts.map +1 -0
  135. package/dist/types/utils.d.ts +4 -0
  136. package/dist/types/utils.d.ts.map +1 -0
  137. package/dist/types/utxo/helpers/api.d.ts +133 -0
  138. package/dist/types/utxo/helpers/api.d.ts.map +1 -0
  139. package/dist/types/utxo/helpers/bchaddrjs.d.ts +10 -0
  140. package/dist/types/utxo/helpers/bchaddrjs.d.ts.map +1 -0
  141. package/dist/types/utxo/helpers/coinselect.d.ts +16 -0
  142. package/dist/types/utxo/helpers/coinselect.d.ts.map +1 -0
  143. package/{src/utxo/helpers/index.ts → dist/types/utxo/helpers/index.d.ts} +1 -0
  144. package/dist/types/utxo/helpers/index.d.ts.map +1 -0
  145. package/dist/types/utxo/helpers/txSize.d.ts +21 -0
  146. package/dist/types/utxo/helpers/txSize.d.ts.map +1 -0
  147. package/{src/utxo/index.ts → dist/types/utxo/index.d.ts} +1 -0
  148. package/dist/types/utxo/index.d.ts.map +1 -0
  149. package/dist/types/utxo/toolbox/bitcoinCash.d.ts +104 -0
  150. package/dist/types/utxo/toolbox/bitcoinCash.d.ts.map +1 -0
  151. package/dist/types/utxo/toolbox/index.d.ts +50 -0
  152. package/dist/types/utxo/toolbox/index.d.ts.map +1 -0
  153. package/dist/types/utxo/toolbox/utxo.d.ts +102 -0
  154. package/dist/types/utxo/toolbox/utxo.d.ts.map +1 -0
  155. package/dist/types/utxo/toolbox/zcash.d.ts +83 -0
  156. package/dist/types/utxo/toolbox/zcash.d.ts.map +1 -0
  157. package/dist/types/utxo/types.d.ts +46 -0
  158. package/dist/types/utxo/types.d.ts.map +1 -0
  159. package/package.json +15 -18
  160. package/dist/chunk-0h4xdrwz.js +0 -5
  161. package/dist/chunk-0h4xdrwz.js.map +0 -10
  162. package/dist/chunk-4yap1fvd.js +0 -4
  163. package/dist/chunk-4yap1fvd.js.map +0 -10
  164. package/dist/chunk-9bqegm61.js +0 -4
  165. package/dist/chunk-9bqegm61.js.map +0 -10
  166. package/dist/chunk-fazw0jvt.js +0 -4
  167. package/dist/chunk-fazw0jvt.js.map +0 -9
  168. package/dist/chunk-fjfxga2v.js +0 -4
  169. package/dist/chunk-fjfxga2v.js.map +0 -10
  170. package/dist/chunk-s47y8512.js +0 -5
  171. package/dist/chunk-s47y8512.js.map +0 -9
  172. package/dist/chunk-vtd17cje.js +0 -4
  173. package/dist/chunk-vtd17cje.js.map +0 -10
  174. package/dist/chunk-zcdeg6h9.js +0 -5
  175. package/dist/chunk-zcdeg6h9.js.map +0 -10
  176. package/src/cosmos/thorchainUtils/addressFormat.ts +0 -26
  177. package/src/cosmos/thorchainUtils/messages.ts +0 -262
  178. package/src/cosmos/thorchainUtils/registry.ts +0 -44
  179. package/src/cosmos/thorchainUtils/types/MsgCompiled.ts +0 -2800
  180. package/src/cosmos/thorchainUtils/types/client-types.ts +0 -73
  181. package/src/cosmos/thorchainUtils/types/index.ts +0 -1
  182. package/src/cosmos/toolbox/cosmos.ts +0 -375
  183. package/src/cosmos/toolbox/index.ts +0 -33
  184. package/src/cosmos/toolbox/thorchain.ts +0 -313
  185. package/src/cosmos/util.ts +0 -266
  186. package/src/evm/__tests__/address-validation.test.ts +0 -86
  187. package/src/evm/__tests__/ethereum.test.ts +0 -141
  188. package/src/evm/api.ts +0 -21
  189. package/src/evm/contracts/eth/multicall.ts +0 -165
  190. package/src/evm/contracts/op/gasOracle.ts +0 -151
  191. package/src/evm/helpers.ts +0 -194
  192. package/src/evm/toolbox/baseEVMToolbox.ts +0 -762
  193. package/src/evm/toolbox/evm.ts +0 -66
  194. package/src/evm/toolbox/index.ts +0 -52
  195. package/src/evm/toolbox/op.ts +0 -131
  196. package/src/evm/types.ts +0 -146
  197. package/src/index.ts +0 -263
  198. package/src/near/__tests__/core.test.ts +0 -80
  199. package/src/near/helpers/contractFactory.ts +0 -22
  200. package/src/near/helpers/core.ts +0 -91
  201. package/src/near/helpers/gasEstimation.ts +0 -110
  202. package/src/near/helpers/index.ts +0 -5
  203. package/src/near/helpers/nep141.ts +0 -110
  204. package/src/near/index.ts +0 -24
  205. package/src/near/toolbox.ts +0 -509
  206. package/src/near/types/contract.ts +0 -48
  207. package/src/near/types/nep141.ts +0 -66
  208. package/src/near/types.ts +0 -57
  209. package/src/radix/index.ts +0 -156
  210. package/src/ripple/index.ts +0 -192
  211. package/src/solana/index.ts +0 -55
  212. package/src/solana/toolbox.ts +0 -433
  213. package/src/substrate/balance.ts +0 -92
  214. package/src/substrate/substrate.ts +0 -320
  215. package/src/substrate/types.ts +0 -120
  216. package/src/tron/__tests__/toolbox.test.ts +0 -147
  217. package/src/tron/helpers/trc20.abi.ts +0 -107
  218. package/src/tron/helpers/trongrid.ts +0 -54
  219. package/src/tron/index.ts +0 -17
  220. package/src/tron/toolbox.ts +0 -650
  221. package/src/tron/types.ts +0 -120
  222. package/src/utils.ts +0 -27
  223. package/src/utxo/__tests__/zcash-integration.test.ts +0 -114
  224. package/src/utxo/helpers/api.ts +0 -560
  225. package/src/utxo/helpers/bchaddrjs.ts +0 -183
  226. package/src/utxo/helpers/coinselect.ts +0 -98
  227. package/src/utxo/helpers/txSize.ts +0 -104
  228. package/src/utxo/toolbox/bitcoinCash.ts +0 -320
  229. package/src/utxo/toolbox/index.ts +0 -90
  230. package/src/utxo/toolbox/utxo.ts +0 -525
  231. package/src/utxo/toolbox/zcash.ts +0 -208
  232. package/src/utxo/types.ts +0 -57
@@ -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
- };