@tcswap/toolboxes 4.3.15

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 (275) hide show
  1. package/dist/src/cardano/index.cjs +4 -0
  2. package/dist/src/cardano/index.cjs.map +11 -0
  3. package/dist/src/cardano/index.js +4 -0
  4. package/dist/src/cardano/index.js.map +11 -0
  5. package/dist/src/cosmos/index.cjs +4 -0
  6. package/dist/src/cosmos/index.cjs.map +20 -0
  7. package/dist/src/cosmos/index.js +4 -0
  8. package/dist/src/cosmos/index.js.map +20 -0
  9. package/dist/src/evm/index.cjs +4 -0
  10. package/dist/src/evm/index.cjs.map +20 -0
  11. package/dist/src/evm/index.js +4 -0
  12. package/dist/src/evm/index.js.map +20 -0
  13. package/dist/src/index.cjs +5 -0
  14. package/dist/src/index.cjs.map +67 -0
  15. package/dist/src/index.js +5 -0
  16. package/dist/src/index.js.map +67 -0
  17. package/dist/src/near/index.cjs +4 -0
  18. package/dist/src/near/index.cjs.map +16 -0
  19. package/dist/src/near/index.js +4 -0
  20. package/dist/src/near/index.js.map +16 -0
  21. package/dist/src/radix/index.cjs +4 -0
  22. package/dist/src/radix/index.cjs.map +10 -0
  23. package/dist/src/radix/index.js +4 -0
  24. package/dist/src/radix/index.js.map +10 -0
  25. package/dist/src/ripple/index.cjs +4 -0
  26. package/dist/src/ripple/index.cjs.map +10 -0
  27. package/dist/src/ripple/index.js +4 -0
  28. package/dist/src/ripple/index.js.map +10 -0
  29. package/dist/src/solana/index.cjs +4 -0
  30. package/dist/src/solana/index.cjs.map +11 -0
  31. package/dist/src/solana/index.js +4 -0
  32. package/dist/src/solana/index.js.map +11 -0
  33. package/dist/src/substrate/index.cjs +4 -0
  34. package/dist/src/substrate/index.cjs.map +13 -0
  35. package/dist/src/substrate/index.js +4 -0
  36. package/dist/src/substrate/index.js.map +13 -0
  37. package/dist/src/sui/index.cjs +4 -0
  38. package/dist/src/sui/index.cjs.map +11 -0
  39. package/dist/src/sui/index.js +4 -0
  40. package/dist/src/sui/index.js.map +11 -0
  41. package/dist/src/ton/index.cjs +4 -0
  42. package/dist/src/ton/index.cjs.map +11 -0
  43. package/dist/src/ton/index.js +4 -0
  44. package/dist/src/ton/index.js.map +11 -0
  45. package/dist/src/tron/index.cjs +4 -0
  46. package/dist/src/tron/index.cjs.map +13 -0
  47. package/dist/src/tron/index.js +4 -0
  48. package/dist/src/tron/index.js.map +13 -0
  49. package/dist/src/utxo/index.cjs +5 -0
  50. package/dist/src/utxo/index.cjs.map +21 -0
  51. package/dist/src/utxo/index.js +5 -0
  52. package/dist/src/utxo/index.js.map +21 -0
  53. package/dist/types/cardano/index.d.ts +3 -0
  54. package/dist/types/cardano/index.d.ts.map +1 -0
  55. package/dist/types/cardano/toolbox.d.ts +37 -0
  56. package/dist/types/cardano/toolbox.d.ts.map +1 -0
  57. package/dist/types/cardano/types.d.ts +11 -0
  58. package/dist/types/cardano/types.d.ts.map +1 -0
  59. package/dist/types/cosmos/index.d.ts +5 -0
  60. package/dist/types/cosmos/index.d.ts.map +1 -0
  61. package/dist/types/cosmos/thorchainUtils/addressFormat.d.ts +8 -0
  62. package/dist/types/cosmos/thorchainUtils/addressFormat.d.ts.map +1 -0
  63. package/dist/types/cosmos/thorchainUtils/index.d.ts +5 -0
  64. package/dist/types/cosmos/thorchainUtils/index.d.ts.map +1 -0
  65. package/dist/types/cosmos/thorchainUtils/messages.d.ts +211 -0
  66. package/dist/types/cosmos/thorchainUtils/messages.d.ts.map +1 -0
  67. package/dist/types/cosmos/thorchainUtils/registry.d.ts +4 -0
  68. package/dist/types/cosmos/thorchainUtils/registry.d.ts.map +1 -0
  69. package/dist/types/cosmos/thorchainUtils/types/MsgCompiled.d.ts +2 -0
  70. package/dist/types/cosmos/thorchainUtils/types/MsgCompiled.d.ts.map +1 -0
  71. package/dist/types/cosmos/thorchainUtils/types/client-types.d.ts +63 -0
  72. package/dist/types/cosmos/thorchainUtils/types/client-types.d.ts.map +1 -0
  73. package/dist/types/cosmos/thorchainUtils/types/index.d.ts +2 -0
  74. package/dist/types/cosmos/thorchainUtils/types/index.d.ts.map +1 -0
  75. package/dist/types/cosmos/toolbox/cosmos.d.ts +65 -0
  76. package/dist/types/cosmos/toolbox/cosmos.d.ts.map +1 -0
  77. package/dist/types/cosmos/toolbox/index.d.ts +18 -0
  78. package/dist/types/cosmos/toolbox/index.d.ts.map +1 -0
  79. package/dist/types/cosmos/toolbox/thorchain.d.ts +161 -0
  80. package/dist/types/cosmos/toolbox/thorchain.d.ts.map +1 -0
  81. package/dist/types/cosmos/types.d.ts +49 -0
  82. package/dist/types/cosmos/types.d.ts.map +1 -0
  83. package/dist/types/cosmos/util.d.ts +77 -0
  84. package/dist/types/cosmos/util.d.ts.map +1 -0
  85. package/dist/types/evm/api.d.ts +8 -0
  86. package/dist/types/evm/api.d.ts.map +1 -0
  87. package/dist/types/evm/contracts/eth/multicall.d.ts +36 -0
  88. package/dist/types/evm/contracts/eth/multicall.d.ts.map +1 -0
  89. package/dist/types/evm/contracts/op/gasOracle.d.ts +40 -0
  90. package/dist/types/evm/contracts/op/gasOracle.d.ts.map +1 -0
  91. package/dist/types/evm/helpers.d.ts +6 -0
  92. package/dist/types/evm/helpers.d.ts.map +1 -0
  93. package/dist/types/evm/index.d.ts +5 -0
  94. package/dist/types/evm/index.d.ts.map +1 -0
  95. package/dist/types/evm/toolbox/baseEVMToolbox.d.ts +88 -0
  96. package/dist/types/evm/toolbox/baseEVMToolbox.d.ts.map +1 -0
  97. package/dist/types/evm/toolbox/evm.d.ts +767 -0
  98. package/dist/types/evm/toolbox/evm.d.ts.map +1 -0
  99. package/dist/types/evm/toolbox/index.d.ts +7 -0
  100. package/dist/types/evm/toolbox/index.d.ts.map +1 -0
  101. package/dist/types/evm/toolbox/op.d.ts +67 -0
  102. package/dist/types/evm/toolbox/op.d.ts.map +1 -0
  103. package/dist/types/evm/types.d.ts +108 -0
  104. package/dist/types/evm/types.d.ts.map +1 -0
  105. package/dist/types/index.d.ts +78 -0
  106. package/dist/types/index.d.ts.map +1 -0
  107. package/dist/types/near/helpers/core.d.ts +18 -0
  108. package/dist/types/near/helpers/core.d.ts.map +1 -0
  109. package/dist/types/near/helpers/gasEstimation.d.ts +41 -0
  110. package/dist/types/near/helpers/gasEstimation.d.ts.map +1 -0
  111. package/dist/types/near/helpers/nep141.d.ts +36 -0
  112. package/dist/types/near/helpers/nep141.d.ts.map +1 -0
  113. package/dist/types/near/index.d.ts +10 -0
  114. package/dist/types/near/index.d.ts.map +1 -0
  115. package/dist/types/near/toolbox.d.ts +35 -0
  116. package/dist/types/near/toolbox.d.ts.map +1 -0
  117. package/dist/types/near/types/contract.d.ts +38 -0
  118. package/dist/types/near/types/contract.d.ts.map +1 -0
  119. package/dist/types/near/types/nep141.d.ts +29 -0
  120. package/dist/types/near/types/nep141.d.ts.map +1 -0
  121. package/dist/types/near/types/toolbox.d.ts +51 -0
  122. package/dist/types/near/types/toolbox.d.ts.map +1 -0
  123. package/dist/types/near/types.d.ts +47 -0
  124. package/dist/types/near/types.d.ts.map +1 -0
  125. package/dist/types/radix/index.d.ts +17 -0
  126. package/dist/types/radix/index.d.ts.map +1 -0
  127. package/dist/types/ripple/index.d.ts +49 -0
  128. package/dist/types/ripple/index.d.ts.map +1 -0
  129. package/dist/types/solana/index.d.ts +23 -0
  130. package/dist/types/solana/index.d.ts.map +1 -0
  131. package/dist/types/solana/toolbox.d.ts +54 -0
  132. package/dist/types/solana/toolbox.d.ts.map +1 -0
  133. package/dist/types/substrate/balance.d.ts +20 -0
  134. package/dist/types/substrate/balance.d.ts.map +1 -0
  135. package/dist/types/substrate/index.d.ts +3 -0
  136. package/dist/types/substrate/index.d.ts.map +1 -0
  137. package/dist/types/substrate/substrate.d.ts +151 -0
  138. package/dist/types/substrate/substrate.d.ts.map +1 -0
  139. package/dist/types/substrate/types.d.ts +100 -0
  140. package/dist/types/substrate/types.d.ts.map +1 -0
  141. package/dist/types/sui/index.d.ts +3 -0
  142. package/dist/types/sui/index.d.ts.map +1 -0
  143. package/dist/types/sui/toolbox.d.ts +22 -0
  144. package/dist/types/sui/toolbox.d.ts.map +1 -0
  145. package/dist/types/sui/types.d.ts +16 -0
  146. package/dist/types/sui/types.d.ts.map +1 -0
  147. package/dist/types/ton/index.d.ts +3 -0
  148. package/dist/types/ton/index.d.ts.map +1 -0
  149. package/dist/types/ton/toolbox.d.ts +17 -0
  150. package/dist/types/ton/toolbox.d.ts.map +1 -0
  151. package/dist/types/ton/types.d.ts +22 -0
  152. package/dist/types/ton/types.d.ts.map +1 -0
  153. package/dist/types/tron/helpers/trc20.abi.d.ts +156 -0
  154. package/dist/types/tron/helpers/trc20.abi.d.ts.map +1 -0
  155. package/dist/types/tron/helpers/trongrid.d.ts +11 -0
  156. package/dist/types/tron/helpers/trongrid.d.ts.map +1 -0
  157. package/dist/types/tron/index.d.ts +6 -0
  158. package/dist/types/tron/index.d.ts.map +1 -0
  159. package/dist/types/tron/toolbox.d.ts +29 -0
  160. package/dist/types/tron/toolbox.d.ts.map +1 -0
  161. package/dist/types/tron/types.d.ts +103 -0
  162. package/dist/types/tron/types.d.ts.map +1 -0
  163. package/dist/types/types.d.ts +26 -0
  164. package/dist/types/types.d.ts.map +1 -0
  165. package/dist/types/utils.d.ts +7 -0
  166. package/dist/types/utils.d.ts.map +1 -0
  167. package/dist/types/utxo/helpers/api.d.ts +104 -0
  168. package/dist/types/utxo/helpers/api.d.ts.map +1 -0
  169. package/dist/types/utxo/helpers/bchaddrjs.d.ts +13 -0
  170. package/dist/types/utxo/helpers/bchaddrjs.d.ts.map +1 -0
  171. package/dist/types/utxo/helpers/coinselect.d.ts +20 -0
  172. package/dist/types/utxo/helpers/coinselect.d.ts.map +1 -0
  173. package/dist/types/utxo/helpers/index.d.ts +5 -0
  174. package/dist/types/utxo/helpers/index.d.ts.map +1 -0
  175. package/dist/types/utxo/helpers/txSize.d.ts +24 -0
  176. package/dist/types/utxo/helpers/txSize.d.ts.map +1 -0
  177. package/dist/types/utxo/index.d.ts +7 -0
  178. package/dist/types/utxo/index.d.ts.map +1 -0
  179. package/dist/types/utxo/toolbox/bitcoinCash.d.ts +96 -0
  180. package/dist/types/utxo/toolbox/bitcoinCash.d.ts.map +1 -0
  181. package/dist/types/utxo/toolbox/index.d.ts +31 -0
  182. package/dist/types/utxo/toolbox/index.d.ts.map +1 -0
  183. package/dist/types/utxo/toolbox/params.d.ts +32 -0
  184. package/dist/types/utxo/toolbox/params.d.ts.map +1 -0
  185. package/dist/types/utxo/toolbox/utxo.d.ts +106 -0
  186. package/dist/types/utxo/toolbox/utxo.d.ts.map +1 -0
  187. package/dist/types/utxo/toolbox/validators.d.ts +4 -0
  188. package/dist/types/utxo/toolbox/validators.d.ts.map +1 -0
  189. package/dist/types/utxo/toolbox/zcash.d.ts +75 -0
  190. package/dist/types/utxo/toolbox/zcash.d.ts.map +1 -0
  191. package/dist/types/utxo/types.d.ts +46 -0
  192. package/dist/types/utxo/types.d.ts.map +1 -0
  193. package/package.json +205 -0
  194. package/src/__tests__/address-validation-all-chains.test.ts +162 -0
  195. package/src/__tests__/addressValidator.test.ts +162 -0
  196. package/src/cardano/__tests__/toolbox.test.ts +48 -0
  197. package/src/cardano/index.ts +2 -0
  198. package/src/cardano/toolbox.ts +172 -0
  199. package/src/cardano/types.ts +10 -0
  200. package/src/cosmos/__tests__/toolbox.test.ts +95 -0
  201. package/src/cosmos/index.ts +4 -0
  202. package/src/cosmos/thorchainUtils/addressFormat.ts +26 -0
  203. package/src/cosmos/thorchainUtils/index.ts +4 -0
  204. package/src/cosmos/thorchainUtils/messages.ts +216 -0
  205. package/src/cosmos/thorchainUtils/registry.ts +43 -0
  206. package/src/cosmos/thorchainUtils/types/MsgCompiled.ts +2800 -0
  207. package/src/cosmos/thorchainUtils/types/client-types.ts +54 -0
  208. package/src/cosmos/thorchainUtils/types/index.ts +1 -0
  209. package/src/cosmos/toolbox/cosmos.ts +354 -0
  210. package/src/cosmos/toolbox/index.ts +39 -0
  211. package/src/cosmos/toolbox/thorchain.ts +253 -0
  212. package/src/cosmos/types.ts +48 -0
  213. package/src/cosmos/util.ts +218 -0
  214. package/src/evm/__tests__/address-validation.test.ts +84 -0
  215. package/src/evm/__tests__/ethereum.test.ts +141 -0
  216. package/src/evm/__tests__/signMessage.test.ts +60 -0
  217. package/src/evm/api.ts +10 -0
  218. package/src/evm/contracts/eth/multicall.ts +165 -0
  219. package/src/evm/contracts/op/gasOracle.ts +145 -0
  220. package/src/evm/helpers.ts +71 -0
  221. package/src/evm/index.ts +4 -0
  222. package/src/evm/toolbox/baseEVMToolbox.ts +701 -0
  223. package/src/evm/toolbox/evm.ts +66 -0
  224. package/src/evm/toolbox/index.ts +44 -0
  225. package/src/evm/toolbox/op.ts +147 -0
  226. package/src/evm/types.ts +146 -0
  227. package/src/index.ts +264 -0
  228. package/src/near/__tests__/core.test.ts +70 -0
  229. package/src/near/helpers/core.ts +89 -0
  230. package/src/near/helpers/gasEstimation.ts +96 -0
  231. package/src/near/helpers/nep141.ts +50 -0
  232. package/src/near/index.ts +21 -0
  233. package/src/near/toolbox.ts +425 -0
  234. package/src/near/types/contract.ts +32 -0
  235. package/src/near/types/nep141.ts +34 -0
  236. package/src/near/types/toolbox.ts +55 -0
  237. package/src/near/types.ts +44 -0
  238. package/src/radix/index.ts +142 -0
  239. package/src/ripple/index.ts +180 -0
  240. package/src/solana/index.ts +36 -0
  241. package/src/solana/toolbox.ts +413 -0
  242. package/src/substrate/balance.ts +92 -0
  243. package/src/substrate/index.ts +2 -0
  244. package/src/substrate/substrate.ts +285 -0
  245. package/src/substrate/types.ts +115 -0
  246. package/src/sui/__tests__/toolbox.test.ts +86 -0
  247. package/src/sui/index.ts +2 -0
  248. package/src/sui/toolbox.ts +170 -0
  249. package/src/sui/types.ts +11 -0
  250. package/src/ton/__tests__/toolbox.test.ts +67 -0
  251. package/src/ton/index.ts +2 -0
  252. package/src/ton/toolbox.ts +140 -0
  253. package/src/ton/types.ts +13 -0
  254. package/src/tron/__tests__/toolbox.test.ts +225 -0
  255. package/src/tron/helpers/trc20.abi.ts +107 -0
  256. package/src/tron/helpers/trongrid.ts +57 -0
  257. package/src/tron/index.ts +21 -0
  258. package/src/tron/toolbox.ts +589 -0
  259. package/src/tron/types.ts +83 -0
  260. package/src/types.ts +28 -0
  261. package/src/utils.ts +38 -0
  262. package/src/utxo/__tests__/zcash-integration.test.ts +97 -0
  263. package/src/utxo/helpers/api.ts +475 -0
  264. package/src/utxo/helpers/bchaddrjs.ts +170 -0
  265. package/src/utxo/helpers/coinselect.ts +96 -0
  266. package/src/utxo/helpers/index.ts +4 -0
  267. package/src/utxo/helpers/txSize.ts +141 -0
  268. package/src/utxo/index.ts +6 -0
  269. package/src/utxo/toolbox/bitcoinCash.ts +247 -0
  270. package/src/utxo/toolbox/index.ts +63 -0
  271. package/src/utxo/toolbox/params.ts +18 -0
  272. package/src/utxo/toolbox/utxo.ts +443 -0
  273. package/src/utxo/toolbox/validators.ts +36 -0
  274. package/src/utxo/toolbox/zcash.ts +246 -0
  275. package/src/utxo/types.ts +39 -0
