@ledgerhq/coin-tron 0.0.1

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 (351) hide show
  1. package/.eslintrc.js +20 -0
  2. package/.turbo/turbo-build.log +4 -0
  3. package/.unimportedrc.json +25 -0
  4. package/LICENSE.txt +21 -0
  5. package/jest.config.js +8 -0
  6. package/jest.integ.config.js +7 -0
  7. package/lib/bridge/broadcast.d.ts +7 -0
  8. package/lib/bridge/broadcast.d.ts.map +1 -0
  9. package/lib/bridge/broadcast.js +26 -0
  10. package/lib/bridge/broadcast.js.map +1 -0
  11. package/lib/bridge/buildOptimisticOperation.d.ts +5 -0
  12. package/lib/bridge/buildOptimisticOperation.d.ts.map +1 -0
  13. package/lib/bridge/buildOptimisticOperation.js +101 -0
  14. package/lib/bridge/buildOptimisticOperation.js.map +1 -0
  15. package/lib/bridge/createTransaction.d.ts +4 -0
  16. package/lib/bridge/createTransaction.d.ts.map +1 -0
  17. package/lib/bridge/createTransaction.js +19 -0
  18. package/lib/bridge/createTransaction.js.map +1 -0
  19. package/lib/bridge/deviceTransactionConfig.d.ts +20 -0
  20. package/lib/bridge/deviceTransactionConfig.d.ts.map +1 -0
  21. package/lib/bridge/deviceTransactionConfig.js +65 -0
  22. package/lib/bridge/deviceTransactionConfig.js.map +1 -0
  23. package/lib/bridge/estimateMaxSpendable.d.ts +5 -0
  24. package/lib/bridge/estimateMaxSpendable.d.ts.map +1 -0
  25. package/lib/bridge/estimateMaxSpendable.js +30 -0
  26. package/lib/bridge/estimateMaxSpendable.js.map +1 -0
  27. package/lib/bridge/getEstimateFees.d.ts +6 -0
  28. package/lib/bridge/getEstimateFees.d.ts.map +1 -0
  29. package/lib/bridge/getEstimateFees.js +52 -0
  30. package/lib/bridge/getEstimateFees.js.map +1 -0
  31. package/lib/bridge/getTransactionStatus.d.ts +4 -0
  32. package/lib/bridge/getTransactionStatus.d.ts.map +1 -0
  33. package/lib/bridge/getTransactionStatus.js +218 -0
  34. package/lib/bridge/getTransactionStatus.js.map +1 -0
  35. package/lib/bridge/index.d.ts +10 -0
  36. package/lib/bridge/index.d.ts.map +1 -0
  37. package/lib/bridge/index.js +60 -0
  38. package/lib/bridge/index.js.map +1 -0
  39. package/lib/bridge/preload.d.ts +8 -0
  40. package/lib/bridge/preload.d.ts.map +1 -0
  41. package/lib/bridge/preload.js +32 -0
  42. package/lib/bridge/preload.js.map +1 -0
  43. package/lib/bridge/prepareTransaction.d.ts +4 -0
  44. package/lib/bridge/prepareTransaction.d.ts.map +1 -0
  45. package/lib/bridge/prepareTransaction.js +19 -0
  46. package/lib/bridge/prepareTransaction.js.map +1 -0
  47. package/lib/bridge/serialization.d.ts +9 -0
  48. package/lib/bridge/serialization.d.ts.map +1 -0
  49. package/lib/bridge/serialization.js +238 -0
  50. package/lib/bridge/serialization.js.map +1 -0
  51. package/lib/bridge/signOperation.d.ts +5 -0
  52. package/lib/bridge/signOperation.d.ts.map +1 -0
  53. package/lib/bridge/signOperation.js +92 -0
  54. package/lib/bridge/signOperation.js.map +1 -0
  55. package/lib/bridge/synchronization.d.ts +5 -0
  56. package/lib/bridge/synchronization.d.ts.map +1 -0
  57. package/lib/bridge/synchronization.integ.test.d.ts +3 -0
  58. package/lib/bridge/synchronization.integ.test.d.ts.map +1 -0
  59. package/lib/bridge/synchronization.integ.test.js +96 -0
  60. package/lib/bridge/synchronization.integ.test.js.map +1 -0
  61. package/lib/bridge/synchronization.js +216 -0
  62. package/lib/bridge/synchronization.js.map +1 -0
  63. package/lib/bridge/transaction.d.ts +15 -0
  64. package/lib/bridge/transaction.d.ts.map +1 -0
  65. package/lib/bridge/transaction.js +61 -0
  66. package/lib/bridge/transaction.js.map +1 -0
  67. package/lib/config.d.ts +10 -0
  68. package/lib/config.d.ts.map +1 -0
  69. package/lib/config.js +17 -0
  70. package/lib/config.js.map +1 -0
  71. package/lib/index.d.ts +3 -0
  72. package/lib/index.d.ts.map +1 -0
  73. package/lib/index.js +21 -0
  74. package/lib/index.js.map +1 -0
  75. package/lib/logic/constants.d.ts +4 -0
  76. package/lib/logic/constants.d.ts.map +1 -0
  77. package/lib/logic/constants.js +7 -0
  78. package/lib/logic/constants.js.map +1 -0
  79. package/lib/logic/pagination.d.ts +3 -0
  80. package/lib/logic/pagination.d.ts.map +1 -0
  81. package/lib/logic/pagination.js +19 -0
  82. package/lib/logic/pagination.js.map +1 -0
  83. package/lib/logic/utils.d.ts +12 -0
  84. package/lib/logic/utils.d.ts.map +1 -0
  85. package/lib/logic/utils.js +177 -0
  86. package/lib/logic/utils.js.map +1 -0
  87. package/lib/network/format.d.ts +9 -0
  88. package/lib/network/format.d.ts.map +1 -0
  89. package/lib/network/format.js +127 -0
  90. package/lib/network/format.js.map +1 -0
  91. package/lib/network/index.d.ts +30 -0
  92. package/lib/network/index.d.ts.map +1 -0
  93. package/lib/network/index.integ.test.d.ts +2 -0
  94. package/lib/network/index.integ.test.d.ts.map +1 -0
  95. package/lib/network/index.integ.test.js +38 -0
  96. package/lib/network/index.integ.test.js.map +1 -0
  97. package/lib/network/index.js +555 -0
  98. package/lib/network/index.js.map +1 -0
  99. package/lib/network/index.test.d.ts +2 -0
  100. package/lib/network/index.test.d.ts.map +1 -0
  101. package/lib/network/index.test.js +66 -0
  102. package/lib/network/index.test.js.map +1 -0
  103. package/lib/network/superRepresentativesData.mock.d.ts +69 -0
  104. package/lib/network/superRepresentativesData.mock.d.ts.map +1 -0
  105. package/lib/network/superRepresentativesData.mock.js +2208 -0
  106. package/lib/network/superRepresentativesData.mock.js.map +1 -0
  107. package/lib/network/types.d.ts +122 -0
  108. package/lib/network/types.d.ts.map +1 -0
  109. package/lib/network/types.fixture.d.ts +498 -0
  110. package/lib/network/types.fixture.d.ts.map +1 -0
  111. package/lib/network/types.fixture.js +4375 -0
  112. package/lib/network/types.fixture.js.map +1 -0
  113. package/lib/network/types.js +13 -0
  114. package/lib/network/types.js.map +1 -0
  115. package/lib/signer/getAddress.d.ts +6 -0
  116. package/lib/signer/getAddress.d.ts.map +1 -0
  117. package/lib/signer/getAddress.js +19 -0
  118. package/lib/signer/getAddress.js.map +1 -0
  119. package/lib/signer/index.d.ts +6 -0
  120. package/lib/signer/index.d.ts.map +1 -0
  121. package/lib/signer/index.js +11 -0
  122. package/lib/signer/index.js.map +1 -0
  123. package/lib/test/bot-deviceActions.d.ts +4 -0
  124. package/lib/test/bot-deviceActions.d.ts.map +1 -0
  125. package/lib/test/bot-deviceActions.js +103 -0
  126. package/lib/test/bot-deviceActions.js.map +1 -0
  127. package/lib/test/bot-specs.d.ts +7 -0
  128. package/lib/test/bot-specs.d.ts.map +1 -0
  129. package/lib/test/bot-specs.js +433 -0
  130. package/lib/test/bot-specs.js.map +1 -0
  131. package/lib/test/bridgeDatasetTest.d.ts +4 -0
  132. package/lib/test/bridgeDatasetTest.d.ts.map +1 -0
  133. package/lib/test/bridgeDatasetTest.js +1284 -0
  134. package/lib/test/bridgeDatasetTest.js.map +1 -0
  135. package/lib/test/cli.d.ts +52 -0
  136. package/lib/test/cli.d.ts.map +1 -0
  137. package/lib/test/cli.js +155 -0
  138. package/lib/test/cli.js.map +1 -0
  139. package/lib/test/index.d.ts +6 -0
  140. package/lib/test/index.d.ts.map +1 -0
  141. package/lib/test/index.js +26 -0
  142. package/lib/test/index.js.map +1 -0
  143. package/lib/types/bridge.d.ts +245 -0
  144. package/lib/types/bridge.d.ts.map +1 -0
  145. package/lib/types/bridge.js +16 -0
  146. package/lib/types/bridge.js.map +1 -0
  147. package/lib/types/errors.d.ts +49 -0
  148. package/lib/types/errors.d.ts.map +1 -0
  149. package/lib/types/errors.js +21 -0
  150. package/lib/types/errors.js.map +1 -0
  151. package/lib/types/index.d.ts +4 -0
  152. package/lib/types/index.d.ts.map +1 -0
  153. package/lib/types/index.js +21 -0
  154. package/lib/types/index.js.map +1 -0
  155. package/lib/types/signer.d.ts +10 -0
  156. package/lib/types/signer.d.ts.map +1 -0
  157. package/lib/types/signer.js +3 -0
  158. package/lib/types/signer.js.map +1 -0
  159. package/lib-es/bridge/broadcast.d.ts +7 -0
  160. package/lib-es/bridge/broadcast.d.ts.map +1 -0
  161. package/lib-es/bridge/broadcast.js +24 -0
  162. package/lib-es/bridge/broadcast.js.map +1 -0
  163. package/lib-es/bridge/buildOptimisticOperation.d.ts +5 -0
  164. package/lib-es/bridge/buildOptimisticOperation.d.ts.map +1 -0
  165. package/lib-es/bridge/buildOptimisticOperation.js +94 -0
  166. package/lib-es/bridge/buildOptimisticOperation.js.map +1 -0
  167. package/lib-es/bridge/createTransaction.d.ts +4 -0
  168. package/lib-es/bridge/createTransaction.d.ts.map +1 -0
  169. package/lib-es/bridge/createTransaction.js +14 -0
  170. package/lib-es/bridge/createTransaction.js.map +1 -0
  171. package/lib-es/bridge/deviceTransactionConfig.d.ts +20 -0
  172. package/lib-es/bridge/deviceTransactionConfig.d.ts.map +1 -0
  173. package/lib-es/bridge/deviceTransactionConfig.js +63 -0
  174. package/lib-es/bridge/deviceTransactionConfig.js.map +1 -0
  175. package/lib-es/bridge/estimateMaxSpendable.d.ts +5 -0
  176. package/lib-es/bridge/estimateMaxSpendable.d.ts.map +1 -0
  177. package/lib-es/bridge/estimateMaxSpendable.js +25 -0
  178. package/lib-es/bridge/estimateMaxSpendable.js.map +1 -0
  179. package/lib-es/bridge/getEstimateFees.d.ts +6 -0
  180. package/lib-es/bridge/getEstimateFees.d.ts.map +1 -0
  181. package/lib-es/bridge/getEstimateFees.js +47 -0
  182. package/lib-es/bridge/getEstimateFees.js.map +1 -0
  183. package/lib-es/bridge/getTransactionStatus.d.ts +4 -0
  184. package/lib-es/bridge/getTransactionStatus.d.ts.map +1 -0
  185. package/lib-es/bridge/getTransactionStatus.js +213 -0
  186. package/lib-es/bridge/getTransactionStatus.js.map +1 -0
  187. package/lib-es/bridge/index.d.ts +10 -0
  188. package/lib-es/bridge/index.d.ts.map +1 -0
  189. package/lib-es/bridge/index.js +53 -0
  190. package/lib-es/bridge/index.js.map +1 -0
  191. package/lib-es/bridge/preload.d.ts +8 -0
  192. package/lib-es/bridge/preload.d.ts.map +1 -0
  193. package/lib-es/bridge/preload.js +27 -0
  194. package/lib-es/bridge/preload.js.map +1 -0
  195. package/lib-es/bridge/prepareTransaction.d.ts +4 -0
  196. package/lib-es/bridge/prepareTransaction.d.ts.map +1 -0
  197. package/lib-es/bridge/prepareTransaction.js +15 -0
  198. package/lib-es/bridge/prepareTransaction.js.map +1 -0
  199. package/lib-es/bridge/serialization.d.ts +9 -0
  200. package/lib-es/bridge/serialization.d.ts.map +1 -0
  201. package/lib-es/bridge/serialization.js +229 -0
  202. package/lib-es/bridge/serialization.js.map +1 -0
  203. package/lib-es/bridge/signOperation.d.ts +5 -0
  204. package/lib-es/bridge/signOperation.d.ts.map +1 -0
  205. package/lib-es/bridge/signOperation.js +85 -0
  206. package/lib-es/bridge/signOperation.js.map +1 -0
  207. package/lib-es/bridge/synchronization.d.ts +5 -0
  208. package/lib-es/bridge/synchronization.d.ts.map +1 -0
  209. package/lib-es/bridge/synchronization.integ.test.d.ts +3 -0
  210. package/lib-es/bridge/synchronization.integ.test.d.ts.map +1 -0
  211. package/lib-es/bridge/synchronization.integ.test.js +89 -0
  212. package/lib-es/bridge/synchronization.integ.test.js.map +1 -0
  213. package/lib-es/bridge/synchronization.js +209 -0
  214. package/lib-es/bridge/synchronization.js.map +1 -0
  215. package/lib-es/bridge/transaction.d.ts +15 -0
  216. package/lib-es/bridge/transaction.d.ts.map +1 -0
  217. package/lib-es/bridge/transaction.js +55 -0
  218. package/lib-es/bridge/transaction.js.map +1 -0
  219. package/lib-es/config.d.ts +10 -0
  220. package/lib-es/config.d.ts.map +1 -0
  221. package/lib-es/config.js +12 -0
  222. package/lib-es/config.js.map +1 -0
  223. package/lib-es/index.d.ts +3 -0
  224. package/lib-es/index.d.ts.map +1 -0
  225. package/lib-es/index.js +3 -0
  226. package/lib-es/index.js.map +1 -0
  227. package/lib-es/logic/constants.d.ts +4 -0
  228. package/lib-es/logic/constants.d.ts.map +1 -0
  229. package/lib-es/logic/constants.js +4 -0
  230. package/lib-es/logic/constants.js.map +1 -0
  231. package/lib-es/logic/pagination.d.ts +3 -0
  232. package/lib-es/logic/pagination.d.ts.map +1 -0
  233. package/lib-es/logic/pagination.js +15 -0
  234. package/lib-es/logic/pagination.js.map +1 -0
  235. package/lib-es/logic/utils.d.ts +12 -0
  236. package/lib-es/logic/utils.d.ts.map +1 -0
  237. package/lib-es/logic/utils.js +167 -0
  238. package/lib-es/logic/utils.js.map +1 -0
  239. package/lib-es/network/format.d.ts +9 -0
  240. package/lib-es/network/format.d.ts.map +1 -0
  241. package/lib-es/network/format.js +117 -0
  242. package/lib-es/network/format.js.map +1 -0
  243. package/lib-es/network/index.d.ts +30 -0
  244. package/lib-es/network/index.d.ts.map +1 -0
  245. package/lib-es/network/index.integ.test.d.ts +2 -0
  246. package/lib-es/network/index.integ.test.d.ts.map +1 -0
  247. package/lib-es/network/index.integ.test.js +36 -0
  248. package/lib-es/network/index.integ.test.js.map +1 -0
  249. package/lib-es/network/index.js +524 -0
  250. package/lib-es/network/index.js.map +1 -0
  251. package/lib-es/network/index.test.d.ts +2 -0
  252. package/lib-es/network/index.test.d.ts.map +1 -0
  253. package/lib-es/network/index.test.js +63 -0
  254. package/lib-es/network/index.test.js.map +1 -0
  255. package/lib-es/network/superRepresentativesData.mock.d.ts +69 -0
  256. package/lib-es/network/superRepresentativesData.mock.d.ts.map +1 -0
  257. package/lib-es/network/superRepresentativesData.mock.js +2206 -0
  258. package/lib-es/network/superRepresentativesData.mock.js.map +1 -0
  259. package/lib-es/network/types.d.ts +122 -0
  260. package/lib-es/network/types.d.ts.map +1 -0
  261. package/lib-es/network/types.fixture.d.ts +498 -0
  262. package/lib-es/network/types.fixture.d.ts.map +1 -0
  263. package/lib-es/network/types.fixture.js +4371 -0
  264. package/lib-es/network/types.fixture.js.map +1 -0
  265. package/lib-es/network/types.js +8 -0
  266. package/lib-es/network/types.js.map +1 -0
  267. package/lib-es/signer/getAddress.d.ts +6 -0
  268. package/lib-es/signer/getAddress.d.ts.map +1 -0
  269. package/lib-es/signer/getAddress.js +17 -0
  270. package/lib-es/signer/getAddress.js.map +1 -0
  271. package/lib-es/signer/index.d.ts +6 -0
  272. package/lib-es/signer/index.d.ts.map +1 -0
  273. package/lib-es/signer/index.js +6 -0
  274. package/lib-es/signer/index.js.map +1 -0
  275. package/lib-es/test/bot-deviceActions.d.ts +4 -0
  276. package/lib-es/test/bot-deviceActions.d.ts.map +1 -0
  277. package/lib-es/test/bot-deviceActions.js +100 -0
  278. package/lib-es/test/bot-deviceActions.js.map +1 -0
  279. package/lib-es/test/bot-specs.d.ts +7 -0
  280. package/lib-es/test/bot-specs.d.ts.map +1 -0
  281. package/lib-es/test/bot-specs.js +428 -0
  282. package/lib-es/test/bot-specs.js.map +1 -0
  283. package/lib-es/test/bridgeDatasetTest.d.ts +4 -0
  284. package/lib-es/test/bridgeDatasetTest.d.ts.map +1 -0
  285. package/lib-es/test/bridgeDatasetTest.js +1278 -0
  286. package/lib-es/test/bridgeDatasetTest.js.map +1 -0
  287. package/lib-es/test/cli.d.ts +52 -0
  288. package/lib-es/test/cli.d.ts.map +1 -0
  289. package/lib-es/test/cli.js +149 -0
  290. package/lib-es/test/cli.js.map +1 -0
  291. package/lib-es/test/index.d.ts +6 -0
  292. package/lib-es/test/index.d.ts.map +1 -0
  293. package/lib-es/test/index.js +6 -0
  294. package/lib-es/test/index.js.map +1 -0
  295. package/lib-es/types/bridge.d.ts +245 -0
  296. package/lib-es/types/bridge.d.ts.map +1 -0
  297. package/lib-es/types/bridge.js +11 -0
  298. package/lib-es/types/bridge.js.map +1 -0
  299. package/lib-es/types/errors.d.ts +49 -0
  300. package/lib-es/types/errors.d.ts.map +1 -0
  301. package/lib-es/types/errors.js +18 -0
  302. package/lib-es/types/errors.js.map +1 -0
  303. package/lib-es/types/index.d.ts +4 -0
  304. package/lib-es/types/index.d.ts.map +1 -0
  305. package/lib-es/types/index.js +5 -0
  306. package/lib-es/types/index.js.map +1 -0
  307. package/lib-es/types/signer.d.ts +10 -0
  308. package/lib-es/types/signer.d.ts.map +1 -0
  309. package/lib-es/types/signer.js +2 -0
  310. package/lib-es/types/signer.js.map +1 -0
  311. package/package.json +133 -0
  312. package/src/bridge/broadcast.ts +24 -0
  313. package/src/bridge/buildOptimisticOperation.ts +133 -0
  314. package/src/bridge/createTransaction.ts +16 -0
  315. package/src/bridge/deviceTransactionConfig.ts +99 -0
  316. package/src/bridge/estimateMaxSpendable.ts +32 -0
  317. package/src/bridge/getEstimateFees.ts +52 -0
  318. package/src/bridge/getTransactionStatus.ts +263 -0
  319. package/src/bridge/index.ts +78 -0
  320. package/src/bridge/preload.ts +24 -0
  321. package/src/bridge/prepareTransaction.ts +12 -0
  322. package/src/bridge/serialization.ts +288 -0
  323. package/src/bridge/signOperation.ts +123 -0
  324. package/src/bridge/synchronization.integ.test.ts +105 -0
  325. package/src/bridge/synchronization.ts +284 -0
  326. package/src/bridge/transaction.ts +84 -0
  327. package/src/config.ts +24 -0
  328. package/src/index.ts +3 -0
  329. package/src/logic/constants.ts +4 -0
  330. package/src/logic/pagination.ts +21 -0
  331. package/src/logic/utils.ts +231 -0
  332. package/src/network/format.ts +148 -0
  333. package/src/network/index.integ.test.ts +33 -0
  334. package/src/network/index.test.ts +61 -0
  335. package/src/network/index.ts +747 -0
  336. package/src/network/superRepresentativesData.mock.ts +2205 -0
  337. package/src/network/types.fixture.ts +4476 -0
  338. package/src/network/types.ts +147 -0
  339. package/src/signer/getAddress.ts +13 -0
  340. package/src/signer/index.ts +7 -0
  341. package/src/test/bot-deviceActions.ts +121 -0
  342. package/src/test/bot-specs.ts +457 -0
  343. package/src/test/bridgeDatasetTest.ts +1343 -0
  344. package/src/test/cli.ts +219 -0
  345. package/src/test/index.ts +6 -0
  346. package/src/types/bridge.ts +304 -0
  347. package/src/types/errors.ts +22 -0
  348. package/src/types/index.ts +4 -0
  349. package/src/types/signer.ts +9 -0
  350. package/tsconfig.json +14 -0
  351. package/types/tronweb/index.d.ts +5 -0
