@shapeshiftoss/unchained-client 10.14.10 → 10.15.0

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 (256) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +2 -2
  3. package/dist/cjs/.tsbuildinfo +1 -1
  4. package/dist/cjs/cosmossdk/thorchain/parser/__tests__/thorchain.test.js +1 -1
  5. package/dist/cjs/cosmossdk/thorchain/parser/rfox.js +1 -1
  6. package/dist/cjs/evm/arbitrum/parser/index.js +2 -2
  7. package/dist/cjs/evm/ethereum/parser/__tests__/ethereum.test.js +29 -0
  8. package/dist/cjs/evm/ethereum/parser/index.js +6 -0
  9. package/dist/cjs/generated/arbitrum/apis/V1Api.d.ts +1 -14
  10. package/dist/cjs/generated/arbitrum/apis/V1Api.js +0 -39
  11. package/dist/cjs/generated/arbitrum/models/index.d.ts +0 -3
  12. package/dist/cjs/generated/arbitrum/models/index.js +0 -3
  13. package/dist/cjs/generated/avalanche/apis/V1Api.d.ts +1 -14
  14. package/dist/cjs/generated/avalanche/apis/V1Api.js +0 -39
  15. package/dist/cjs/generated/avalanche/models/index.d.ts +0 -3
  16. package/dist/cjs/generated/avalanche/models/index.js +0 -3
  17. package/dist/cjs/generated/base/apis/V1Api.d.ts +1 -14
  18. package/dist/cjs/generated/base/apis/V1Api.js +0 -39
  19. package/dist/cjs/generated/base/models/index.d.ts +0 -3
  20. package/dist/cjs/generated/base/models/index.js +0 -3
  21. package/dist/cjs/generated/bitcoin/models/Address.d.ts +7 -0
  22. package/dist/cjs/generated/bitcoin/models/Address.js +3 -0
  23. package/dist/cjs/generated/bitcoincash/models/Address.d.ts +7 -0
  24. package/dist/cjs/generated/bitcoincash/models/Address.js +3 -0
  25. package/dist/cjs/generated/bnbsmartchain/apis/V1Api.d.ts +1 -14
  26. package/dist/cjs/generated/bnbsmartchain/apis/V1Api.js +0 -39
  27. package/dist/cjs/generated/bnbsmartchain/models/index.d.ts +0 -3
  28. package/dist/cjs/generated/bnbsmartchain/models/index.js +0 -3
  29. package/dist/cjs/generated/dogecoin/models/Address.d.ts +7 -0
  30. package/dist/cjs/generated/dogecoin/models/Address.js +3 -0
  31. package/dist/cjs/generated/ethereum/apis/V1Api.d.ts +1 -14
  32. package/dist/cjs/generated/ethereum/apis/V1Api.js +0 -39
  33. package/dist/cjs/generated/ethereum/models/index.d.ts +0 -3
  34. package/dist/cjs/generated/ethereum/models/index.js +0 -3
  35. package/dist/cjs/generated/gnosis/apis/V1Api.d.ts +1 -14
  36. package/dist/cjs/generated/gnosis/apis/V1Api.js +0 -39
  37. package/dist/cjs/generated/gnosis/models/index.d.ts +0 -3
  38. package/dist/cjs/generated/gnosis/models/index.js +0 -3
  39. package/dist/cjs/generated/litecoin/models/Address.d.ts +7 -0
  40. package/dist/cjs/generated/litecoin/models/Address.js +3 -0
  41. package/dist/cjs/generated/mayachain/apis/ProxyApi.d.ts +18 -2
  42. package/dist/cjs/generated/mayachain/apis/ProxyApi.js +42 -2
  43. package/dist/cjs/generated/mayachain/apis/V1Api.d.ts +1 -13
  44. package/dist/cjs/generated/mayachain/apis/V1Api.js +0 -27
  45. package/dist/cjs/generated/mayachain/models/index.d.ts +0 -2
  46. package/dist/cjs/generated/mayachain/models/index.js +0 -2
  47. package/dist/cjs/generated/optimism/apis/V1Api.d.ts +1 -14
  48. package/dist/cjs/generated/optimism/apis/V1Api.js +0 -39
  49. package/dist/cjs/generated/optimism/models/index.d.ts +0 -3
  50. package/dist/cjs/generated/optimism/models/index.js +0 -3
  51. package/dist/cjs/generated/polygon/apis/V1Api.d.ts +1 -14
  52. package/dist/cjs/generated/polygon/apis/V1Api.js +0 -39
  53. package/dist/cjs/generated/polygon/models/index.d.ts +0 -3
  54. package/dist/cjs/generated/polygon/models/index.js +0 -3
  55. package/dist/cjs/generated/thorchain/apis/V1Api.d.ts +1 -25
  56. package/dist/cjs/generated/thorchain/apis/V1Api.js +0 -54
  57. package/dist/cjs/generated/thorchain/models/index.d.ts +0 -3
  58. package/dist/cjs/generated/thorchain/models/index.js +0 -3
  59. package/dist/cjs/generated/zcash/models/Address.d.ts +7 -0
  60. package/dist/cjs/generated/zcash/models/Address.js +3 -0
  61. package/dist/cjs/solana/parser/__tests__/solana.test.js +5 -3
  62. package/dist/cjs/solana/parser/index.js +1 -0
  63. package/dist/cjs/solana/parser/thorchain.d.ts +9 -0
  64. package/dist/cjs/solana/parser/thorchain.js +54 -0
  65. package/dist/cjs/solana/parser/types.d.ts +4 -1
  66. package/dist/cjs/tron/__tests__/api.test.d.ts +1 -0
  67. package/dist/cjs/tron/__tests__/api.test.js +300 -0
  68. package/dist/cjs/tron/api.d.ts +38 -15
  69. package/dist/cjs/tron/api.js +241 -84
  70. package/dist/cjs/tron/types.d.ts +4 -0
  71. package/dist/esm/.tsbuildinfo +1 -1
  72. package/dist/esm/cosmossdk/thorchain/parser/__tests__/thorchain.test.js +2 -2
  73. package/dist/esm/cosmossdk/thorchain/parser/rfox.js +2 -2
  74. package/dist/esm/evm/arbitrum/parser/index.js +3 -3
  75. package/dist/esm/evm/ethereum/parser/__tests__/ethereum.test.js +29 -0
  76. package/dist/esm/evm/ethereum/parser/index.js +7 -1
  77. package/dist/esm/generated/arbitrum/apis/V1Api.d.ts +1 -14
  78. package/dist/esm/generated/arbitrum/apis/V1Api.js +1 -40
  79. package/dist/esm/generated/arbitrum/models/index.d.ts +0 -3
  80. package/dist/esm/generated/arbitrum/models/index.js +0 -3
  81. package/dist/esm/generated/avalanche/apis/V1Api.d.ts +1 -14
  82. package/dist/esm/generated/avalanche/apis/V1Api.js +1 -40
  83. package/dist/esm/generated/avalanche/models/index.d.ts +0 -3
  84. package/dist/esm/generated/avalanche/models/index.js +0 -3
  85. package/dist/esm/generated/base/apis/V1Api.d.ts +1 -14
  86. package/dist/esm/generated/base/apis/V1Api.js +1 -40
  87. package/dist/esm/generated/base/models/index.d.ts +0 -3
  88. package/dist/esm/generated/base/models/index.js +0 -3
  89. package/dist/esm/generated/bitcoin/models/Address.d.ts +7 -0
  90. package/dist/esm/generated/bitcoin/models/Address.js +3 -0
  91. package/dist/esm/generated/bitcoincash/models/Address.d.ts +7 -0
  92. package/dist/esm/generated/bitcoincash/models/Address.js +3 -0
  93. package/dist/esm/generated/bnbsmartchain/apis/V1Api.d.ts +1 -14
  94. package/dist/esm/generated/bnbsmartchain/apis/V1Api.js +1 -40
  95. package/dist/esm/generated/bnbsmartchain/models/index.d.ts +0 -3
  96. package/dist/esm/generated/bnbsmartchain/models/index.js +0 -3
  97. package/dist/esm/generated/dogecoin/models/Address.d.ts +7 -0
  98. package/dist/esm/generated/dogecoin/models/Address.js +3 -0
  99. package/dist/esm/generated/ethereum/apis/V1Api.d.ts +1 -14
  100. package/dist/esm/generated/ethereum/apis/V1Api.js +1 -40
  101. package/dist/esm/generated/ethereum/models/index.d.ts +0 -3
  102. package/dist/esm/generated/ethereum/models/index.js +0 -3
  103. package/dist/esm/generated/gnosis/apis/V1Api.d.ts +1 -14
  104. package/dist/esm/generated/gnosis/apis/V1Api.js +1 -40
  105. package/dist/esm/generated/gnosis/models/index.d.ts +0 -3
  106. package/dist/esm/generated/gnosis/models/index.js +0 -3
  107. package/dist/esm/generated/litecoin/models/Address.d.ts +7 -0
  108. package/dist/esm/generated/litecoin/models/Address.js +3 -0
  109. package/dist/esm/generated/mayachain/apis/ProxyApi.d.ts +18 -2
  110. package/dist/esm/generated/mayachain/apis/ProxyApi.js +42 -2
  111. package/dist/esm/generated/mayachain/apis/V1Api.d.ts +1 -13
  112. package/dist/esm/generated/mayachain/apis/V1Api.js +1 -28
  113. package/dist/esm/generated/mayachain/models/index.d.ts +0 -2
  114. package/dist/esm/generated/mayachain/models/index.js +0 -2
  115. package/dist/esm/generated/optimism/apis/V1Api.d.ts +1 -14
  116. package/dist/esm/generated/optimism/apis/V1Api.js +1 -40
  117. package/dist/esm/generated/optimism/models/index.d.ts +0 -3
  118. package/dist/esm/generated/optimism/models/index.js +0 -3
  119. package/dist/esm/generated/polygon/apis/V1Api.d.ts +1 -14
  120. package/dist/esm/generated/polygon/apis/V1Api.js +1 -40
  121. package/dist/esm/generated/polygon/models/index.d.ts +0 -3
  122. package/dist/esm/generated/polygon/models/index.js +0 -3
  123. package/dist/esm/generated/thorchain/apis/V1Api.d.ts +1 -25
  124. package/dist/esm/generated/thorchain/apis/V1Api.js +1 -55
  125. package/dist/esm/generated/thorchain/models/index.d.ts +0 -3
  126. package/dist/esm/generated/thorchain/models/index.js +0 -3
  127. package/dist/esm/generated/zcash/models/Address.d.ts +7 -0
  128. package/dist/esm/generated/zcash/models/Address.js +3 -0
  129. package/dist/esm/solana/parser/__tests__/solana.test.js +5 -3
  130. package/dist/esm/solana/parser/index.js +1 -0
  131. package/dist/esm/solana/parser/thorchain.d.ts +9 -0
  132. package/dist/esm/solana/parser/thorchain.js +24 -0
  133. package/dist/esm/solana/parser/types.d.ts +4 -1
  134. package/dist/esm/tron/__tests__/api.test.d.ts +1 -0
  135. package/dist/esm/tron/__tests__/api.test.js +298 -0
  136. package/dist/esm/tron/api.d.ts +38 -15
  137. package/dist/esm/tron/api.js +239 -83
  138. package/dist/esm/tron/types.d.ts +4 -0
  139. package/package.json +16 -17
  140. package/CHANGELOG.md +0 -409
  141. package/dist/cjs/generated/arbitrum/models/TokenMetadata.d.ts +0 -62
  142. package/dist/cjs/generated/arbitrum/models/TokenMetadata.js +0 -67
  143. package/dist/cjs/generated/arbitrum/models/TokenMetadataMedia.d.ts +0 -45
  144. package/dist/cjs/generated/arbitrum/models/TokenMetadataMedia.js +0 -61
  145. package/dist/cjs/generated/arbitrum/models/TokenType.d.ts +0 -23
  146. package/dist/cjs/generated/arbitrum/models/TokenType.js +0 -37
  147. package/dist/cjs/generated/avalanche/models/TokenMetadata.d.ts +0 -62
  148. package/dist/cjs/generated/avalanche/models/TokenMetadata.js +0 -67
  149. package/dist/cjs/generated/avalanche/models/TokenMetadataMedia.d.ts +0 -45
  150. package/dist/cjs/generated/avalanche/models/TokenMetadataMedia.js +0 -61
  151. package/dist/cjs/generated/avalanche/models/TokenType.d.ts +0 -23
  152. package/dist/cjs/generated/avalanche/models/TokenType.js +0 -37
  153. package/dist/cjs/generated/base/models/TokenMetadata.d.ts +0 -62
  154. package/dist/cjs/generated/base/models/TokenMetadata.js +0 -67
  155. package/dist/cjs/generated/base/models/TokenMetadataMedia.d.ts +0 -45
  156. package/dist/cjs/generated/base/models/TokenMetadataMedia.js +0 -61
  157. package/dist/cjs/generated/base/models/TokenType.d.ts +0 -23
  158. package/dist/cjs/generated/base/models/TokenType.js +0 -37
  159. package/dist/cjs/generated/bnbsmartchain/models/TokenMetadata.d.ts +0 -62
  160. package/dist/cjs/generated/bnbsmartchain/models/TokenMetadata.js +0 -67
  161. package/dist/cjs/generated/bnbsmartchain/models/TokenMetadataMedia.d.ts +0 -45
  162. package/dist/cjs/generated/bnbsmartchain/models/TokenMetadataMedia.js +0 -61
  163. package/dist/cjs/generated/bnbsmartchain/models/TokenType.d.ts +0 -23
  164. package/dist/cjs/generated/bnbsmartchain/models/TokenType.js +0 -37
  165. package/dist/cjs/generated/ethereum/models/TokenMetadata.d.ts +0 -62
  166. package/dist/cjs/generated/ethereum/models/TokenMetadata.js +0 -67
  167. package/dist/cjs/generated/ethereum/models/TokenMetadataMedia.d.ts +0 -45
  168. package/dist/cjs/generated/ethereum/models/TokenMetadataMedia.js +0 -61
  169. package/dist/cjs/generated/ethereum/models/TokenType.d.ts +0 -23
  170. package/dist/cjs/generated/ethereum/models/TokenType.js +0 -37
  171. package/dist/cjs/generated/gnosis/models/TokenMetadata.d.ts +0 -62
  172. package/dist/cjs/generated/gnosis/models/TokenMetadata.js +0 -67
  173. package/dist/cjs/generated/gnosis/models/TokenMetadataMedia.d.ts +0 -45
  174. package/dist/cjs/generated/gnosis/models/TokenMetadataMedia.js +0 -61
  175. package/dist/cjs/generated/gnosis/models/TokenType.d.ts +0 -23
  176. package/dist/cjs/generated/gnosis/models/TokenType.js +0 -37
  177. package/dist/cjs/generated/mayachain/models/AffiliateFee.d.ts +0 -67
  178. package/dist/cjs/generated/mayachain/models/AffiliateFee.js +0 -63
  179. package/dist/cjs/generated/mayachain/models/AffiliateFees.d.ts +0 -32
  180. package/dist/cjs/generated/mayachain/models/AffiliateFees.js +0 -52
  181. package/dist/cjs/generated/optimism/models/TokenMetadata.d.ts +0 -62
  182. package/dist/cjs/generated/optimism/models/TokenMetadata.js +0 -67
  183. package/dist/cjs/generated/optimism/models/TokenMetadataMedia.d.ts +0 -45
  184. package/dist/cjs/generated/optimism/models/TokenMetadataMedia.js +0 -61
  185. package/dist/cjs/generated/optimism/models/TokenType.d.ts +0 -23
  186. package/dist/cjs/generated/optimism/models/TokenType.js +0 -37
  187. package/dist/cjs/generated/polygon/models/TokenMetadata.d.ts +0 -62
  188. package/dist/cjs/generated/polygon/models/TokenMetadata.js +0 -67
  189. package/dist/cjs/generated/polygon/models/TokenMetadataMedia.d.ts +0 -45
  190. package/dist/cjs/generated/polygon/models/TokenMetadataMedia.js +0 -61
  191. package/dist/cjs/generated/polygon/models/TokenType.d.ts +0 -23
  192. package/dist/cjs/generated/polygon/models/TokenType.js +0 -37
  193. package/dist/cjs/generated/thorchain/models/AffiliateFee.d.ts +0 -67
  194. package/dist/cjs/generated/thorchain/models/AffiliateFee.js +0 -63
  195. package/dist/cjs/generated/thorchain/models/AffiliateFees.d.ts +0 -32
  196. package/dist/cjs/generated/thorchain/models/AffiliateFees.js +0 -52
  197. package/dist/cjs/generated/thorchain/models/AffiliateRevenue.d.ts +0 -45
  198. package/dist/cjs/generated/thorchain/models/AffiliateRevenue.js +0 -57
  199. package/dist/esm/generated/arbitrum/models/TokenMetadata.d.ts +0 -62
  200. package/dist/esm/generated/arbitrum/models/TokenMetadata.js +0 -60
  201. package/dist/esm/generated/arbitrum/models/TokenMetadataMedia.d.ts +0 -45
  202. package/dist/esm/generated/arbitrum/models/TokenMetadataMedia.js +0 -54
  203. package/dist/esm/generated/arbitrum/models/TokenType.d.ts +0 -23
  204. package/dist/esm/generated/arbitrum/models/TokenType.js +0 -31
  205. package/dist/esm/generated/avalanche/models/TokenMetadata.d.ts +0 -62
  206. package/dist/esm/generated/avalanche/models/TokenMetadata.js +0 -60
  207. package/dist/esm/generated/avalanche/models/TokenMetadataMedia.d.ts +0 -45
  208. package/dist/esm/generated/avalanche/models/TokenMetadataMedia.js +0 -54
  209. package/dist/esm/generated/avalanche/models/TokenType.d.ts +0 -23
  210. package/dist/esm/generated/avalanche/models/TokenType.js +0 -31
  211. package/dist/esm/generated/base/models/TokenMetadata.d.ts +0 -62
  212. package/dist/esm/generated/base/models/TokenMetadata.js +0 -60
  213. package/dist/esm/generated/base/models/TokenMetadataMedia.d.ts +0 -45
  214. package/dist/esm/generated/base/models/TokenMetadataMedia.js +0 -54
  215. package/dist/esm/generated/base/models/TokenType.d.ts +0 -23
  216. package/dist/esm/generated/base/models/TokenType.js +0 -31
  217. package/dist/esm/generated/bnbsmartchain/models/TokenMetadata.d.ts +0 -62
  218. package/dist/esm/generated/bnbsmartchain/models/TokenMetadata.js +0 -60
  219. package/dist/esm/generated/bnbsmartchain/models/TokenMetadataMedia.d.ts +0 -45
  220. package/dist/esm/generated/bnbsmartchain/models/TokenMetadataMedia.js +0 -54
  221. package/dist/esm/generated/bnbsmartchain/models/TokenType.d.ts +0 -23
  222. package/dist/esm/generated/bnbsmartchain/models/TokenType.js +0 -31
  223. package/dist/esm/generated/ethereum/models/TokenMetadata.d.ts +0 -62
  224. package/dist/esm/generated/ethereum/models/TokenMetadata.js +0 -60
  225. package/dist/esm/generated/ethereum/models/TokenMetadataMedia.d.ts +0 -45
  226. package/dist/esm/generated/ethereum/models/TokenMetadataMedia.js +0 -54
  227. package/dist/esm/generated/ethereum/models/TokenType.d.ts +0 -23
  228. package/dist/esm/generated/ethereum/models/TokenType.js +0 -31
  229. package/dist/esm/generated/gnosis/models/TokenMetadata.d.ts +0 -62
  230. package/dist/esm/generated/gnosis/models/TokenMetadata.js +0 -60
  231. package/dist/esm/generated/gnosis/models/TokenMetadataMedia.d.ts +0 -45
  232. package/dist/esm/generated/gnosis/models/TokenMetadataMedia.js +0 -54
  233. package/dist/esm/generated/gnosis/models/TokenType.d.ts +0 -23
  234. package/dist/esm/generated/gnosis/models/TokenType.js +0 -31
  235. package/dist/esm/generated/mayachain/models/AffiliateFee.d.ts +0 -67
  236. package/dist/esm/generated/mayachain/models/AffiliateFee.js +0 -56
  237. package/dist/esm/generated/mayachain/models/AffiliateFees.d.ts +0 -32
  238. package/dist/esm/generated/mayachain/models/AffiliateFees.js +0 -45
  239. package/dist/esm/generated/optimism/models/TokenMetadata.d.ts +0 -62
  240. package/dist/esm/generated/optimism/models/TokenMetadata.js +0 -60
  241. package/dist/esm/generated/optimism/models/TokenMetadataMedia.d.ts +0 -45
  242. package/dist/esm/generated/optimism/models/TokenMetadataMedia.js +0 -54
  243. package/dist/esm/generated/optimism/models/TokenType.d.ts +0 -23
  244. package/dist/esm/generated/optimism/models/TokenType.js +0 -31
  245. package/dist/esm/generated/polygon/models/TokenMetadata.d.ts +0 -62
  246. package/dist/esm/generated/polygon/models/TokenMetadata.js +0 -60
  247. package/dist/esm/generated/polygon/models/TokenMetadataMedia.d.ts +0 -45
  248. package/dist/esm/generated/polygon/models/TokenMetadataMedia.js +0 -54
  249. package/dist/esm/generated/polygon/models/TokenType.d.ts +0 -23
  250. package/dist/esm/generated/polygon/models/TokenType.js +0 -31
  251. package/dist/esm/generated/thorchain/models/AffiliateFee.d.ts +0 -67
  252. package/dist/esm/generated/thorchain/models/AffiliateFee.js +0 -56
  253. package/dist/esm/generated/thorchain/models/AffiliateFees.d.ts +0 -32
  254. package/dist/esm/generated/thorchain/models/AffiliateFees.js +0 -45
  255. package/dist/esm/generated/thorchain/models/AffiliateRevenue.d.ts +0 -45
  256. package/dist/esm/generated/thorchain/models/AffiliateRevenue.js +0 -50