@@ -0,0 +1,589 @@
1
+ /**
2
+ * Modifications © 2025 Horizontal Systems.
3
+ */
4
+
5
+ import {
6
+ AssetValue,
7
+ BaseDecimal,
8
+ Chain,
9
+ derivationPathToString,
10
+ getRPCUrl,
11
+ NetworkDerivationPath,
12
+ USwapError,
13
+ updateDerivationPath,
14
+ warnOnce,
15
+ } from "@tcswap/helpers";
16
+ import type { TronWeb } from "tronweb";
17
+ import { match, P } from "ts-pattern";
18
+ import { trc20ABI } from "./helpers/trc20.abi";
19
+ import { fetchAccountFromTronGrid } from "./helpers/trongrid";
20
+ import type {
21
+ TronApprovedParams,
22
+ TronApproveParams,
23
+ TronCreateTransactionParams,
24
+ TronIsApprovedParams,
25
+ TronSignedTransaction,
26
+ TronSigner,
27
+ TronToolboxOptions,
28
+ TronTransaction,
29
+ TronTransferParams,
30
+ } from "./types";
31
+
32
+ // Constants for TRON resource calculation
33
+ const TRX_TRANSFER_BANDWIDTH = 268; // Bandwidth consumed by a TRX transfer
34
+ const TRC20_TRANSFER_ENERGY = 13000; // Average energy consumed by TRC20 transfer
35
+ const TRC20_TRANSFER_BANDWIDTH = 345; // Bandwidth consumed by TRC20 transfer
36
+
37
+ // Known TRON tokens
38
+ const TRON_USDT_CONTRACT = "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t";
39
+
40
+ const MAX_APPROVAL = "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
41
+
42
+ export async function getTronAddressValidator() {
43
+ const TW = await import("tronweb");
44
+ const TronWeb = TW.TronWeb ?? TW.default?.TronWeb;
45
+
46
+ return (address: string) => {
47
+ return TronWeb.isAddress(address);
48
+ };
49
+ }
50
+
51
+ export async function getTronPrivateKeyFromMnemonic({
52
+ phrase,
53
+ derivationPath: customPath,
54
+ index,
55
+ }: {
56
+ phrase: string;
57
+ derivationPath?: string;
58
+ index?: number;
59
+ }) {
60
+ const derivationPathToUse =
61
+ customPath ||
62
+ derivationPathToString(updateDerivationPath(NetworkDerivationPath[Chain.Tron], { index: index || 0 }));
63
+
64
+ const { HDKey } = await import("@scure/bip32");
65
+ const { mnemonicToSeedSync } = await import("@scure/bip39");
66
+
67
+ const seed = mnemonicToSeedSync(phrase);
68
+ const hdKey = HDKey.fromMasterSeed(seed);
69
+ const derived = hdKey.derive(derivationPathToUse);
70
+
71
+ if (!derived.privateKey) {
72
+ throw new USwapError("toolbox_tron_no_signer");
73
+ }
74
+
75
+ return Buffer.from(derived.privateKey).toString("hex");
76
+ }
77
+
78
+ async function createKeysForPath({
79
+ phrase,
80
+ derivationPath,
81
+ tronWeb,
82
+ }: {
83
+ phrase: string;
84
+ derivationPath: string;
85
+ tronWeb: TronWeb;
86
+ }) {
87
+ const { HDKey } = await import("@scure/bip32");
88
+ const { mnemonicToSeedSync } = await import("@scure/bip39");
89
+
90
+ const seed = mnemonicToSeedSync(phrase);
91
+ const hdKey = HDKey.fromMasterSeed(seed);
92
+ const derived = hdKey.derive(derivationPath);
93
+
94
+ if (!derived.privateKey) {
95
+ throw new USwapError("toolbox_tron_no_signer");
96
+ }
97
+
98
+ // Convert private key to hex string for TronWeb
99
+ const privateKeyHex = Buffer.from(derived.privateKey).toString("hex");
100
+
101
+ tronWeb.setPrivateKey(privateKeyHex);
102
+
103
+ const address = tronWeb?.address.fromPrivateKey(privateKeyHex);
104
+
105
+ return {
106
+ getAddress: () => Promise.resolve(typeof address === "string" ? address : ""),
107
+ signTransaction: async (transaction: TronTransaction) => {
108
+ const signedTx = await tronWeb.trx.sign(transaction, privateKeyHex);
109
+ return signedTx;
110
+ },
111
+ };
112
+ }
113
+
114
+ export const createTronToolbox = async (
115
+ options: TronToolboxOptions = {},
116
+ ): Promise<{
117
+ tronWeb: TronWeb;
118
+ getAddress: () => Promise<string>;
119
+ validateAddress: (address: string) => boolean;
120
+ getBalance: (address: string) => Promise<AssetValue[]>;
121
+ transfer: (params: TronTransferParams) => Promise<string>;
122
+ estimateTransactionFee: (params: TronTransferParams & { sender?: string }) => Promise<AssetValue>;
123
+ createTransaction: (params: TronCreateTransactionParams) => Promise<TronTransaction>;
124
+ signTransaction: (transaction: TronTransaction) => Promise<TronSignedTransaction>;
125
+ broadcastTransaction: (signedTransaction: TronSignedTransaction) => Promise<string>;
126
+ approve: (params: TronApproveParams) => Promise<string>;
127
+ isApproved: (params: TronIsApprovedParams) => Promise<boolean>;
128
+ getApprovedAmount: (params: TronApprovedParams) => Promise<bigint>;
129
+ }> => {
130
+ const TW = await import("tronweb");
131
+ const TronWeb = TW.TronWeb ?? TW.default?.TronWeb;
132
+
133
+ const rpcUrl = await getRPCUrl(Chain.Tron);
134
+ // Note: TRON API key support can be added to USwapConfig apiKeys when needed
135
+ const headers = undefined; // No API key needed for basic TronGrid access
136
+
137
+ const tronWeb = new TronWeb({ fullHost: rpcUrl, headers });
138
+
139
+ // Handle derivation path and index
140
+ const index = "index" in options ? options.index || 0 : 0;
141
+ const derivationPath = derivationPathToString(
142
+ "derivationPath" in options && options.derivationPath
143
+ ? options.derivationPath
144
+ : updateDerivationPath(NetworkDerivationPath[Chain.Tron], { index }),
145
+ );
146
+
147
+ // Create signer based on options using pattern matching
148
+ const signer: TronSigner | undefined = await match(options)
149
+ .with({ phrase: P.string }, async ({ phrase }) => createKeysForPath({ derivationPath, phrase, tronWeb }))
150
+ .with({ signer: P.any }, ({ signer }) => Promise.resolve(signer as TronSigner))
151
+ .otherwise(() => Promise.resolve(undefined));
152
+
153
+ const getAddress = async () => {
154
+ if (!signer) throw new USwapError("toolbox_tron_no_signer");
155
+ return await signer.getAddress();
156
+ };
157
+
158
+ const calculateFeeLimit = () => {
159
+ return 100_000_000; // 100 TRX in SUN
160
+ };
161
+
162
+ /**
163
+ * Get current chain parameters including resource prices
164
+ */
165
+ const getChainParameters = async () => {
166
+ try {
167
+ const parameters = await tronWeb.trx.getChainParameters();
168
+ const paramMap: Record<string, number> = {};
169
+
170
+ for (const param of parameters) {
171
+ paramMap[param.key] = param.value;
172
+ }
173
+
174
+ return {
175
+ bandwidthFee: paramMap.getTransactionFee || 1000, // SUN per bandwidth unit
176
+ createAccountFee: paramMap.getCreateAccountFee || 100000, // 0.1 TRX in SUN
177
+ energyFee: paramMap.getEnergyFee || 420, // SUN per energy unit
178
+ };
179
+ } catch {
180
+ // Return default values if unable to fetch
181
+ return { bandwidthFee: 1000, createAccountFee: 100000, energyFee: 420 };
182
+ }
183
+ };
184
+
185
+ /**
186
+ * Check if an address exists on the blockchain
187
+ */
188
+ const accountExists = async (address: string) => {
189
+ try {
190
+ const account = await tronWeb.trx.getAccount(address);
191
+ return account && Object.keys(account).length > 0;
192
+ } catch {
193
+ return false;
194
+ }
195
+ };
196
+
197
+ /**
198
+ * Get account resources (bandwidth and energy)
199
+ */
200
+ const getAccountResources = async (address: string) => {
201
+ try {
202
+ const resources = await tronWeb.trx.getAccountResources(address);
203
+
204
+ return {
205
+ bandwidth: {
206
+ free: resources.freeNetLimit - resources.freeNetUsed,
207
+ total: resources.NetLimit || 0,
208
+ used: resources.NetUsed || 0,
209
+ },
210
+ energy: { total: resources.EnergyLimit || 0, used: resources.EnergyUsed || 0 },
211
+ };
212
+ } catch {
213
+ // Return default structure if unable to fetch
214
+ return {
215
+ bandwidth: { free: 600, total: 0, used: 0 }, // 600 free bandwidth daily
216
+ energy: { total: 0, used: 0 },
217
+ };
218
+ }
219
+ };
220
+
221
+ /**
222
+ * Get token balance and info directly from contract
223
+ */
224
+ const fetchTokenBalance = async (address: string, contractAddress: string) => {
225
+ try {
226
+ const contract = tronWeb.contract(trc20ABI, contractAddress);
227
+
228
+ if (!contract.methods?.balanceOf) {
229
+ return 0n;
230
+ }
231
+
232
+ const [balance] = await contract.methods.balanceOf(address).call();
233
+
234
+ return balance ? (typeof balance === "bigint" ? balance : BigInt(balance)) : 0n;
235
+ } catch (err) {
236
+ const errorMessage = err instanceof Error ? err.message : String(err);
237
+ console.warn(`balanceOf() failed for ${contractAddress}: ${errorMessage}`);
238
+ return 0n;
239
+ }
240
+ };
241
+
242
+ /**
243
+ * Get token balance and info directly from contract
244
+ */
245
+ const fetchTokenMetadata = async (contractAddress: string, address: string) => {
246
+ try {
247
+ tronWeb.setAddress(address); // Set address for contract calls
248
+ const contract = tronWeb.contract(trc20ABI, contractAddress);
249
+
250
+ const [symbolRaw, decimalsRaw] = await Promise.all([
251
+ contract
252
+ .symbol()
253
+ .call()
254
+ .catch(() => "UNKNOWN"),
255
+ contract
256
+ .decimals()
257
+ .call()
258
+ .catch(() => "18"),
259
+ ]);
260
+
261
+ return { decimals: Number(decimalsRaw ?? 18), symbol: symbolRaw ?? "UNKNOWN" };
262
+ } catch (error) {
263
+ warnOnce({
264
+ condition: true,
265
+ id: "tron_toolbox_get_token_metadata_failed",
266
+ warning: `Failed to get token metadata for ${contractAddress}: ${
267
+ error instanceof Error ? error.message : error
268
+ }`,
269
+ });
270
+ return null;
271
+ }
272
+ };
273
+
274
+ // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: TODO
275
+ const getBalance = async (address: string, _scamFilter = true) => {
276
+ const fallbackBalance = [AssetValue.from({ chain: Chain.Tron })];
277
+ // Try primary source (TronGrid)
278
+ try {
279
+ const accountData = await fetchAccountFromTronGrid(address);
280
+ if (accountData) {
281
+ const balances: AssetValue[] = [];
282
+
283
+ // Add TRX balance
284
+ balances.push(AssetValue.from({ chain: Chain.Tron, fromBaseDecimal: 6, value: accountData.balance }));
285
+
286
+ // Add TRC20 balances
287
+
288
+ for (const token of accountData.trc20) {
289
+ const [contractAddress, balance] = Object.entries(token)[0] || [];
290
+
291
+ if (!(contractAddress && balance)) continue;
292
+
293
+ const tokenMetaData = await fetchTokenMetadata(contractAddress, address);
294
+
295
+ if (!tokenMetaData) continue;
296
+
297
+ balances.push(
298
+ AssetValue.from({
299
+ asset: `TRON.${tokenMetaData.symbol}-${contractAddress}`,
300
+ fromBaseDecimal: tokenMetaData.decimals,
301
+ value: BigInt(balance || 0),
302
+ }),
303
+ );
304
+ }
305
+
306
+ return balances;
307
+ }
308
+ return fallbackBalance;
309
+ } catch (error) {
310
+ warnOnce({
311
+ condition: true,
312
+ id: "tron_toolbox_get_balance_failed",
313
+ warning: `Tron API getBalance failed: ${error instanceof Error ? error.message : error}`,
314
+ });
315
+
316
+ try {
317
+ const balances: AssetValue[] = [];
318
+
319
+ const trxBalanceInSun = await tronWeb.trx.getBalance(address);
320
+ if (trxBalanceInSun && Number(trxBalanceInSun) > 0) {
321
+ balances.push(AssetValue.from({ chain: Chain.Tron, fromBaseDecimal: 6, value: trxBalanceInSun }));
322
+ }
323
+
324
+ const usdtBalance = await fetchTokenBalance(address, TRON_USDT_CONTRACT);
325
+ if (usdtBalance) {
326
+ balances.push(
327
+ AssetValue.from({ asset: `TRON.USDT-${TRON_USDT_CONTRACT}`, fromBaseDecimal: 6, value: usdtBalance }),
328
+ );
329
+ }
330
+
331
+ if (balances.length === 0) {
332
+ return fallbackBalance;
333
+ }
334
+
335
+ return balances;
336
+ } catch (fallbackError) {
337
+ const errorMessage = fallbackError instanceof Error ? fallbackError.message : String(fallbackError);
338
+ console.error(`Tron balance fetch failed: ${errorMessage}`);
339
+ return fallbackBalance;
340
+ }
341
+ }
342
+ };
343
+
344
+ const transfer = async ({ recipient, assetValue, memo, expiration }: TronTransferParams) => {
345
+ if (!signer) throw new USwapError("toolbox_tron_no_signer");
346
+
347
+ const from = await getAddress();
348
+ tronWeb.setAddress(from);
349
+ const transaction = await createTransaction({ assetValue, expiration, memo, recipient, sender: from });
350
+
351
+ const signedTx = await signer.signTransaction(transaction);
352
+ const { txid } = await tronWeb.trx.sendRawTransaction(signedTx);
353
+
354
+ if (!txid) {
355
+ throw new USwapError("toolbox_tron_token_transfer_failed");
356
+ }
357
+
358
+ return txid;
359
+ };
360
+
361
+ const estimateTransactionFee = async ({
362
+ assetValue,
363
+ recipient,
364
+ sender,
365
+ }: // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: TODO
366
+ TronTransferParams & { sender?: string }) => {
367
+ const isNative = assetValue.isGasAsset;
368
+
369
+ try {
370
+ const senderAddress = sender ? sender : signer ? await getAddress() : undefined;
371
+ if (!senderAddress) {
372
+ return isNative
373
+ ? AssetValue.from({ chain: Chain.Tron, fromBaseDecimal: 0, value: 0.1 })
374
+ : AssetValue.from({ chain: Chain.Tron, fromBaseDecimal: 0, value: 15 });
375
+ }
376
+
377
+ const chainParams = await getChainParameters();
378
+
379
+ const recipientExists = await accountExists(recipient);
380
+ const activationFee = recipientExists ? 0 : chainParams.createAccountFee;
381
+
382
+ const resources = await getAccountResources(senderAddress);
383
+
384
+ if (isNative) {
385
+ const bandwidthNeeded = TRX_TRANSFER_BANDWIDTH;
386
+ const availableBandwidth = resources.bandwidth.free + (resources.bandwidth.total - resources.bandwidth.used);
387
+
388
+ let bandwidthFee = 0;
389
+ if (bandwidthNeeded > availableBandwidth) {
390
+ const bandwidthToBuy = bandwidthNeeded - availableBandwidth;
391
+ bandwidthFee = bandwidthToBuy * chainParams.bandwidthFee;
392
+ }
393
+
394
+ const totalFeeSun = activationFee + bandwidthFee;
395
+
396
+ return AssetValue.from({ chain: Chain.Tron, fromBaseDecimal: BaseDecimal.TRON, value: totalFeeSun });
397
+ }
398
+
399
+ const bandwidthNeeded = TRC20_TRANSFER_BANDWIDTH;
400
+ const energyNeeded = TRC20_TRANSFER_ENERGY;
401
+
402
+ const availableBandwidth = resources.bandwidth.free + (resources.bandwidth.total - resources.bandwidth.used);
403
+ const availableEnergy = resources.energy.total - resources.energy.used;
404
+
405
+ let bandwidthFee = 0;
406
+ if (bandwidthNeeded > availableBandwidth) {
407
+ const bandwidthToBuy = bandwidthNeeded - availableBandwidth;
408
+ bandwidthFee = bandwidthToBuy * chainParams.bandwidthFee;
409
+ }
410
+
411
+ let energyFee = 0;
412
+ if (energyNeeded > availableEnergy) {
413
+ const energyToBuy = energyNeeded - availableEnergy;
414
+ energyFee = energyToBuy * chainParams.energyFee;
415
+ }
416
+
417
+ const totalFeeSun = activationFee + bandwidthFee + energyFee;
418
+
419
+ return AssetValue.from({ chain: Chain.Tron, fromBaseDecimal: BaseDecimal.TRON, value: totalFeeSun });
420
+ } catch (error) {
421
+ warnOnce({
422
+ condition: true,
423
+ id: "tron_toolbox_fee_estimation_failed",
424
+ warning: `Failed to calculate exact fee, using conservative estimate: ${
425
+ error instanceof Error ? error.message : error
426
+ }`,
427
+ });
428
+
429
+ throw new USwapError("toolbox_tron_fee_estimation_failed", { error });
430
+ }
431
+ };
432
+
433
+ const createTransaction = async (params: TronCreateTransactionParams) => {
434
+ const { recipient, assetValue, memo, sender, expiration } = params;
435
+ const isNative = assetValue.isGasAsset;
436
+
437
+ const addTxData = async ({
438
+ transaction,
439
+ memo,
440
+ expiration,
441
+ }: {
442
+ transaction: TronTransaction;
443
+ memo?: string;
444
+ expiration?: number;
445
+ }) => {
446
+ const transactionWithMemo = memo
447
+ ? await tronWeb.transactionBuilder.addUpdateData(transaction, memo, "utf8")
448
+ : transaction;
449
+
450
+ const transactionFinal = expiration
451
+ ? await tronWeb.transactionBuilder.extendExpiration(transactionWithMemo, expiration)
452
+ : transactionWithMemo;
453
+
454
+ return transactionFinal;
455
+ };
456
+
457
+ if (isNative) {
458
+ const transaction = await tronWeb.transactionBuilder.sendTrx(
459
+ recipient,
460
+ assetValue.getBaseValue("number"),
461
+ sender,
462
+ );
463
+
464
+ const txWithData = addTxData({ expiration, memo, transaction });
465
+ return txWithData;
466
+ }
467
+
468
+ tronWeb.setAddress(sender);
469
+ const contractAddress = assetValue.address;
470
+ if (!contractAddress) {
471
+ throw new USwapError("toolbox_tron_invalid_token_identifier", { identifier: assetValue.toString() });
472
+ }
473
+
474
+ try {
475
+ const functionSelector = "transfer(address,uint256)";
476
+ const parameter = [
477
+ { type: "address", value: recipient },
478
+ { type: "uint256", value: assetValue.getBaseValue("string") },
479
+ ];
480
+
481
+ const options = { callValue: 0, feeLimit: calculateFeeLimit() };
482
+
483
+ const { transaction } = await tronWeb.transactionBuilder.triggerSmartContract(
484
+ contractAddress,
485
+ functionSelector,
486
+ options,
487
+ parameter,
488
+ sender,
489
+ );
490
+
491
+ const txWithData = addTxData({ expiration, memo, transaction });
492
+ return txWithData;
493
+ } catch (error) {
494
+ throw new USwapError("toolbox_tron_transaction_creation_failed", {
495
+ message: "Failed to create TRC20 transaction.",
496
+ originalError: error instanceof Error ? error.message : String(error),
497
+ });
498
+ }
499
+ };
500
+
501
+ const signTransaction = async (transaction: TronTransaction) => {
502
+ if (!signer) throw new USwapError("toolbox_tron_no_signer");
503
+ return await signer.signTransaction(transaction);
504
+ };
505
+
506
+ const broadcastTransaction = async (signedTx: TronSignedTransaction) => {
507
+ const { txid } = await tronWeb.trx.sendRawTransaction(signedTx);
508
+ return txid;
509
+ };
510
+
511
+ const getApprovedAmount = async ({ assetAddress, spenderAddress, from }: TronApprovedParams) => {
512
+ try {
513
+ const contract = tronWeb.contract(trc20ABI, assetAddress);
514
+
515
+ if (!contract.methods?.allowance) {
516
+ throw new USwapError("toolbox_tron_invalid_token_contract");
517
+ }
518
+
519
+ const [allowance] = await contract.methods.allowance(from, spenderAddress).call();
520
+
521
+ return allowance ? (typeof allowance === "bigint" ? allowance : BigInt(allowance)) : 0n;
522
+ } catch (error) {
523
+ throw new USwapError("toolbox_tron_allowance_check_failed", { error });
524
+ }
525
+ };
526
+
527
+ const isApproved = async ({ assetAddress, spenderAddress, from, amount }: TronIsApprovedParams) => {
528
+ const allowance = await getApprovedAmount({ assetAddress, from, spenderAddress });
529
+
530
+ if (!amount) {
531
+ return allowance > 0n;
532
+ }
533
+
534
+ const amountBigInt = BigInt(amount);
535
+ return allowance >= amountBigInt;
536
+ };
537
+
538
+ const approve = async ({ assetAddress, spenderAddress, amount, from }: TronApproveParams) => {
539
+ if (!signer) throw new USwapError("toolbox_tron_no_signer");
540
+
541
+ const fromAddress = from || (await getAddress());
542
+ const approvalAmount = amount !== undefined ? BigInt(amount).toString() : MAX_APPROVAL;
543
+
544
+ const functionSelector = "approve(address,uint256)";
545
+ const parameter = [
546
+ { type: "address", value: spenderAddress },
547
+ { type: "uint256", value: approvalAmount },
548
+ ];
549
+
550
+ const feeLimit = calculateFeeLimit();
551
+ const options = { callValue: 0, feeLimit };
552
+
553
+ try {
554
+ const { transaction } = await tronWeb.transactionBuilder.triggerSmartContract(
555
+ assetAddress,
556
+ functionSelector,
557
+ options,
558
+ parameter,
559
+ fromAddress,
560
+ );
561
+
562
+ const signedTx = await signer.signTransaction(transaction);
563
+ const { txid } = await tronWeb.trx.sendRawTransaction(signedTx);
564
+
565
+ if (!txid) {
566
+ throw new USwapError("toolbox_tron_approve_failed");
567
+ }
568
+
569
+ return txid;
570
+ } catch (error) {
571
+ throw new USwapError("toolbox_tron_approve_failed", { error });
572
+ }
573
+ };
574
+
575
+ return {
576
+ approve,
577
+ broadcastTransaction,
578
+ createTransaction,
579
+ estimateTransactionFee,
580
+ getAddress,
581
+ getApprovedAmount,
582
+ getBalance,
583
+ isApproved,
584
+ signTransaction,
585
+ transfer,
586
+ tronWeb,
587
+ validateAddress: await getTronAddressValidator(),
588
+ };
589
+ };
@@ -0,0 +1,83 @@
1
+ import type {
2
+ DerivationPathArray,
3
+ FeeOption,
4
+ GenericCreateTransactionParams,
5
+ GenericTransferParams,
6
+ } from "@tcswap/helpers";
7
+ import type { Contract, Types } from "tronweb";
8
+
9
+ export type TronTransaction = Types.Transaction;
10
+ export type TronContract = Contract;
11
+ export type TronSignedTransaction = Types.SignedTransaction;
12
+
13
+ export interface TronSigner {
14
+ getAddress(): Promise<string>;
15
+ signTransaction(transaction: TronTransaction): Promise<TronSignedTransaction>;
16
+ }
17
+
18
+ export type TronToolboxOptions =
19
+ | { signer?: TronSigner }
20
+ | { phrase?: string; derivationPath?: DerivationPathArray; index?: number }
21
+ | {};
22
+
23
+ export interface TronTransferParams extends GenericTransferParams {
24
+ expiration?: number;
25
+ }
26
+
27
+ export interface TronCreateTransactionParams extends Omit<GenericCreateTransactionParams, "feeRate"> {
28
+ expiration?: number;
29
+ }
30
+
31
+ export type TronApproveParams = {
32
+ assetAddress: string;
33
+ spenderAddress: string;
34
+ feeOptionKey?: FeeOption;
35
+ amount?: bigint | string | number;
36
+ from?: string;
37
+ gasLimitFallback?: bigint | string | number;
38
+ nonce?: number;
39
+ };
40
+
41
+ export type TronApprovedParams = { assetAddress: string; spenderAddress: string; from: string };
42
+
43
+ export type TronIsApprovedParams = TronApprovedParams & { amount?: bigint | string | number };
44
+
45
+ export type TronGridTRC20Balance = Array<{ [contractAddress: string]: string }>;
46
+
47
+ export interface TronGridAccountResponse {
48
+ data: Array<{
49
+ address: string;
50
+ balance: number;
51
+ create_time: number;
52
+ latest_opration_time: number;
53
+ free_net_usage: number;
54
+ net_window_size: number;
55
+ net_window_optimized: boolean;
56
+ trc20: TronGridTRC20Balance;
57
+ assetV2?: Array<{ key: string; value: number }>;
58
+ frozenV2?: Array<{ type?: string }>;
59
+ free_asset_net_usageV2?: Array<{ key: string; value: number }>;
60
+ latest_consume_free_time?: number;
61
+ owner_permission?: { keys: Array<{ address: string; weight: number }>; threshold: number; permission_name: string };
62
+ active_permission?: Array<{
63
+ operations: string;
64
+ keys: Array<{ address: string; weight: number }>;
65
+ threshold: number;
66
+ id: number;
67
+ type: string;
68
+ permission_name: string;
69
+ }>;
70
+ account_resource?: { energy_window_optimized: boolean; energy_window_size: number };
71
+ }>;
72
+ success: boolean;
73
+ meta: { at: number; page_size: number };
74
+ }
75
+
76
+ export interface TronGridTokenInfo {
77
+ symbol: string;
78
+ address: string;
79
+ decimals: number;
80
+ name: string;
81
+ totalSupply: string;
82
+ owner: string;
83
+ }
package/src/types.ts ADDED
@@ -0,0 +1,28 @@
1
+ import { type BaseWallet, Chain } from "@tcswap/helpers";
2
+ import type { CardanoWallet } from "./cardano";
3
+ import type { CosmosWallets, ThorchainWallets } from "./cosmos";
4
+ import type { EVMToolboxes } from "./evm";
5
+ import type { NearWallet } from "./near";
6
+ import type { RadixWallet } from "./radix";
7
+ import type { RippleWallet } from "./ripple";
8
+ import type { SolanaWallet } from "./solana";
9
+ import type { SubstrateToolboxes } from "./substrate";
10
+ import type { SuiWallet } from "./sui";
11
+ import type { TONWallet } from "./ton";
12
+ import type { TronWallet } from "./tron";
13
+ import type { UTXOToolboxes } from "./utxo";
14
+
15
+ type OtherWallets = {
16
+ [Chain.Radix]: RadixWallet;
17
+ [Chain.Ripple]: RippleWallet;
18
+ [Chain.Solana]: SolanaWallet;
19
+ [Chain.Ton]: TONWallet;
20
+ [Chain.Sui]: SuiWallet;
21
+ [Chain.Tron]: TronWallet;
22
+ [Chain.Near]: NearWallet;
23
+ [Chain.Cardano]: CardanoWallet;
24
+ };
25
+
26
+ export type FullWallet = BaseWallet<
27
+ EVMToolboxes & UTXOToolboxes & CosmosWallets & ThorchainWallets & SubstrateToolboxes & OtherWallets
28
+ >;