@uswap/toolboxes 4.3.6

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