@@ -1,18 +1,46 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.TronApi = void 0;
3
+ exports.TronApi = exports.getCallerEnergy = void 0;
4
4
  const tronweb_1 = require("tronweb");
5
+ const TRON_CALLER_PAYS_ALL = {
6
+ callerPercent: 100,
7
+ originEnergyLimit: 0,
8
+ originEnergyAvailable: 0,
9
+ };
10
+ // java-tron reads a stored zero, which TronGrid omits, as this creator default
11
+ const TRON_CREATOR_DEFAULT_ENERGY_LIMIT = 10_000_000;
12
+ // A deployer's unspent energy moves slowly next to how often the swappers re-estimate
13
+ const TRON_ORIGIN_ENERGY_TTL_MS = 15_000;
14
+ // A deployer can raise the caller's share after deployment, so the split is re-read within the minute
15
+ const TRON_CONTRACT_TTL_MS = 60_000;
16
+ // The deployer covers the rest only out of what they have staked, so a dry deployer (Tether) leaves the caller paying in full
17
+ const getCallerEnergy = (energyUsed, share) => {
18
+ const originShare = Math.floor((energyUsed * (100 - share.callerPercent)) / 100);
19
+ const originCovered = Math.max(0, Math.min(originShare, share.originEnergyLimit, share.originEnergyAvailable));
20
+ return energyUsed - originCovered;
21
+ };
22
+ exports.getCallerEnergy = getCallerEnergy;
5
23
  class TronApi {
6
24
  rpcUrl;
25
+ apiKey;
7
26
  tronWeb = null;
27
+ contracts = new Map();
28
+ originEnergy = new Map();
8
29
  requestQueue = Promise.resolve();
9
30
  minRequestInterval = 1_500;
10
31
  constructor(config) {
11
32
  this.rpcUrl = config.rpcUrl;
33
+ this.apiKey = config.apiKey ?? '';
12
34
  }
13
35
  getRpcUrl() {
14
36
  return this.rpcUrl;
15
37
  }
38
+ get tronGridHeaders() {
39
+ return {
40
+ 'Content-Type': 'application/json',
41
+ ...(this.apiKey ? { 'TRON-PRO-API-KEY': this.apiKey } : {}),
42
+ };
43
+ }
16
44
  async throttle() {
17
45
  // Queue the request and wait for all previous requests to complete
18
46
  const currentRequest = this.requestQueue.then(async () => {
@@ -23,7 +51,10 @@ class TronApi {
23
51
  }
24
52
  getTronWeb() {
25
53
  if (!this.tronWeb) {
26
- this.tronWeb = new tronweb_1.TronWeb({ fullHost: this.rpcUrl });
54
+ this.tronWeb = new tronweb_1.TronWeb({
55
+ fullHost: this.rpcUrl,
56
+ headers: this.apiKey ? { 'TRON-PRO-API-KEY': this.apiKey } : {},
57
+ });
27
58
  }
28
59
  return this.tronWeb;
29
60
  }
@@ -31,7 +62,7 @@ class TronApi {
31
62
  await this.throttle();
32
63
  const response = await fetch(`${this.rpcUrl}/wallet/getaccount`, {
33
64
  method: 'POST',
34
- headers: { 'Content-Type': 'application/json' },
65
+ headers: this.tronGridHeaders,
35
66
  body: JSON.stringify({ address: params.pubkey, visible: true }),
36
67
  });
37
68
  const data = await response.json();
@@ -48,7 +79,9 @@ class TronApi {
48
79
  // Get TRC20 tokens from TronGrid API
49
80
  try {
50
81
  await this.throttle();
51
- const trc20Response = await fetch(`${this.rpcUrl}/v1/accounts/${params.pubkey}`);
82
+ const trc20Response = await fetch(`${this.rpcUrl}/v1/accounts/${params.pubkey}`, {
83
+ headers: this.tronGridHeaders,
84
+ });
52
85
  const trc20Data = await trc20Response.json();
53
86
  if (trc20Data.data?.[0]?.trc20 && Array.isArray(trc20Data.data[0].trc20)) {
54
87
  // trc20 is an array of objects like [{contractAddress: balance}, ...]
@@ -61,6 +94,45 @@ class TronApi {
61
94
  }
62
95
  });
63
96
  }
97
+ else if (!trc20Data.data || trc20Data.data.length === 0) {
98
+ // Non-activated account: /v1/accounts returns data:[] for addresses that have never sent TRX.
99
+ // Fall back to discovering TRC20 balances via received transactions + hardcoded top tokens.
100
+ try {
101
+ await this.throttle();
102
+ const HARDCODED_TOP_TOKENS = [
103
+ 'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t',
104
+ 'TEkxiTehnzSmSe2XqrBj4w32RUN966rdz8', // USDC
105
+ ];
106
+ const MAX_FALLBACK_CONTRACTS = 20;
107
+ const discoveredContracts = new Set(HARDCODED_TOP_TOKENS);
108
+ const trc20TxResponse = await fetch(`${this.rpcUrl}/v1/accounts/${params.pubkey}/transactions/trc20?limit=200&only_to=true`, { headers: this.tronGridHeaders });
109
+ if (trc20TxResponse.ok) {
110
+ const trc20TxData = await trc20TxResponse.json();
111
+ if (trc20TxData.data && Array.isArray(trc20TxData.data)) {
112
+ trc20TxData.data.forEach((tx) => {
113
+ const contractAddress = tx.token_info?.address;
114
+ if (contractAddress)
115
+ discoveredContracts.add(contractAddress);
116
+ });
117
+ }
118
+ }
119
+ for (const contractAddress of Array.from(discoveredContracts).slice(0, MAX_FALLBACK_CONTRACTS)) {
120
+ await this.throttle();
121
+ await this.getTrc20Balance({ contractAddress, address: params.pubkey })
122
+ .then(balance => {
123
+ if (balance !== '0')
124
+ tokens.push({ contractAddress, balance });
125
+ })
126
+ .catch(() => undefined);
127
+ }
128
+ }
129
+ catch (fallbackErr) {
130
+ console.error('Failed TRC20 fallback discovery for non-activated TRON account', {
131
+ address: `${params.pubkey.slice(0, 6)}...${params.pubkey.slice(-4)}`,
132
+ error: fallbackErr,
133
+ });
134
+ }
135
+ }
64
136
  }
65
137
  catch (err) {
66
138
  // TRC20 fetch failed, continue with just TRC10 tokens
@@ -72,16 +144,36 @@ class TronApi {
72
144
  tokens,
73
145
  };
74
146
  }
75
- async getTRC20Balance(params) {
76
- try {
77
- const tronWeb = await this.getTronWeb();
78
- const contract = await tronWeb.contract().at(params.contractAddress);
79
- const balance = await contract.balanceOf(params.address).call();
80
- return balance.toString();
81
- }
82
- catch (_err) {
83
- return '0';
84
- }
147
+ async getTrc20Balance(params) {
148
+ const result = await this.getTronWeb().transactionBuilder.triggerConstantContract(params.contractAddress, 'balanceOf(address)', {}, [{ type: 'address', value: params.address }], params.address);
149
+ const [balance] = result.constant_result ?? [];
150
+ if (!balance)
151
+ throw new Error('[tron] balanceOf call returned no data');
152
+ return BigInt(`0x${balance}`).toString();
153
+ }
154
+ // A direct selector call - contract().at() would first fetch the ABI, doubling the requests
155
+ async getTrc20Allowance(params) {
156
+ const tronWeb = this.getTronWeb();
157
+ const result = await tronWeb.transactionBuilder.triggerConstantContract(params.contractAddress, 'allowance(address,address)', {}, [
158
+ { type: 'address', value: params.owner },
159
+ { type: 'address', value: params.spender },
160
+ ], params.owner);
161
+ const [allowance] = result.constant_result ?? [];
162
+ if (!allowance)
163
+ throw new Error('[tron] allowance call returned no data');
164
+ return BigInt(`0x${allowance}`).toString();
165
+ }
166
+ // Accounts exist on-chain only once they have received TRX; a fresh address returns {}
167
+ async isAccountActivated(address) {
168
+ const response = await fetch(`${this.rpcUrl}/wallet/getaccount`, {
169
+ method: 'POST',
170
+ headers: this.tronGridHeaders,
171
+ body: JSON.stringify({ address, visible: true }),
172
+ });
173
+ if (!response.ok)
174
+ throw new Error(`[tron] getaccount failed: ${response.status}`);
175
+ const data = await response.json();
176
+ return !!data.address;
85
177
  }
86
178
  getTxHistory(_params) {
87
179
  throw new Error('Transaction history is not supported for TRON');
@@ -91,22 +183,20 @@ class TronApi {
91
183
  const [txResponse, infoResponse] = await Promise.all([
92
184
  fetch(`${this.rpcUrl}/wallet/gettransactionbyid`, {
93
185
  method: 'POST',
94
- headers: { 'Content-Type': 'application/json' },
186
+ headers: this.tronGridHeaders,
95
187
  body: JSON.stringify({ value: params.txid, visible: true }),
96
188
  }),
97
189
  fetch(`${this.rpcUrl}/wallet/gettransactioninfobyid`, {
98
190
  method: 'POST',
99
- headers: { 'Content-Type': 'application/json' },
191
+ headers: this.tronGridHeaders,
100
192
  body: JSON.stringify({ value: params.txid, visible: true }),
101
193
  }),
102
194
  ]);
103
- if (!txResponse.ok) {
195
+ if (!txResponse.ok)
104
196
  return null;
105
- }
106
197
  const tx = await txResponse.json();
107
- if (!tx || !tx.txID) {
198
+ if (!tx || !tx.txID)
108
199
  return null;
109
- }
110
200
  let blockNumber = 0;
111
201
  let blockTimeStamp = 0;
112
202
  let fee = '0';
@@ -137,12 +227,11 @@ class TronApi {
137
227
  await this.throttle();
138
228
  const response = await fetch(`${this.rpcUrl}/wallet/getblockbynum`, {
139
229
  method: 'POST',
140
- headers: { 'Content-Type': 'application/json' },
230
+ headers: this.tronGridHeaders,
141
231
  body: JSON.stringify({ num: params.height }),
142
232
  });
143
- if (!response.ok) {
233
+ if (!response.ok)
144
234
  return null;
145
- }
146
235
  return await response.json();
147
236
  }
148
237
  async sendTx(params) {
@@ -154,9 +243,8 @@ class TronApi {
154
243
  throw new Error(result.message || JSON.stringify(result) || 'Failed to broadcast transaction');
155
244
  }
156
245
  const txid = result.txid || result.transaction?.txID;
157
- if (!txid) {
246
+ if (!txid)
158
247
  throw new Error('Transaction ID not found in broadcast result');
159
- }
160
248
  return txid;
161
249
  }
162
250
  catch (error) {
@@ -164,70 +252,139 @@ class TronApi {
164
252
  }
165
253
  }
166
254
  async getChainPrices() {
167
- try {
168
- const tronWeb = await this.getTronWeb();
169
- const params = await tronWeb.trx.getChainParameters();
170
- const bandwidthPrice = params.find(p => p.key === 'getTransactionFee')?.value ?? 1000;
171
- const energyPrice = params.find(p => p.key === 'getEnergyFee')?.value ?? 420;
172
- return { bandwidthPrice, energyPrice };
173
- }
174
- catch (_err) {
175
- return { bandwidthPrice: 1000, energyPrice: 420 };
176
- }
255
+ const params = await this.getTronWeb().trx.getChainParameters();
256
+ const param = (key) => {
257
+ const value = params.find(p => p.key === key)?.value;
258
+ if (value === undefined)
259
+ throw new Error(`[tron] chain parameter ${key} missing`);
260
+ return value;
261
+ };
262
+ return {
263
+ bandwidthPrice: param('getTransactionFee'),
264
+ energyPrice: param('getEnergyFee'),
265
+ memoFee: param('getMemoFee'),
266
+ };
177
267
  }
178
- async estimateFees(params) {
179
- try {
180
- const { bandwidthPrice } = await this.getChainPrices();
181
- const rawDataBytes = Buffer.from(params.estimateFeesBody.serializedTx, 'hex').length;
182
- const signatureBytes = 65;
183
- const totalBytes = rawDataBytes + signatureBytes;
184
- const feeInSun = totalBytes * bandwidthPrice;
185
- return String(feeInSun);
186
- }
187
- catch (err) {
188
- throw new Error(`Failed to estimate fees: ${err}`);
189
- }
268
+ // A plain address answers getcontract with {} and pays in full
269
+ async getContractEnergyShare(contractAddress) {
270
+ const contract = await this.getContract(contractAddress);
271
+ if (!contract.origin_address)
272
+ return TRON_CALLER_PAYS_ALL;
273
+ // TronGrid omits zero-valued fields, so a contract whose deployer pays everything carries no percent at all
274
+ const callerPercent = contract.consume_user_resource_percent ?? 0;
275
+ if (callerPercent >= 100)
276
+ return TRON_CALLER_PAYS_ALL;
277
+ return {
278
+ callerPercent,
279
+ originEnergyLimit: contract.origin_energy_limit || TRON_CREATOR_DEFAULT_ENERGY_LIMIT,
280
+ originEnergyAvailable: await this.getOriginEnergyAvailable(contract.origin_address),
281
+ };
190
282
  }
191
- async estimateTRC20TransferFee(params) {
192
- try {
193
- const tronWeb = await this.getTronWeb();
194
- const { energyPrice } = await this.getChainPrices();
195
- const result = await tronWeb.transactionBuilder.triggerConstantContract(params.contractAddress, 'transfer(address,uint256)', {}, [
196
- { type: 'address', value: params.to },
197
- { type: 'uint256', value: params.amount },
198
- ], params.from);
199
- const energyUsed = result.energy_used ?? 0;
200
- const feeInSun = energyUsed * energyPrice;
201
- return String(feeInSun);
202
- }
203
- catch (_err) {
204
- // Fallback: Worst case 130k energy at current 100 sun/energy
205
- return '13000000'; // 13 TRX (more realistic than 31 TRX)
206
- }
283
+ getContract(contractAddress) {
284
+ const cached = this.contracts.get(contractAddress);
285
+ if (cached && Date.now() - cached.readAt < TRON_CONTRACT_TTL_MS)
286
+ return cached.value;
287
+ const value = this.post('/wallet/getcontract', {
288
+ value: contractAddress,
289
+ visible: true,
290
+ })
291
+ .then(body => {
292
+ if (body.Error)
293
+ throw new Error(`[tron] getcontract failed: ${body.Error}`);
294
+ // only a contract record is worth keeping; an empty body is re-read next time
295
+ if (!body.origin_address && this.contracts.get(contractAddress)?.value === value) {
296
+ this.contracts.delete(contractAddress);
297
+ }
298
+ return body;
299
+ })
300
+ .catch(err => {
301
+ if (this.contracts.get(contractAddress)?.value === value) {
302
+ this.contracts.delete(contractAddress);
303
+ }
304
+ throw err;
305
+ });
306
+ this.contracts.set(contractAddress, { readAt: Date.now(), value });
307
+ return value;
207
308
  }
208
- async getPriorityFees() {
209
- try {
210
- const { bandwidthPrice } = await this.getChainPrices();
211
- const estimatedBytes = 268;
212
- const baseFee = String(estimatedBytes * bandwidthPrice);
213
- return {
214
- baseFee,
215
- fast: baseFee,
216
- average: baseFee,
217
- slow: baseFee,
218
- estimatedBandwidth: String(estimatedBytes),
219
- };
309
+ // A failed share lookup prices the simulation as if the caller paid in full, unless the caller must not guess
310
+ async getPricingContext(contractAddress, requireEnergyShare = false) {
311
+ const [{ energyPrice }, share] = await Promise.all([
312
+ this.getChainPrices(),
313
+ this.getContractEnergyShare(contractAddress).catch((error) => {
314
+ if (requireEnergyShare)
315
+ throw error;
316
+ console.warn(`[tron] energy share lookup failed for ${contractAddress}, pricing in full`, error);
317
+ return TRON_CALLER_PAYS_ALL;
318
+ }),
319
+ ]);
320
+ return { energyPrice, share };
321
+ }
322
+ getOriginEnergyAvailable(originAddress) {
323
+ const cached = this.originEnergy.get(originAddress);
324
+ if (cached && Date.now() - cached.readAt < TRON_ORIGIN_ENERGY_TTL_MS)
325
+ return cached.value;
326
+ const value = this.post('/wallet/getaccountresource', { address: originAddress, visible: true })
327
+ .then(body => {
328
+ if (body.Error)
329
+ throw new Error(`[tron] getaccountresource failed: ${body.Error}`);
330
+ return Math.max(0, (body.EnergyLimit ?? 0) - (body.EnergyUsed ?? 0));
331
+ })
332
+ .catch(err => {
333
+ if (this.originEnergy.get(originAddress)?.value === value) {
334
+ this.originEnergy.delete(originAddress);
335
+ }
336
+ throw err;
337
+ });
338
+ this.originEnergy.set(originAddress, { readAt: Date.now(), value });
339
+ return value;
340
+ }
341
+ async post(path, body) {
342
+ const response = await fetch(`${this.rpcUrl}${path}`, {
343
+ method: 'POST',
344
+ headers: this.tronGridHeaders,
345
+ body: JSON.stringify(body),
346
+ });
347
+ if (!response.ok)
348
+ throw new Error(`[tron] ${path} failed: ${response.status}`);
349
+ return response.json();
350
+ }
351
+ async estimateTrc20TransferFee(params) {
352
+ const tronWeb = this.getTronWeb();
353
+ const { energyPrice, share } = await this.getPricingContext(params.contractAddress, params.requireEnergyShare);
354
+ const result = await tronWeb.transactionBuilder.triggerConstantContract(params.contractAddress, 'transfer(address,uint256)', {}, [
355
+ { type: 'address', value: params.to },
356
+ { type: 'uint256', value: params.amount },
357
+ ], params.from);
358
+ const energy = this.getSimulatedEnergy(result, 'trc20 transfer');
359
+ return String((0, exports.getCallerEnergy)(energy, share) * energyPrice);
360
+ }
361
+ async estimateContractCallFee(params) {
362
+ const { energyPrice, share } = await this.getPricingContext(params.contractAddress, params.requireEnergyShare);
363
+ const response = await fetch(`${this.rpcUrl}/wallet/triggerconstantcontract`, {
364
+ method: 'POST',
365
+ headers: { 'Content-Type': 'application/json', ...this.tronGridHeaders },
366
+ body: JSON.stringify({
367
+ owner_address: params.from,
368
+ contract_address: params.contractAddress,
369
+ data: params.data.startsWith('0x') ? params.data.slice(2) : params.data,
370
+ call_value: Number(params.callValue) || 0,
371
+ visible: true,
372
+ }),
373
+ });
374
+ if (!response.ok) {
375
+ throw new Error(`[tron] contract call simulation request failed: ${response.status}`);
220
376
  }
221
- catch (_err) {
222
- const defaultFee = '268000';
223
- return {
224
- baseFee: defaultFee,
225
- fast: defaultFee,
226
- average: defaultFee,
227
- slow: defaultFee,
228
- estimatedBandwidth: '268',
229
- };
377
+ const result = await response.json();
378
+ const energy = this.getSimulatedEnergy(result, 'contract call');
379
+ return String((0, exports.getCallerEnergy)(energy, share) * energyPrice);
380
+ }
381
+ // A revert still reports result.result: true with the partial energy burned - trusting it would underestimate
382
+ getSimulatedEnergy(result, label) {
383
+ const isReverted = result.transaction?.ret?.some(ret => ret.ret === 'FAILED');
384
+ if (result.result?.result !== true || isReverted || !result.energy_used) {
385
+ throw new Error(`[tron] ${label} simulation failed: ${result.result?.message ?? 'unknown error'}`);
230
386
  }
387
+ return result.energy_used;
231
388
  }
232
389
  }
233
390
  exports.TronApi = TronApi;
@@ -29,6 +29,9 @@ export interface TronTx {
29
29
  amount?: number;
30
30
  owner_address?: string;
31
31
  to_address?: string;
32
+ contract_address?: string;
33
+ call_value?: number;
34
+ data?: string;
32
35
  };
33
36
  type_url: string;
34
37
  };
@@ -38,6 +41,7 @@ export interface TronTx {
38
41
  ref_block_hash: string;
39
42
  expiration: number;
40
43
  timestamp: number;
44
+ fee_limit?: number;
41
45
  };
42
46
  raw_data_hex: string;
43
47
  txID: string;