@@ -0,0 +1,123 @@
1
+ import { SignerContext } from "@ledgerhq/coin-framework/signer";
2
+ import { SignOperationEvent, SignOperationFnSignature, TokenAccount } from "@ledgerhq/types-live";
3
+ import BigNumber from "bignumber.js";
4
+ import { Observable } from "rxjs";
5
+ import {
6
+ claimRewardTronTransaction,
7
+ createTronTransaction,
8
+ fetchTronContract,
9
+ freezeTronTransaction,
10
+ legacyUnfreezeTronTransaction,
11
+ unDelegateResourceTransaction,
12
+ unfreezeTronTransaction,
13
+ voteTronSuperRepresentatives,
14
+ withdrawExpireUnfreezeTronTransaction,
15
+ } from "../network";
16
+ import { Transaction, TronAccount, TronSigner } from "../types";
17
+ import { buildOptimisticOperation } from "./buildOptimisticOperation";
18
+ import getEstimatedFees from "./getEstimateFees";
19
+
20
+ export const buildSignOperation =
21
+ (signerContext: SignerContext<TronSigner>): SignOperationFnSignature<Transaction, TronAccount> =>
22
+ ({ account, transaction, deviceId }): Observable<SignOperationEvent> =>
23
+ new Observable(o => {
24
+ async function main() {
25
+ const subAccount =
26
+ transaction.subAccountId && account.subAccounts
27
+ ? account.subAccounts.find(sa => sa.id === transaction.subAccountId)
28
+ : undefined;
29
+ const isContractAddressRecipient =
30
+ (await fetchTronContract(transaction.recipient)) !== undefined;
31
+ const fee = await getEstimatedFees(account, transaction, isContractAddressRecipient);
32
+ const balance = subAccount
33
+ ? subAccount.balance
34
+ : BigNumber.max(0, account.spendableBalance.minus(fee));
35
+
36
+ if (transaction.useAllAmount) {
37
+ transaction = { ...transaction }; // transaction object must not be mutated
38
+ transaction.amount = balance; // force the amount to be the max
39
+ }
40
+
41
+ const {
42
+ raw_data_hex: rawDataHex,
43
+ raw_data: rawData,
44
+ txID: hash,
45
+ } = await prepareTransactionForSignature(account, subAccount, transaction);
46
+
47
+ o.next({
48
+ type: "device-signature-requested",
49
+ });
50
+
51
+ const txArg = {
52
+ rawDataHex,
53
+ // only for trc10, we need to put the token ledger signature
54
+ tokenSignature:
55
+ subAccount &&
56
+ subAccount.type === "TokenAccount" &&
57
+ subAccount.token.id.includes("trc10")
58
+ ? subAccount.token.ledgerSignature
59
+ : undefined,
60
+ };
61
+
62
+ // Sign by device
63
+ const signature = await signerContext(deviceId, signer =>
64
+ signer.sign(
65
+ account.freshAddressPath,
66
+ txArg.rawDataHex ?? "", //FIXME: why rawDataHex could be undefined? This shouldn't be the case.
67
+ txArg.tokenSignature ? [txArg.tokenSignature] : [],
68
+ ),
69
+ );
70
+
71
+ o.next({
72
+ type: "device-signature-granted",
73
+ });
74
+
75
+ const operation = buildOptimisticOperation(account, subAccount, transaction, fee, hash);
76
+
77
+ o.next({
78
+ type: "signed",
79
+ signedOperation: {
80
+ operation,
81
+ signature,
82
+ rawData,
83
+ },
84
+ });
85
+ }
86
+
87
+ main().then(
88
+ () => o.complete(),
89
+ e => o.error(e),
90
+ );
91
+ });
92
+
93
+ const prepareTransactionForSignature = (
94
+ account: TronAccount,
95
+ subAccount: TokenAccount | undefined,
96
+ transaction: Transaction,
97
+ ) => {
98
+ switch (transaction.mode) {
99
+ case "freeze":
100
+ return freezeTronTransaction(account, transaction);
101
+
102
+ case "unfreeze":
103
+ return unfreezeTronTransaction(account, transaction);
104
+
105
+ case "vote":
106
+ return voteTronSuperRepresentatives(account, transaction);
107
+
108
+ case "claimReward":
109
+ return claimRewardTronTransaction(account);
110
+
111
+ case "withdrawExpireUnfreeze":
112
+ return withdrawExpireUnfreezeTronTransaction(account, transaction);
113
+
114
+ case "unDelegateResource":
115
+ return unDelegateResourceTransaction(account, transaction);
116
+
117
+ case "legacyUnfreeze":
118
+ return legacyUnfreezeTronTransaction(account, transaction);
119
+
120
+ default:
121
+ return createTronTransaction(account, transaction, subAccount);
122
+ }
123
+ };
@@ -0,0 +1,105 @@
1
+ import BigNumber from "bignumber.js";
2
+ import { firstValueFrom, reduce } from "rxjs";
3
+ import { getCryptoCurrencyById } from "@ledgerhq/cryptoassets/index";
4
+ import { Account, AccountBridge, SyncConfig, TransactionCommon } from "@ledgerhq/types-live";
5
+ import { TronCoinConfig } from "../config";
6
+ import { defaultTronResources } from "../logic/utils";
7
+ import { Transaction, TronAccount } from "../types";
8
+ import { createBridges } from "./index";
9
+
10
+ jest.setTimeout(30000);
11
+
12
+ const tron = getCryptoCurrencyById("tron");
13
+ const defaultSyncConfig = {
14
+ paginationConfig: {},
15
+ blacklistedTokenIds: [],
16
+ };
17
+ export function syncAccount<T extends TransactionCommon, A extends Account = Account>(
18
+ bridge: AccountBridge<T, A>,
19
+ account: A,
20
+ syncConfig: SyncConfig = defaultSyncConfig,
21
+ ): Promise<A> {
22
+ return firstValueFrom(
23
+ bridge.sync(account, syncConfig).pipe(reduce((a, f: (arg0: A) => A) => f(a), account)),
24
+ );
25
+ }
26
+
27
+ const dummyAccount: TronAccount = {
28
+ type: "Account",
29
+ id: "",
30
+ derivationMode: "",
31
+ seedIdentifier: "",
32
+ used: false,
33
+ currency: tron,
34
+ index: 0,
35
+ freshAddress: "",
36
+ freshAddressPath: "",
37
+ swapHistory: [],
38
+ blockHeight: 0,
39
+ balance: new BigNumber(0),
40
+ spendableBalance: new BigNumber(0),
41
+ operationsCount: 0,
42
+ operations: [],
43
+ pendingOperations: [],
44
+ lastSyncDate: new Date(0),
45
+ creationDate: new Date(),
46
+ balanceHistoryCache: {
47
+ HOUR: {
48
+ balances: [],
49
+ latestDate: undefined,
50
+ },
51
+ DAY: {
52
+ balances: [],
53
+ latestDate: undefined,
54
+ },
55
+ WEEK: {
56
+ balances: [],
57
+ latestDate: undefined,
58
+ },
59
+ },
60
+ tronResources: {} as any,
61
+ };
62
+
63
+ describe("Tron Accounts", () => {
64
+ let bridge: ReturnType<typeof createBridges>;
65
+
66
+ beforeAll(() => {
67
+ const signer = jest.fn();
68
+ const coinConfig = (): TronCoinConfig => ({
69
+ status: {
70
+ type: "active",
71
+ },
72
+ explorer: {
73
+ url: "https://tron.coin.ledger.com",
74
+ },
75
+ });
76
+ bridge = createBridges(signer, coinConfig);
77
+ });
78
+
79
+ test("should always have tronResources", async () => {
80
+ const account = await syncAccount<Transaction, TronAccount>(
81
+ bridge.accountBridge,
82
+ dummyAccount,
83
+ defaultSyncConfig,
84
+ );
85
+
86
+ expect(account.tronResources).toEqual(defaultTronResources);
87
+ });
88
+
89
+ test.each([
90
+ "TL24LCps5FKwp3PoU1MvrYrwhi5LU1tHre",
91
+ "TAVrrARNdnjHgCGMQYeQV7hv4PSu7mVsMj",
92
+ "THAe4BNVxp293qgyQEqXEkHMpPcqtG73bi",
93
+ "TRqkRnAj6ceJFYAn2p1eE7aWrgBBwtdhS9",
94
+ "TUxd6v64YTWkfpFpNDdtgc5Ps4SfGxwizT",
95
+ "TY2ksFgpvb82TgGPwUSa7iseqPW5weYQyh",
96
+ ])("should always be sync wihtout error for address %s", async (accountId: string) => {
97
+ const account = await syncAccount<Transaction, TronAccount>(
98
+ bridge.accountBridge,
99
+ { ...dummyAccount, id: `js:2:tron:${accountId}:`, freshAddress: accountId },
100
+ defaultSyncConfig,
101
+ );
102
+
103
+ expect(account.id).toEqual(`js:2:tron:${accountId}:`);
104
+ });
105
+ });
@@ -0,0 +1,284 @@
1
+ import {
2
+ emptyHistoryCache,
3
+ encodeAccountId,
4
+ encodeTokenAccountId,
5
+ } from "@ledgerhq/coin-framework/account";
6
+ import { GetAccountShape, makeSync } from "@ledgerhq/coin-framework/bridge/jsHelpers";
7
+ import { encodeOperationId } from "@ledgerhq/coin-framework/operation";
8
+ import { findTokenByAddressInCurrency, findTokenById } from "@ledgerhq/cryptoassets/index";
9
+ import { Account, SubAccount, TokenAccount } from "@ledgerhq/types-live";
10
+ import BigNumber from "bignumber.js";
11
+ import compact from "lodash/compact";
12
+ import get from "lodash/get";
13
+ import { getOperationsPageSize } from "../logic/pagination";
14
+ import { isParentTx, txInfoToOperation } from "../logic/utils";
15
+ import {
16
+ fetchCurrentBlockHeight,
17
+ fetchTronAccount,
18
+ fetchTronAccountTxs,
19
+ getTronResources,
20
+ } from "../network";
21
+ import { TronAccount, TrongridExtraTxInfo, TronOperation } from "../types";
22
+
23
+ type TronToken = {
24
+ key: string;
25
+ type: "trc10" | "trc20";
26
+ tokenId: string;
27
+ balance: string;
28
+ };
29
+
30
+ // the balance does not update straightaway so we should ignore recent operations if they are in pending for a bit
31
+ const PREFER_PENDING_OPERATIONS_UNTIL_BLOCK_VALIDATION = 35;
32
+
33
+ export const getAccountShape: GetAccountShape<TronAccount> = async (
34
+ { initialAccount, currency, address, derivationMode },
35
+ syncConfig,
36
+ ) => {
37
+ const blockHeight = await fetchCurrentBlockHeight();
38
+ const tronAcc = await fetchTronAccount(address);
39
+
40
+ const accountId = encodeAccountId({
41
+ type: "js",
42
+ version: "2",
43
+ currencyId: currency.id,
44
+ xpubOrAddress: address,
45
+ derivationMode: derivationMode,
46
+ });
47
+
48
+ if (tronAcc.length === 0) {
49
+ const defaultTronResources = await getTronResources();
50
+
51
+ return {
52
+ id: accountId,
53
+ blockHeight,
54
+ balance: new BigNumber(0),
55
+ tronResources: defaultTronResources,
56
+ };
57
+ }
58
+
59
+ const acc = tronAcc[0];
60
+ const spendableBalance = acc.balance ? new BigNumber(acc.balance) : new BigNumber(0);
61
+ const cacheTransactionInfoById = initialAccount
62
+ ? {
63
+ ...(initialAccount?.tronResources?.cacheTransactionInfoById || {}),
64
+ }
65
+ : {};
66
+ const operationsPageSize = Math.min(
67
+ 1000,
68
+ getOperationsPageSize(initialAccount && initialAccount.id, syncConfig),
69
+ );
70
+ // FIXME: this is not optional especially that we might already have initialAccount
71
+ // use minimalOperationsBuilderSync to reconciliate and KEEP REF
72
+ const txs = await fetchTronAccountTxs(
73
+ address,
74
+ txs => txs.length < operationsPageSize,
75
+ cacheTransactionInfoById,
76
+ );
77
+
78
+ const tronResources = await getTronResources(acc, txs, cacheTransactionInfoById);
79
+ const balance = spendableBalance
80
+ .plus(tronResources.frozen.bandwidth ? tronResources.frozen.bandwidth.amount : new BigNumber(0))
81
+ .plus(tronResources.frozen.energy ? tronResources.frozen.energy.amount : new BigNumber(0))
82
+ .plus(
83
+ tronResources.delegatedFrozen.bandwidth
84
+ ? tronResources.delegatedFrozen.bandwidth.amount
85
+ : new BigNumber(0),
86
+ )
87
+ .plus(
88
+ tronResources.delegatedFrozen.energy
89
+ ? tronResources.delegatedFrozen.energy.amount
90
+ : new BigNumber(0),
91
+ )
92
+
93
+ .plus(
94
+ tronResources.unFrozen.energy
95
+ ? tronResources.unFrozen.energy.reduce((accum, cur) => {
96
+ return accum.plus(cur.amount);
97
+ }, new BigNumber(0))
98
+ : new BigNumber(0),
99
+ )
100
+ .plus(
101
+ tronResources.unFrozen.bandwidth
102
+ ? tronResources.unFrozen.bandwidth.reduce((accum, cur) => {
103
+ return accum.plus(cur.amount);
104
+ }, new BigNumber(0))
105
+ : new BigNumber(0),
106
+ )
107
+ .plus(
108
+ tronResources.legacyFrozen.bandwidth
109
+ ? tronResources.legacyFrozen.bandwidth.amount
110
+ : new BigNumber(0),
111
+ )
112
+ .plus(
113
+ tronResources.legacyFrozen.energy
114
+ ? tronResources.legacyFrozen.energy.amount
115
+ : new BigNumber(0),
116
+ );
117
+
118
+ const parentTxs = txs.filter(isParentTx);
119
+ const parentOperations: TronOperation[] = compact(
120
+ parentTxs.map(tx => txInfoToOperation(accountId, address, tx)),
121
+ );
122
+
123
+ const trc10Tokens = get(acc, "assetV2", []).reduce(
124
+ (accumulator: TronToken[], { key, value }: { key: string; value: string }) => {
125
+ const tokenInfo = findTokenById(`tron/trc10/${key}`);
126
+ if (tokenInfo) {
127
+ accumulator.push({
128
+ key,
129
+ type: "trc10",
130
+ tokenId: tokenInfo.id,
131
+ balance: value,
132
+ });
133
+ }
134
+ return accumulator;
135
+ },
136
+ [],
137
+ );
138
+
139
+ const trc20Tokens = get(acc, "trc20", []).reduce((accumulator: TronToken[], trc20: TronToken) => {
140
+ const [[contractAddress, balance]] = Object.entries(trc20);
141
+ const tokenInfo = findTokenByAddressInCurrency(contractAddress, currency.id);
142
+ if (tokenInfo) {
143
+ accumulator.push({
144
+ key: contractAddress,
145
+ type: "trc20",
146
+ tokenId: tokenInfo.id,
147
+ balance,
148
+ });
149
+ }
150
+ return accumulator;
151
+ }, []);
152
+
153
+ const { blacklistedTokenIds = [] } = syncConfig;
154
+
155
+ const subAccounts: SubAccount[] = compact(
156
+ trc10Tokens.concat(trc20Tokens).map(({ key, tokenId, balance }: TronToken) => {
157
+ const { blacklistedTokenIds = [] } = syncConfig;
158
+ const token = findTokenById(tokenId);
159
+ if (!token || blacklistedTokenIds.includes(tokenId)) return;
160
+ const id = encodeTokenAccountId(accountId, token);
161
+ const tokenTxs = txs.filter(tx => tx.tokenId === key);
162
+ const operations = compact(tokenTxs.map(tx => txInfoToOperation(id, address, tx)));
163
+ const maybeExistingSubAccount = initialAccount?.subAccounts?.find(a => a.id === id);
164
+ const bnBalance = new BigNumber(balance);
165
+ const sub: TokenAccount = {
166
+ type: "TokenAccount",
167
+ id,
168
+ parentId: accountId,
169
+ token,
170
+ balance: bnBalance,
171
+ spendableBalance: bnBalance,
172
+ operationsCount: operations.length,
173
+ operations,
174
+ pendingOperations: maybeExistingSubAccount ? maybeExistingSubAccount.pendingOperations : [],
175
+ creationDate: operations.length > 0 ? operations[operations.length - 1].date : new Date(),
176
+ swapHistory: maybeExistingSubAccount ? maybeExistingSubAccount.swapHistory : [],
177
+ balanceHistoryCache: emptyHistoryCache, // calculated in the jsHelpers
178
+ };
179
+ return sub;
180
+ }),
181
+ );
182
+
183
+ // Filter blacklisted tokens from the initial account's subAccounts
184
+ // Could be use to filter out tokens that got their CAL id changed
185
+ const filteredInitialSubAccounts = (initialAccount?.subAccounts || []).filter(
186
+ subAccount => !blacklistedTokenIds.includes(subAccount.token.id),
187
+ );
188
+
189
+ // keep old account with emptyBalance and a history not returned by the BE fixes LIVE-12797
190
+ const mergedSubAccounts = mergeSubAccounts(subAccounts, filteredInitialSubAccounts);
191
+
192
+ // get 'OUT' token operations with fee
193
+ const subOutOperationsWithFee: TronOperation[] = subAccounts
194
+ .flatMap(s => s.operations)
195
+ .filter(o => o.type === "OUT" && o.fee.isGreaterThan(0))
196
+ .map(
197
+ (o): TronOperation => ({
198
+ ...o,
199
+ accountId,
200
+ value: o.fee,
201
+ id: encodeOperationId(accountId, o.hash, "OUT"),
202
+ extra: o.extra as TrongridExtraTxInfo,
203
+ }),
204
+ );
205
+ // add them to the parent operations and sort by date desc
206
+
207
+ /**
208
+ * FIXME
209
+ *
210
+ * We have a problem here as we're just concatenating ops without ever really linking them.
211
+ * It means no operation can be "FEES" of a subOp by example. It leads to our issues with TRC10/TRC20
212
+ * optimistic operation never really existing in the end.
213
+ */
214
+ const parentOpsAndSubOutOpsWithFee = parentOperations
215
+ .concat(subOutOperationsWithFee)
216
+ .sort((a, b) => b.date.valueOf() - a.date.valueOf());
217
+
218
+ return {
219
+ id: accountId,
220
+ balance,
221
+ spendableBalance,
222
+ operationsCount: parentOpsAndSubOutOpsWithFee.length,
223
+ operations: parentOpsAndSubOutOpsWithFee,
224
+ subAccounts: mergedSubAccounts,
225
+ tronResources,
226
+ blockHeight,
227
+ };
228
+ };
229
+
230
+ const postSync = (initial: TronAccount, parent: TronAccount): TronAccount => {
231
+ function evictRecentOpsIfPending(a: Account | TokenAccount) {
232
+ a.pendingOperations.forEach(pending => {
233
+ const i = a.operations.findIndex(o => o.id === pending.id);
234
+
235
+ if (i !== -1) {
236
+ const diff = parent.blockHeight - (a.operations[i].blockHeight || 0);
237
+
238
+ if (diff < PREFER_PENDING_OPERATIONS_UNTIL_BLOCK_VALIDATION) {
239
+ a.operations.splice(i, 1);
240
+ }
241
+ }
242
+ });
243
+ }
244
+
245
+ evictRecentOpsIfPending(parent);
246
+ parent.subAccounts && parent.subAccounts.forEach(evictRecentOpsIfPending);
247
+ return parent;
248
+ };
249
+
250
+ /**
251
+ * Merges two arrays of subAccounts according to specific rules:
252
+ * - The first array (subAccounts1) is up-to-date and should not be modified.
253
+ * - Old duplicates from the second array (subAccounts2) should be filtered out.
254
+ * - Only new subAccounts with a unique ID from the second array should be included.
255
+ * - The balance and spendableBalance fields of the second array's subAccounts should be set to 0.
256
+ *
257
+ * @param {Array} subAccounts1 - The first array of subAccounts, which is up-to-date and should not be modified.
258
+ * @param {Array} subAccounts2 - The second array of subAccounts, from which only new unique subAccounts should be included.
259
+ * @returns {Array} - The merged array of subAccounts.
260
+ */
261
+ const mergeSubAccounts = (subAccounts1: TokenAccount[], subAccounts2: TokenAccount[]) => {
262
+ const existingIds = new Set(subAccounts1.map(subAccount => subAccount.id));
263
+ const filteredSubAccounts2: TokenAccount[] = subAccounts2
264
+ .map(subAccount => {
265
+ if (existingIds.has(subAccount.id)) {
266
+ return null;
267
+ } else {
268
+ // Set balance and spendableBalance to 0 has if they are not here it means balance is 0
269
+ return {
270
+ ...subAccount,
271
+ balance: new BigNumber(0),
272
+ spendableBalance: new BigNumber(0),
273
+ };
274
+ }
275
+ })
276
+ .filter((elt): elt is NonNullable<typeof elt> => elt !== null);
277
+
278
+ return subAccounts1.concat(filteredSubAccounts2);
279
+ };
280
+
281
+ export const sync = makeSync({
282
+ getAccountShape,
283
+ postSync,
284
+ });
@@ -0,0 +1,84 @@
1
+ import { BigNumber } from "bignumber.js";
2
+ import type { Transaction, TransactionRaw } from "../types";
3
+ import { formatTransactionStatus } from "@ledgerhq/coin-framework/formatters";
4
+ import {
5
+ fromTransactionCommonRaw,
6
+ fromTransactionStatusRawCommon as fromTransactionStatusRaw,
7
+ toTransactionCommonRaw,
8
+ toTransactionStatusRawCommon as toTransactionStatusRaw,
9
+ } from "@ledgerhq/coin-framework/serialization";
10
+ import type { Account } from "@ledgerhq/types-live";
11
+ import { getAccountCurrency } from "@ledgerhq/coin-framework/account";
12
+ import { formatCurrencyUnit } from "@ledgerhq/coin-framework/currencies";
13
+
14
+ export const fromTransactionRaw = (tr: TransactionRaw): Transaction => {
15
+ const common = fromTransactionCommonRaw(tr);
16
+ const { networkInfo } = tr;
17
+ return {
18
+ ...common,
19
+ networkInfo: networkInfo && {
20
+ family: "tron",
21
+ freeNetUsed: new BigNumber(networkInfo.freeNetUsed),
22
+ freeNetLimit: new BigNumber(networkInfo.freeNetLimit),
23
+ netUsed: new BigNumber(networkInfo.netUsed),
24
+ netLimit: new BigNumber(networkInfo.netLimit),
25
+ energyUsed: new BigNumber(networkInfo.energyUsed),
26
+ energyLimit: new BigNumber(networkInfo.energyLimit),
27
+ },
28
+ family: tr.family,
29
+ mode: tr.mode,
30
+ resource: tr.resource || null,
31
+ duration: tr.duration || 3,
32
+ votes: tr.votes,
33
+ };
34
+ };
35
+
36
+ export const toTransactionRaw = (t: Transaction): TransactionRaw => {
37
+ const common = toTransactionCommonRaw(t);
38
+ const { networkInfo } = t;
39
+ return {
40
+ ...common,
41
+ networkInfo: networkInfo && {
42
+ family: "tron",
43
+ freeNetUsed: networkInfo.freeNetUsed.toString(),
44
+ freeNetLimit: networkInfo.freeNetLimit.toString(),
45
+ netUsed: networkInfo.netUsed.toString(),
46
+ netLimit: networkInfo.netLimit.toString(),
47
+ energyUsed: networkInfo.energyUsed.toString(),
48
+ energyLimit: networkInfo.energyLimit.toString(),
49
+ },
50
+ family: t.family,
51
+ mode: t.mode,
52
+ resource: t.resource || null,
53
+ duration: t.duration || 3,
54
+ votes: t.votes,
55
+ };
56
+ };
57
+
58
+ export const formatTransaction = (t: Transaction, mainAccount: Account): string => {
59
+ const account =
60
+ (t.subAccountId && (mainAccount.subAccounts || []).find(a => a.id === t.subAccountId)) ||
61
+ mainAccount;
62
+ return `
63
+ ${t.mode.toUpperCase()}${t.resource ? " " + t.resource : ""} ${
64
+ t.useAllAmount
65
+ ? "MAX"
66
+ : t.amount.isZero()
67
+ ? ""
68
+ : " " +
69
+ formatCurrencyUnit(getAccountCurrency(account).units[0], t.amount, {
70
+ showCode: true,
71
+ disableRounding: true,
72
+ })
73
+ }${!t.votes ? "" : " " + t.votes.map(v => v.voteCount + "->" + v.address).join(" ")}
74
+ TO ${t.recipient}`;
75
+ };
76
+
77
+ export default {
78
+ formatTransaction,
79
+ fromTransactionRaw,
80
+ toTransactionRaw,
81
+ fromTransactionStatusRaw,
82
+ toTransactionStatusRaw,
83
+ formatTransactionStatus,
84
+ };
package/src/config.ts ADDED
@@ -0,0 +1,24 @@
1
+ import { CurrencyConfig, CoinConfig } from "@ledgerhq/coin-framework/config";
2
+ import { MissingCoinConfig } from "@ledgerhq/coin-framework/errors";
3
+
4
+ export type TronConfig = {
5
+ explorer: {
6
+ url: string;
7
+ };
8
+ };
9
+
10
+ export type TronCoinConfig = CurrencyConfig & TronConfig;
11
+
12
+ let coinConfig: CoinConfig<TronCoinConfig> | undefined;
13
+
14
+ export const setCoinConfig = (config: CoinConfig<TronCoinConfig>): void => {
15
+ coinConfig = config;
16
+ };
17
+
18
+ export const getCoinConfig = (): TronCoinConfig => {
19
+ if (!coinConfig) {
20
+ throw new MissingCoinConfig();
21
+ }
22
+
23
+ return coinConfig();
24
+ };
package/src/index.ts ADDED
@@ -0,0 +1,3 @@
1
+ export * from "./types";
2
+
3
+ export { createBridges } from "./bridge/index";
@@ -0,0 +1,4 @@
1
+ import { BigNumber } from "bignumber.js";
2
+
3
+ export const ONE_TRX = new BigNumber(1000000);
4
+ export const ACTIVATION_FEES = new BigNumber(1100000); // ONE TRX fee + 0.1 TRX activation cost
@@ -0,0 +1,21 @@
1
+ import type { SyncConfig } from "@ledgerhq/types-live";
2
+
3
+ export function getOperationsPageSize(
4
+ accountId: string | null | undefined,
5
+ syncConfig: SyncConfig,
6
+ ): number {
7
+ const { paginationConfig } = syncConfig;
8
+ const { operationsPerAccountId, operations } = paginationConfig;
9
+ const numbers: number[] = [];
10
+
11
+ if (operationsPerAccountId && accountId && accountId in operationsPerAccountId) {
12
+ numbers.push(operationsPerAccountId[accountId]);
13
+ }
14
+
15
+ if (typeof operations === "number") {
16
+ numbers.push(operations);
17
+ }
18
+
19
+ if (numbers.length === 0) return Infinity;
20
+ return Math.max(...numbers);
21
+ }