@ledgerhq/coin-hedera 1.12.1-nightly.1 → 1.13.0-nightly.3

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 (386) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/.unimportedrc.json +1 -1
  3. package/CHANGELOG.md +29 -0
  4. package/jest.config.js +1 -1
  5. package/jest.integ.config.js +8 -0
  6. package/lib/api/index.d.ts +4 -0
  7. package/lib/api/index.d.ts.map +1 -0
  8. package/lib/api/index.js +119 -0
  9. package/lib/api/index.js.map +1 -0
  10. package/lib/bridge/broadcast.d.ts +1 -1
  11. package/lib/bridge/broadcast.d.ts.map +1 -1
  12. package/lib/bridge/broadcast.js +6 -9
  13. package/lib/bridge/broadcast.js.map +1 -1
  14. package/lib/bridge/buildOptimisticOperation.d.ts.map +1 -1
  15. package/lib/bridge/buildOptimisticOperation.js +14 -11
  16. package/lib/bridge/buildOptimisticOperation.js.map +1 -1
  17. package/lib/bridge/createTransaction.d.ts +1 -1
  18. package/lib/bridge/createTransaction.d.ts.map +1 -1
  19. package/lib/bridge/createTransaction.js +2 -0
  20. package/lib/bridge/createTransaction.js.map +1 -1
  21. package/lib/bridge/estimateMaxSpendable.d.ts.map +1 -1
  22. package/lib/bridge/estimateMaxSpendable.js +2 -2
  23. package/lib/bridge/estimateMaxSpendable.js.map +1 -1
  24. package/lib/bridge/getTransactionStatus.d.ts.map +1 -1
  25. package/lib/bridge/getTransactionStatus.js +11 -10
  26. package/lib/bridge/getTransactionStatus.js.map +1 -1
  27. package/lib/bridge/prepareTransaction.d.ts.map +1 -1
  28. package/lib/bridge/prepareTransaction.js +6 -5
  29. package/lib/bridge/prepareTransaction.js.map +1 -1
  30. package/lib/bridge/signOperation.d.ts +1 -1
  31. package/lib/bridge/signOperation.d.ts.map +1 -1
  32. package/lib/bridge/signOperation.js +53 -14
  33. package/lib/bridge/signOperation.js.map +1 -1
  34. package/lib/bridge/synchronisation.d.ts.map +1 -1
  35. package/lib/bridge/synchronisation.js +24 -11
  36. package/lib/bridge/synchronisation.js.map +1 -1
  37. package/lib/bridge/utils.d.ts +3 -13
  38. package/lib/bridge/utils.d.ts.map +1 -1
  39. package/lib/bridge/utils.js +10 -119
  40. package/lib/bridge/utils.js.map +1 -1
  41. package/lib/config.d.ts +8 -0
  42. package/lib/config.d.ts.map +1 -0
  43. package/lib/config.js +9 -0
  44. package/lib/config.js.map +1 -0
  45. package/lib/constants.d.ts +11 -8
  46. package/lib/constants.d.ts.map +1 -1
  47. package/lib/constants.js +17 -13
  48. package/lib/constants.js.map +1 -1
  49. package/lib/deviceTransactionConfig.d.ts +2 -2
  50. package/lib/deviceTransactionConfig.d.ts.map +1 -1
  51. package/lib/deviceTransactionConfig.js +4 -4
  52. package/lib/deviceTransactionConfig.js.map +1 -1
  53. package/lib/logic/broadcast.d.ts +3 -0
  54. package/lib/logic/broadcast.d.ts.map +1 -0
  55. package/lib/logic/broadcast.js +11 -0
  56. package/lib/logic/broadcast.js.map +1 -0
  57. package/lib/logic/combine.d.ts +2 -0
  58. package/lib/logic/combine.d.ts.map +1 -0
  59. package/lib/logic/combine.js +19 -0
  60. package/lib/logic/combine.js.map +1 -0
  61. package/lib/logic/craftTransaction.d.ts +8 -0
  62. package/lib/logic/craftTransaction.d.ts.map +1 -0
  63. package/lib/logic/craftTransaction.js +107 -0
  64. package/lib/logic/craftTransaction.js.map +1 -0
  65. package/lib/logic/estimateFees.d.ts +5 -0
  66. package/lib/logic/estimateFees.d.ts.map +1 -0
  67. package/lib/logic/estimateFees.js +25 -0
  68. package/lib/logic/estimateFees.js.map +1 -0
  69. package/lib/logic/getAssetFromToken.d.ts +4 -0
  70. package/lib/logic/getAssetFromToken.d.ts.map +1 -0
  71. package/lib/logic/getAssetFromToken.js +14 -0
  72. package/lib/logic/getAssetFromToken.js.map +1 -0
  73. package/lib/logic/getBalance.d.ts +4 -0
  74. package/lib/logic/getBalance.d.ts.map +1 -0
  75. package/lib/logic/getBalance.js +36 -0
  76. package/lib/logic/getBalance.js.map +1 -0
  77. package/lib/logic/getTokenFromAsset.d.ts +4 -0
  78. package/lib/logic/getTokenFromAsset.d.ts.map +1 -0
  79. package/lib/logic/getTokenFromAsset.js +13 -0
  80. package/lib/logic/getTokenFromAsset.js.map +1 -0
  81. package/lib/logic/index.d.ts +10 -0
  82. package/lib/logic/index.d.ts.map +1 -0
  83. package/lib/logic/index.js +22 -0
  84. package/lib/logic/index.js.map +1 -0
  85. package/lib/logic/lastBlock.d.ts +12 -0
  86. package/lib/logic/lastBlock.d.ts.map +1 -0
  87. package/lib/logic/lastBlock.js +25 -0
  88. package/lib/logic/lastBlock.js.map +1 -0
  89. package/lib/logic/listOperations.d.ts +19 -0
  90. package/lib/logic/listOperations.d.ts.map +1 -0
  91. package/lib/logic/listOperations.js +179 -0
  92. package/lib/logic/listOperations.js.map +1 -0
  93. package/lib/logic/utils.d.ts +55 -0
  94. package/lib/logic/utils.d.ts.map +1 -0
  95. package/lib/logic/utils.js +197 -0
  96. package/lib/logic/utils.js.map +1 -0
  97. package/lib/network/api.d.ts +24 -0
  98. package/lib/network/api.d.ts.map +1 -0
  99. package/lib/network/api.js +119 -0
  100. package/lib/network/api.js.map +1 -0
  101. package/lib/network/rpc.d.ts +12 -0
  102. package/lib/network/rpc.d.ts.map +1 -0
  103. package/lib/network/rpc.js +22 -0
  104. package/lib/network/rpc.js.map +1 -0
  105. package/lib/{api → network}/utils.d.ts +1 -5
  106. package/lib/network/utils.d.ts.map +1 -0
  107. package/lib/network/utils.js +52 -0
  108. package/lib/network/utils.js.map +1 -0
  109. package/lib/test/bridgeDatasetTest.d.ts.map +1 -1
  110. package/lib/test/bridgeDatasetTest.js +5 -1
  111. package/lib/test/bridgeDatasetTest.js.map +1 -1
  112. package/lib/test/fixtures/account.fixture.d.ts +17 -0
  113. package/lib/test/fixtures/account.fixture.d.ts.map +1 -1
  114. package/lib/test/fixtures/account.fixture.js +18 -1
  115. package/lib/test/fixtures/account.fixture.js.map +1 -1
  116. package/lib/test/fixtures/currency.fixture.d.ts.map +1 -1
  117. package/lib/test/fixtures/currency.fixture.js +1 -1
  118. package/lib/test/fixtures/currency.fixture.js.map +1 -1
  119. package/lib/test/fixtures/mirror.fixture.d.ts +1 -1
  120. package/lib/test/fixtures/mirror.fixture.d.ts.map +1 -1
  121. package/lib/test/fixtures/network.fixture.d.ts +3 -0
  122. package/lib/test/fixtures/network.fixture.d.ts.map +1 -0
  123. package/lib/test/fixtures/network.fixture.js +9 -0
  124. package/lib/test/fixtures/network.fixture.js.map +1 -0
  125. package/lib/test/fixtures/transaction.fixture.d.ts.map +1 -1
  126. package/lib/test/fixtures/transaction.fixture.js +3 -0
  127. package/lib/test/fixtures/transaction.fixture.js.map +1 -1
  128. package/lib/transaction.d.ts +1 -1
  129. package/lib/transaction.d.ts.map +1 -1
  130. package/lib/transaction.js +35 -6
  131. package/lib/transaction.js.map +1 -1
  132. package/lib/types/alpaca.d.ts +3 -0
  133. package/lib/types/alpaca.d.ts.map +1 -0
  134. package/lib/{api/types.js → types/alpaca.js} +1 -1
  135. package/lib/types/alpaca.js.map +1 -0
  136. package/lib/types/bridge.d.ts +28 -9
  137. package/lib/types/bridge.d.ts.map +1 -1
  138. package/lib/types/index.d.ts +2 -0
  139. package/lib/types/index.d.ts.map +1 -1
  140. package/lib/types/index.js +2 -0
  141. package/lib/types/index.js.map +1 -1
  142. package/lib/{api/types.d.ts → types/mirror.d.ts} +21 -2
  143. package/lib/types/mirror.d.ts.map +1 -0
  144. package/lib/types/mirror.js +3 -0
  145. package/lib/types/mirror.js.map +1 -0
  146. package/lib-es/api/index.d.ts +4 -0
  147. package/lib-es/api/index.d.ts.map +1 -0
  148. package/lib-es/api/index.js +112 -0
  149. package/lib-es/api/index.js.map +1 -0
  150. package/lib-es/bridge/broadcast.d.ts +1 -1
  151. package/lib-es/bridge/broadcast.d.ts.map +1 -1
  152. package/lib-es/bridge/broadcast.js +4 -7
  153. package/lib-es/bridge/broadcast.js.map +1 -1
  154. package/lib-es/bridge/buildOptimisticOperation.d.ts.map +1 -1
  155. package/lib-es/bridge/buildOptimisticOperation.js +12 -9
  156. package/lib-es/bridge/buildOptimisticOperation.js.map +1 -1
  157. package/lib-es/bridge/createTransaction.d.ts +1 -1
  158. package/lib-es/bridge/createTransaction.d.ts.map +1 -1
  159. package/lib-es/bridge/createTransaction.js +2 -0
  160. package/lib-es/bridge/createTransaction.js.map +1 -1
  161. package/lib-es/bridge/estimateMaxSpendable.d.ts.map +1 -1
  162. package/lib-es/bridge/estimateMaxSpendable.js +2 -2
  163. package/lib-es/bridge/estimateMaxSpendable.js.map +1 -1
  164. package/lib-es/bridge/getTransactionStatus.d.ts.map +1 -1
  165. package/lib-es/bridge/getTransactionStatus.js +7 -6
  166. package/lib-es/bridge/getTransactionStatus.js.map +1 -1
  167. package/lib-es/bridge/prepareTransaction.d.ts.map +1 -1
  168. package/lib-es/bridge/prepareTransaction.js +4 -3
  169. package/lib-es/bridge/prepareTransaction.js.map +1 -1
  170. package/lib-es/bridge/signOperation.d.ts +1 -1
  171. package/lib-es/bridge/signOperation.d.ts.map +1 -1
  172. package/lib-es/bridge/signOperation.js +53 -14
  173. package/lib-es/bridge/signOperation.js.map +1 -1
  174. package/lib-es/bridge/synchronisation.d.ts.map +1 -1
  175. package/lib-es/bridge/synchronisation.js +24 -11
  176. package/lib-es/bridge/synchronisation.js.map +1 -1
  177. package/lib-es/bridge/utils.d.ts +3 -13
  178. package/lib-es/bridge/utils.d.ts.map +1 -1
  179. package/lib-es/bridge/utils.js +7 -113
  180. package/lib-es/bridge/utils.js.map +1 -1
  181. package/lib-es/config.d.ts +8 -0
  182. package/lib-es/config.d.ts.map +1 -0
  183. package/lib-es/config.js +4 -0
  184. package/lib-es/config.js.map +1 -0
  185. package/lib-es/constants.d.ts +11 -8
  186. package/lib-es/constants.d.ts.map +1 -1
  187. package/lib-es/constants.js +13 -9
  188. package/lib-es/constants.js.map +1 -1
  189. package/lib-es/deviceTransactionConfig.d.ts +2 -2
  190. package/lib-es/deviceTransactionConfig.d.ts.map +1 -1
  191. package/lib-es/deviceTransactionConfig.js +2 -2
  192. package/lib-es/deviceTransactionConfig.js.map +1 -1
  193. package/lib-es/logic/broadcast.d.ts +3 -0
  194. package/lib-es/logic/broadcast.d.ts.map +1 -0
  195. package/lib-es/logic/broadcast.js +7 -0
  196. package/lib-es/logic/broadcast.js.map +1 -0
  197. package/lib-es/logic/combine.d.ts +2 -0
  198. package/lib-es/logic/combine.d.ts.map +1 -0
  199. package/lib-es/logic/combine.js +12 -0
  200. package/lib-es/logic/combine.js.map +1 -0
  201. package/lib-es/logic/craftTransaction.d.ts +8 -0
  202. package/lib-es/logic/craftTransaction.d.ts.map +1 -0
  203. package/lib-es/logic/craftTransaction.js +100 -0
  204. package/lib-es/logic/craftTransaction.js.map +1 -0
  205. package/lib-es/logic/estimateFees.d.ts +5 -0
  206. package/lib-es/logic/estimateFees.d.ts.map +1 -0
  207. package/lib-es/logic/estimateFees.js +18 -0
  208. package/lib-es/logic/estimateFees.js.map +1 -0
  209. package/lib-es/logic/getAssetFromToken.d.ts +4 -0
  210. package/lib-es/logic/getAssetFromToken.d.ts.map +1 -0
  211. package/lib-es/logic/getAssetFromToken.js +10 -0
  212. package/lib-es/logic/getAssetFromToken.js.map +1 -0
  213. package/lib-es/logic/getBalance.d.ts +4 -0
  214. package/lib-es/logic/getBalance.d.ts.map +1 -0
  215. package/lib-es/logic/getBalance.js +32 -0
  216. package/lib-es/logic/getBalance.js.map +1 -0
  217. package/lib-es/logic/getTokenFromAsset.d.ts +4 -0
  218. package/lib-es/logic/getTokenFromAsset.d.ts.map +1 -0
  219. package/lib-es/logic/getTokenFromAsset.js +9 -0
  220. package/lib-es/logic/getTokenFromAsset.js.map +1 -0
  221. package/lib-es/logic/index.d.ts +10 -0
  222. package/lib-es/logic/index.d.ts.map +1 -0
  223. package/lib-es/logic/index.js +10 -0
  224. package/lib-es/logic/index.js.map +1 -0
  225. package/lib-es/logic/lastBlock.d.ts +12 -0
  226. package/lib-es/logic/lastBlock.d.ts.map +1 -0
  227. package/lib-es/logic/lastBlock.js +21 -0
  228. package/lib-es/logic/lastBlock.js.map +1 -0
  229. package/lib-es/logic/listOperations.d.ts +19 -0
  230. package/lib-es/logic/listOperations.d.ts.map +1 -0
  231. package/lib-es/logic/listOperations.js +172 -0
  232. package/lib-es/logic/listOperations.js.map +1 -0
  233. package/lib-es/logic/utils.d.ts +55 -0
  234. package/lib-es/logic/utils.d.ts.map +1 -0
  235. package/lib-es/logic/utils.js +174 -0
  236. package/lib-es/logic/utils.js.map +1 -0
  237. package/lib-es/network/api.d.ts +24 -0
  238. package/lib-es/network/api.d.ts.map +1 -0
  239. package/lib-es/network/api.js +113 -0
  240. package/lib-es/network/api.js.map +1 -0
  241. package/lib-es/network/rpc.d.ts +12 -0
  242. package/lib-es/network/rpc.d.ts.map +1 -0
  243. package/lib-es/network/rpc.js +19 -0
  244. package/lib-es/network/rpc.js.map +1 -0
  245. package/lib-es/{api → network}/utils.d.ts +1 -5
  246. package/lib-es/network/utils.d.ts.map +1 -0
  247. package/lib-es/network/utils.js +45 -0
  248. package/lib-es/network/utils.js.map +1 -0
  249. package/lib-es/test/bridgeDatasetTest.d.ts.map +1 -1
  250. package/lib-es/test/bridgeDatasetTest.js +5 -1
  251. package/lib-es/test/bridgeDatasetTest.js.map +1 -1
  252. package/lib-es/test/fixtures/account.fixture.d.ts +17 -0
  253. package/lib-es/test/fixtures/account.fixture.d.ts.map +1 -1
  254. package/lib-es/test/fixtures/account.fixture.js +17 -0
  255. package/lib-es/test/fixtures/account.fixture.js.map +1 -1
  256. package/lib-es/test/fixtures/currency.fixture.d.ts.map +1 -1
  257. package/lib-es/test/fixtures/currency.fixture.js +1 -1
  258. package/lib-es/test/fixtures/currency.fixture.js.map +1 -1
  259. package/lib-es/test/fixtures/mirror.fixture.d.ts +1 -1
  260. package/lib-es/test/fixtures/mirror.fixture.d.ts.map +1 -1
  261. package/lib-es/test/fixtures/network.fixture.d.ts +3 -0
  262. package/lib-es/test/fixtures/network.fixture.d.ts.map +1 -0
  263. package/lib-es/test/fixtures/network.fixture.js +5 -0
  264. package/lib-es/test/fixtures/network.fixture.js.map +1 -0
  265. package/lib-es/test/fixtures/transaction.fixture.d.ts.map +1 -1
  266. package/lib-es/test/fixtures/transaction.fixture.js +3 -0
  267. package/lib-es/test/fixtures/transaction.fixture.js.map +1 -1
  268. package/lib-es/transaction.d.ts +1 -1
  269. package/lib-es/transaction.d.ts.map +1 -1
  270. package/lib-es/transaction.js +35 -6
  271. package/lib-es/transaction.js.map +1 -1
  272. package/lib-es/types/alpaca.d.ts +3 -0
  273. package/lib-es/types/alpaca.d.ts.map +1 -0
  274. package/lib-es/types/alpaca.js +2 -0
  275. package/lib-es/types/alpaca.js.map +1 -0
  276. package/lib-es/types/bridge.d.ts +28 -9
  277. package/lib-es/types/bridge.d.ts.map +1 -1
  278. package/lib-es/types/index.d.ts +2 -0
  279. package/lib-es/types/index.d.ts.map +1 -1
  280. package/lib-es/types/index.js +2 -0
  281. package/lib-es/types/index.js.map +1 -1
  282. package/lib-es/{api/types.d.ts → types/mirror.d.ts} +21 -2
  283. package/lib-es/types/mirror.d.ts.map +1 -0
  284. package/lib-es/types/mirror.js +2 -0
  285. package/lib-es/types/mirror.js.map +1 -0
  286. package/package.json +8 -7
  287. package/src/api/index.integ.test.ts +401 -0
  288. package/src/api/index.test.ts +30 -0
  289. package/src/api/index.ts +149 -0
  290. package/src/bridge/broadcast.ts +5 -10
  291. package/src/bridge/buildOptimisticOperation.integration.test.ts +8 -8
  292. package/src/bridge/buildOptimisticOperation.ts +13 -10
  293. package/src/bridge/createTransaction.ts +3 -1
  294. package/src/bridge/estimateMaxSpendable.ts +6 -3
  295. package/src/bridge/getTransactionStatus.test.ts +11 -10
  296. package/src/bridge/getTransactionStatus.ts +12 -11
  297. package/src/bridge/js-estimateMaxSpendable.integration.test.ts +6 -3
  298. package/src/bridge/prepareTransaction.test.ts +9 -17
  299. package/src/bridge/prepareTransaction.ts +5 -4
  300. package/src/bridge/serialization.test.ts +6 -6
  301. package/src/bridge/signOperation.ts +69 -16
  302. package/src/bridge/synchronisation.ts +22 -14
  303. package/src/bridge/utils.integration.test.ts +19 -248
  304. package/src/bridge/utils.ts +14 -160
  305. package/src/config.ts +7 -0
  306. package/src/constants.ts +15 -9
  307. package/src/deviceTransactionConfig.ts +4 -4
  308. package/src/logic/broadcast.test.ts +58 -0
  309. package/src/logic/broadcast.ts +8 -0
  310. package/src/logic/combine.test.ts +119 -0
  311. package/src/logic/combine.ts +14 -0
  312. package/src/logic/craftTransaction.test.ts +215 -0
  313. package/src/logic/craftTransaction.ts +175 -0
  314. package/src/logic/estimateFees.test.ts +99 -0
  315. package/src/logic/estimateFees.ts +28 -0
  316. package/src/logic/getAssetFromToken.test.ts +27 -0
  317. package/src/logic/getAssetFromToken.ts +12 -0
  318. package/src/logic/getBalance.test.ts +200 -0
  319. package/src/logic/getBalance.ts +39 -0
  320. package/src/logic/getTokenFromAsset.test.ts +22 -0
  321. package/src/logic/getTokenFromAsset.ts +17 -0
  322. package/src/logic/index.ts +9 -0
  323. package/src/logic/lastBlock.test.ts +23 -0
  324. package/src/logic/lastBlock.ts +23 -0
  325. package/src/logic/listOperations.test.ts +388 -0
  326. package/src/logic/listOperations.ts +247 -0
  327. package/src/logic/utils.test.ts +432 -0
  328. package/src/logic/utils.ts +255 -0
  329. package/src/{api/mirror.test.ts → network/api.test.ts} +81 -35
  330. package/src/network/api.ts +159 -0
  331. package/src/network/rpc.test.ts +68 -0
  332. package/src/network/rpc.ts +25 -0
  333. package/src/network/utils.test.ts +175 -0
  334. package/src/network/utils.ts +58 -0
  335. package/src/test/bridgeDatasetTest.ts +6 -2
  336. package/src/test/fixtures/account.fixture.ts +18 -0
  337. package/src/test/fixtures/currency.fixture.ts +1 -1
  338. package/src/test/fixtures/mirror.fixture.ts +1 -1
  339. package/src/test/fixtures/network.fixture.ts +6 -0
  340. package/src/test/fixtures/transaction.fixture.ts +5 -2
  341. package/src/transaction.ts +40 -9
  342. package/src/types/alpaca.ts +3 -0
  343. package/src/types/bridge.ts +36 -10
  344. package/src/types/index.ts +2 -0
  345. package/src/{api/types.ts → types/mirror.ts} +23 -1
  346. package/lib/api/mirror.d.ts +0 -6
  347. package/lib/api/mirror.d.ts.map +0 -1
  348. package/lib/api/mirror.js +0 -84
  349. package/lib/api/mirror.js.map +0 -1
  350. package/lib/api/network.d.ts +0 -11
  351. package/lib/api/network.d.ts.map +0 -1
  352. package/lib/api/network.js +0 -80
  353. package/lib/api/network.js.map +0 -1
  354. package/lib/api/types.d.ts.map +0 -1
  355. package/lib/api/types.js.map +0 -1
  356. package/lib/api/utils.d.ts.map +0 -1
  357. package/lib/api/utils.js +0 -132
  358. package/lib/api/utils.js.map +0 -1
  359. package/lib/logic.d.ts +0 -11
  360. package/lib/logic.d.ts.map +0 -1
  361. package/lib/logic.js +0 -37
  362. package/lib/logic.js.map +0 -1
  363. package/lib-es/api/mirror.d.ts +0 -6
  364. package/lib-es/api/mirror.d.ts.map +0 -1
  365. package/lib-es/api/mirror.js +0 -74
  366. package/lib-es/api/mirror.js.map +0 -1
  367. package/lib-es/api/network.d.ts +0 -11
  368. package/lib-es/api/network.d.ts.map +0 -1
  369. package/lib-es/api/network.js +0 -71
  370. package/lib-es/api/network.js.map +0 -1
  371. package/lib-es/api/types.d.ts.map +0 -1
  372. package/lib-es/api/types.js +0 -2
  373. package/lib-es/api/types.js.map +0 -1
  374. package/lib-es/api/utils.d.ts.map +0 -1
  375. package/lib-es/api/utils.js +0 -124
  376. package/lib-es/api/utils.js.map +0 -1
  377. package/lib-es/logic.d.ts +0 -11
  378. package/lib-es/logic.d.ts.map +0 -1
  379. package/lib-es/logic.js +0 -29
  380. package/lib-es/logic.js.map +0 -1
  381. package/src/api/mirror.ts +0 -91
  382. package/src/api/network.test.ts +0 -49
  383. package/src/api/network.ts +0 -125
  384. package/src/api/utils.ts +0 -150
  385. package/src/logic.test.ts +0 -152
  386. package/src/logic.ts +0 -66
@@ -1,30 +1,25 @@
1
- import network from "@ledgerhq/live-network/network";
2
- import { getAccount, getAccountTokens, getAccountTransactions } from "./mirror";
1
+ import network from "@ledgerhq/live-network";
2
+ import { apiClient } from "./api";
3
+ import { getMockResponse } from "../test/fixtures/network.fixture";
3
4
 
4
- jest.mock("@ledgerhq/live-network/network");
5
+ jest.mock("@ledgerhq/live-network");
5
6
  const mockedNetwork = jest.mocked(network);
6
7
 
7
- const makeMockResponse = (data: any): Awaited<ReturnType<typeof network>> => ({
8
- data,
9
- status: 200,
10
- statusText: "OK",
11
- headers: {},
12
- config: {
13
- headers: {} as any,
14
- },
15
- });
16
-
17
8
  describe("getAccountTransactions", () => {
18
9
  beforeEach(() => {
19
- jest.clearAllMocks();
10
+ jest.resetAllMocks();
20
11
  });
21
12
 
22
13
  test("should include 'account.id', 'limit=100' and 'order=desc' query params", async () => {
23
14
  mockedNetwork.mockResolvedValueOnce(
24
- makeMockResponse({ transactions: [], links: { next: null } }),
15
+ getMockResponse({ transactions: [], links: { next: null } }),
25
16
  );
26
17
 
27
- await getAccountTransactions("0.0.1234", null);
18
+ await apiClient.getAccountTransactions({
19
+ address: "0.0.1234",
20
+ pagingToken: null,
21
+ fetchAllPages: true,
22
+ });
28
23
 
29
24
  const requestUrl = mockedNetwork.mock.calls[0][0].url;
30
25
  expect(requestUrl).toContain("account.id=0.0.1234");
@@ -32,55 +27,106 @@ describe("getAccountTransactions", () => {
32
27
  expect(requestUrl).toContain("order=desc");
33
28
  });
34
29
 
35
- test("should keep fetching if links.next is present", async () => {
30
+ test("should keep fetching if fetchAllPages is set and links.next is present", async () => {
36
31
  mockedNetwork
37
32
  .mockResolvedValueOnce(
38
- makeMockResponse({
33
+ getMockResponse({
39
34
  transactions: [{ consensus_timestamp: "1" }],
40
35
  links: { next: "/next-1" },
41
36
  }),
42
37
  )
43
38
  .mockResolvedValueOnce(
44
- makeMockResponse({
39
+ getMockResponse({
45
40
  transactions: [],
46
41
  links: { next: "/next-2" },
47
42
  }),
48
43
  )
49
44
  .mockResolvedValueOnce(
50
- makeMockResponse({
45
+ getMockResponse({
51
46
  transactions: [{ consensus_timestamp: "3" }],
52
47
  links: { next: "/next-3" },
53
48
  }),
54
49
  )
55
50
  .mockResolvedValueOnce(
56
- makeMockResponse({
57
- transactions: [],
51
+ getMockResponse({
52
+ transactions: [{ consensus_timestamp: "4" }],
58
53
  links: { next: "/next-4" },
59
54
  }),
60
55
  )
61
56
  .mockResolvedValueOnce(
62
- makeMockResponse({
57
+ getMockResponse({
63
58
  transactions: [],
64
59
  links: { next: null },
65
60
  }),
66
61
  );
67
62
 
68
- const result = await getAccountTransactions("0.0.1234", null);
63
+ const result = await apiClient.getAccountTransactions({
64
+ address: "0.0.1234",
65
+ pagingToken: null,
66
+ fetchAllPages: true,
67
+ });
69
68
 
70
- expect(result).toHaveLength(2);
71
- expect(result.map(tx => tx.consensus_timestamp)).toEqual(["1", "3"]);
69
+ expect(result.transactions).toHaveLength(3);
70
+ expect(result.transactions.map(tx => tx.consensus_timestamp)).toEqual(["1", "3", "4"]);
71
+ expect(result.nextCursor).toBeNull();
72
72
  expect(mockedNetwork).toHaveBeenCalledTimes(5);
73
73
  });
74
+
75
+ test("should paginate if fetchAllPages is not set", async () => {
76
+ mockedNetwork
77
+ .mockResolvedValueOnce(
78
+ getMockResponse({
79
+ transactions: [{ consensus_timestamp: "1" }],
80
+ links: { next: "/next-1" },
81
+ }),
82
+ )
83
+ .mockResolvedValueOnce(
84
+ getMockResponse({
85
+ transactions: [],
86
+ links: { next: "/next-2" },
87
+ }),
88
+ )
89
+ .mockResolvedValueOnce(
90
+ getMockResponse({
91
+ transactions: [{ consensus_timestamp: "3" }],
92
+ links: { next: "/next-3" },
93
+ }),
94
+ )
95
+ .mockResolvedValueOnce(
96
+ getMockResponse({
97
+ transactions: [{ consensus_timestamp: "4" }],
98
+ links: { next: "/next-4" },
99
+ }),
100
+ )
101
+ .mockResolvedValueOnce(
102
+ getMockResponse({
103
+ transactions: [],
104
+ links: { next: null },
105
+ }),
106
+ );
107
+
108
+ const result = await apiClient.getAccountTransactions({
109
+ address: "0.0.1234",
110
+ pagingToken: null,
111
+ limit: 2,
112
+ fetchAllPages: false,
113
+ });
114
+
115
+ expect(result.transactions).toHaveLength(2);
116
+ expect(result.transactions.map(tx => tx.consensus_timestamp)).toEqual(["1", "3"]);
117
+ expect(result.nextCursor).toBe("3");
118
+ expect(mockedNetwork).toHaveBeenCalledTimes(3);
119
+ });
74
120
  });
75
121
 
76
122
  describe("getAccount", () => {
77
123
  beforeEach(() => {
78
- jest.clearAllMocks();
124
+ jest.resetAllMocks();
79
125
  });
80
126
 
81
127
  it("should call the correct endpoint and return account data", async () => {
82
128
  mockedNetwork.mockResolvedValueOnce(
83
- makeMockResponse({
129
+ getMockResponse({
84
130
  account: "0.0.1234",
85
131
  max_automatic_token_associations: 0,
86
132
  balance: {
@@ -91,7 +137,7 @@ describe("getAccount", () => {
91
137
  }),
92
138
  );
93
139
 
94
- const result = await getAccount("0.0.1234");
140
+ const result = await apiClient.getAccount("0.0.1234");
95
141
  const requestUrl = mockedNetwork.mock.calls[0][0].url;
96
142
 
97
143
  expect(result.account).toEqual("0.0.1234");
@@ -102,12 +148,12 @@ describe("getAccount", () => {
102
148
 
103
149
  describe("getAccountTokens", () => {
104
150
  beforeEach(() => {
105
- jest.clearAllMocks();
151
+ jest.resetAllMocks();
106
152
  });
107
153
 
108
154
  it("should return all tokens if only one page is needed", async () => {
109
155
  mockedNetwork.mockResolvedValueOnce(
110
- makeMockResponse({
156
+ getMockResponse({
111
157
  tokens: [
112
158
  { token_id: "0.0.1001", balance: 10 },
113
159
  { token_id: "0.0.1002", balance: 20 },
@@ -116,7 +162,7 @@ describe("getAccountTokens", () => {
116
162
  }),
117
163
  );
118
164
 
119
- const result = await getAccountTokens("0.0.1234");
165
+ const result = await apiClient.getAccountTokens("0.0.1234");
120
166
  const requestUrl = mockedNetwork.mock.calls[0][0].url;
121
167
 
122
168
  expect(result.map(t => t.token_id)).toEqual(["0.0.1001", "0.0.1002"]);
@@ -128,19 +174,19 @@ describe("getAccountTokens", () => {
128
174
  it("should keep fetching if links.next is present and new tokens are returned", async () => {
129
175
  mockedNetwork
130
176
  .mockResolvedValueOnce(
131
- makeMockResponse({
177
+ getMockResponse({
132
178
  tokens: [{ token_id: "0.0.1001", balance: 10 }],
133
179
  links: { next: "/next-1" },
134
180
  }),
135
181
  )
136
182
  .mockResolvedValueOnce(
137
- makeMockResponse({
183
+ getMockResponse({
138
184
  tokens: [{ token_id: "0.0.1002", balance: 20 }],
139
185
  links: { next: null },
140
186
  }),
141
187
  );
142
188
 
143
- const result = await getAccountTokens("0.0.1234");
189
+ const result = await apiClient.getAccountTokens("0.0.1234");
144
190
 
145
191
  expect(result.map(t => t.token_id)).toEqual(["0.0.1001", "0.0.1002"]);
146
192
  expect(mockedNetwork).toHaveBeenCalledTimes(2);
@@ -0,0 +1,159 @@
1
+ import network from "@ledgerhq/live-network";
2
+ import type { LiveNetworkResponse } from "@ledgerhq/live-network/network";
3
+ import { getEnv } from "@ledgerhq/live-env";
4
+ import { LedgerAPI4xx } from "@ledgerhq/errors";
5
+ import { HederaAddAccountError } from "../errors";
6
+ import type {
7
+ HederaMirrorAccountTokensResponse,
8
+ HederaMirrorTransactionsResponse,
9
+ HederaMirrorAccount,
10
+ HederaMirrorAccountsResponse,
11
+ HederaMirrorToken,
12
+ HederaMirrorTransaction,
13
+ } from "../types";
14
+
15
+ const getMirrorApiUrl = (): string => getEnv("API_HEDERA_MIRROR");
16
+
17
+ const fetch = <Result>(path: string) => {
18
+ return network<Result>({
19
+ method: "GET",
20
+ url: `${getMirrorApiUrl()}${path}`,
21
+ });
22
+ };
23
+
24
+ async function getAccountsForPublicKey(publicKey: string): Promise<HederaMirrorAccount[]> {
25
+ let res;
26
+ try {
27
+ res = await fetch<HederaMirrorAccountsResponse>(
28
+ `/api/v1/accounts?account.publicKey=${publicKey}&balance=true&limit=100`,
29
+ );
30
+ } catch (e: unknown) {
31
+ if (e instanceof LedgerAPI4xx) return [];
32
+ throw e;
33
+ }
34
+
35
+ const accounts = res.data.accounts;
36
+
37
+ return accounts;
38
+ }
39
+
40
+ async function getAccount(address: string): Promise<HederaMirrorAccount> {
41
+ try {
42
+ const res = await fetch<HederaMirrorAccount>(`/api/v1/accounts/${address}`);
43
+ const account = res.data;
44
+
45
+ return account;
46
+ } catch (error) {
47
+ if (error instanceof LedgerAPI4xx && "status" in error && error.status === 404) {
48
+ throw new HederaAddAccountError();
49
+ }
50
+
51
+ throw error;
52
+ }
53
+ }
54
+
55
+ async function getAccountTransactions({
56
+ address,
57
+ pagingToken,
58
+ limit = 100,
59
+ order = "desc",
60
+ fetchAllPages,
61
+ }: {
62
+ address: string;
63
+ pagingToken: string | null;
64
+ limit?: number | undefined;
65
+ order?: "asc" | "desc" | undefined;
66
+ fetchAllPages: boolean;
67
+ }): Promise<{ transactions: HederaMirrorTransaction[]; nextCursor: string | null }> {
68
+ const transactions: HederaMirrorTransaction[] = [];
69
+ const params = new URLSearchParams({
70
+ "account.id": address,
71
+ limit: limit.toString(),
72
+ order,
73
+ });
74
+
75
+ // keeps old behavior when all pages are fetched
76
+ const getTimestampDirection = () => {
77
+ if (fetchAllPages) return "gt";
78
+ return order === "asc" ? "gt" : "lt";
79
+ };
80
+
81
+ if (pagingToken) {
82
+ params.append("timestamp", `${getTimestampDirection()}:${pagingToken}`);
83
+ }
84
+
85
+ let nextCursor: string | null = null;
86
+ let nextUrl: string | null = `/api/v1/transactions?${params.toString()}`;
87
+
88
+ // WARNING: don't break the loop when `transactions` array is empty but `links.next` is present
89
+ // the mirror node API enforces a 60-day max time range per query, even if `timestamp` param is set
90
+ // see: https://hedera.com/blog/changes-to-the-hedera-operated-mirror-node
91
+ while (nextUrl) {
92
+ const res: LiveNetworkResponse<HederaMirrorTransactionsResponse> = await fetch(nextUrl);
93
+ const newTransactions = res.data.transactions;
94
+ transactions.push(...newTransactions);
95
+ nextUrl = res.data.links.next;
96
+
97
+ // stop fetching if pagination mode is used and we reached the limit
98
+ if (!fetchAllPages && transactions.length >= limit) {
99
+ break;
100
+ }
101
+ }
102
+
103
+ // ensure we don't exceed the limit in pagination mode
104
+ if (!fetchAllPages && transactions.length > limit) {
105
+ transactions.splice(limit);
106
+ }
107
+
108
+ // set the next cursor only if we have more transactions to fetch
109
+ if (!fetchAllPages && nextUrl) {
110
+ const lastTx = transactions.at(-1);
111
+ nextCursor = lastTx?.consensus_timestamp ?? null;
112
+ }
113
+
114
+ return { transactions, nextCursor };
115
+ }
116
+
117
+ async function getAccountTokens(address: string): Promise<HederaMirrorToken[]> {
118
+ const tokens: HederaMirrorToken[] = [];
119
+ const params = new URLSearchParams({
120
+ limit: "100",
121
+ });
122
+
123
+ let nextUrl: string | null = `/api/v1/accounts/${address}/tokens?${params.toString()}`;
124
+
125
+ while (nextUrl) {
126
+ const res: LiveNetworkResponse<HederaMirrorAccountTokensResponse> = await fetch(nextUrl);
127
+ const newTokens = res.data.tokens;
128
+ tokens.push(...newTokens);
129
+ nextUrl = res.data.links.next;
130
+ }
131
+
132
+ return tokens;
133
+ }
134
+
135
+ async function getLatestTransaction(): Promise<HederaMirrorTransaction> {
136
+ const params = new URLSearchParams({
137
+ limit: "1",
138
+ order: "desc",
139
+ });
140
+
141
+ const res = await fetch<HederaMirrorTransactionsResponse>(
142
+ `/api/v1/transactions?${params.toString()}`,
143
+ );
144
+ const transaction = res.data.transactions[0];
145
+
146
+ if (!transaction) {
147
+ throw new Error("No transactions found on the Hedera network");
148
+ }
149
+
150
+ return transaction;
151
+ }
152
+
153
+ export const apiClient = {
154
+ getAccountsForPublicKey,
155
+ getAccount,
156
+ getAccountTokens,
157
+ getAccountTransactions,
158
+ getLatestTransaction,
159
+ };
@@ -0,0 +1,68 @@
1
+ import { Client, Transaction, TransactionResponse } from "@hashgraph/sdk";
2
+ import { rpcClient } from "./rpc";
3
+
4
+ const mockClient = {
5
+ setMaxNodesPerTransaction: jest.fn().mockReturnThis(),
6
+ setNetwork: jest.fn().mockReturnThis(),
7
+ } as unknown as Client;
8
+
9
+ jest.mock("@hashgraph/sdk", () => {
10
+ return {
11
+ Transaction: jest.fn(),
12
+ Client: {
13
+ forMainnet: jest.fn(() => mockClient),
14
+ },
15
+ };
16
+ });
17
+
18
+ describe("getInstance", () => {
19
+ beforeEach(() => {
20
+ jest.clearAllMocks();
21
+ rpcClient._resetInstance();
22
+ });
23
+
24
+ it("returns cached client instance for multiple calls", () => {
25
+ const client1 = rpcClient.getInstance();
26
+ const client2 = rpcClient.getInstance();
27
+
28
+ expect(Client.forMainnet).toHaveBeenCalledTimes(1);
29
+ expect(client1).toBe(mockClient);
30
+ expect(client2).toBe(client1);
31
+ });
32
+ });
33
+
34
+ describe("broadcastTransaction", () => {
35
+ beforeEach(() => {
36
+ jest.clearAllMocks();
37
+ rpcClient._resetInstance();
38
+ });
39
+
40
+ it("executes the transaction using the client", async () => {
41
+ const expectedResponse = { transactionId: "test-tx-id" } as unknown as TransactionResponse;
42
+ const mockedExecute = jest.fn().mockResolvedValue(expectedResponse);
43
+ const mockTransaction = { execute: mockedExecute } as unknown as Transaction;
44
+
45
+ const response = await rpcClient.broadcastTransaction(mockTransaction);
46
+
47
+ expect(mockedExecute).toHaveBeenCalledTimes(1);
48
+ expect(mockedExecute).toHaveBeenCalledWith(mockClient);
49
+ expect(response).toBe(expectedResponse);
50
+ });
51
+
52
+ it("reuses the same client instance for multiple calls", async () => {
53
+ const mockedExecute1 = jest.fn();
54
+ const mockedExecute2 = jest.fn();
55
+
56
+ const mockTransaction1 = { execute: mockedExecute1 } as unknown as Transaction;
57
+ const mockTransaction2 = { execute: mockedExecute2 } as unknown as Transaction;
58
+
59
+ await rpcClient.broadcastTransaction(mockTransaction1);
60
+ await rpcClient.broadcastTransaction(mockTransaction2);
61
+
62
+ expect(Client.forMainnet).toHaveBeenCalledTimes(1);
63
+ expect(mockedExecute1).toHaveBeenCalledTimes(1);
64
+ expect(mockedExecute2).toHaveBeenCalledTimes(1);
65
+ expect(mockedExecute1).toHaveBeenCalledWith(mockClient);
66
+ expect(mockedExecute2).toHaveBeenCalledWith(mockClient);
67
+ });
68
+ });
@@ -0,0 +1,25 @@
1
+ import type { Transaction as HederaTransaction, TransactionResponse } from "@hashgraph/sdk";
2
+ import { Client } from "@hashgraph/sdk";
3
+
4
+ function broadcastTransaction(transaction: HederaTransaction): Promise<TransactionResponse> {
5
+ return transaction.execute(getInstance());
6
+ }
7
+
8
+ let _hederaClient: Client | null = null;
9
+
10
+ function getInstance(): Client {
11
+ _hederaClient ??= Client.forMainnet().setMaxNodesPerTransaction(1);
12
+
13
+ return _hederaClient;
14
+ }
15
+
16
+ // for testing purposes only, used to reset singleton client instance
17
+ function _resetInstance() {
18
+ _hederaClient = null;
19
+ }
20
+
21
+ export const rpcClient = {
22
+ getInstance,
23
+ broadcastTransaction,
24
+ _resetInstance,
25
+ };
@@ -0,0 +1,175 @@
1
+ import BigNumber from "bignumber.js";
2
+ import type { HederaMirrorCoinTransfer, HederaMirrorTokenTransfer } from "../types";
3
+ import { parseTransfers } from "./utils";
4
+
5
+ const createMirrorCoinTransfer = (account: string, amount: number): HederaMirrorCoinTransfer => ({
6
+ account,
7
+ amount,
8
+ });
9
+
10
+ const createMirrorTokenTransfer = (
11
+ account: string,
12
+ amount: number,
13
+ tokenId: string,
14
+ ): HederaMirrorTokenTransfer => ({
15
+ token_id: tokenId,
16
+ account,
17
+ amount,
18
+ });
19
+
20
+ describe("parseTransfers", () => {
21
+ it("should correctly identify an incoming transfer", () => {
22
+ const userAddress = "0.0.1234";
23
+ const transfers = [
24
+ createMirrorCoinTransfer("0.0.5678", -100),
25
+ createMirrorCoinTransfer(userAddress, 100),
26
+ ];
27
+
28
+ const result = parseTransfers(transfers, userAddress);
29
+
30
+ expect(result.type).toBe("IN");
31
+ expect(result.value).toEqual(new BigNumber(100));
32
+ expect(result.senders).toEqual(["0.0.5678"]);
33
+ expect(result.recipients).toEqual([userAddress]);
34
+ });
35
+
36
+ it("should correctly identify an outgoing transfer", () => {
37
+ const userAddress = "0.0.1234";
38
+ const transfers = [
39
+ createMirrorCoinTransfer(userAddress, -100),
40
+ createMirrorCoinTransfer("0.0.5678", 100),
41
+ ];
42
+
43
+ const result = parseTransfers(transfers, userAddress);
44
+
45
+ expect(result.type).toBe("OUT");
46
+ expect(result.value).toEqual(new BigNumber(100));
47
+ expect(result.senders).toEqual([userAddress]);
48
+ expect(result.recipients).toEqual(["0.0.5678"]);
49
+ });
50
+
51
+ it("should handle multiple senders and recipients", () => {
52
+ const userAddress = "0.0.1234";
53
+ const transfers = [
54
+ createMirrorCoinTransfer("0.0.5678", -50),
55
+ createMirrorCoinTransfer(userAddress, -50),
56
+ createMirrorCoinTransfer("0.0.9999", 100),
57
+ ];
58
+
59
+ const result = parseTransfers(transfers, userAddress);
60
+
61
+ expect(result.type).toBe("OUT");
62
+ expect(result.value).toEqual(new BigNumber(50));
63
+ expect(result.senders).toEqual(["0.0.1234", "0.0.5678"]);
64
+ expect(result.recipients).toEqual(["0.0.9999"]);
65
+ });
66
+
67
+ it("should correctly process token transfers", () => {
68
+ const userAddress = "0.0.1234";
69
+ const tokenId = "0.0.7777";
70
+ const transfers = [
71
+ createMirrorTokenTransfer(userAddress, -10, tokenId),
72
+ createMirrorTokenTransfer("0.0.5678", 10, tokenId),
73
+ ];
74
+
75
+ const result = parseTransfers(transfers, userAddress);
76
+
77
+ expect(result.type).toBe("OUT");
78
+ expect(result.value).toEqual(new BigNumber(10));
79
+ expect(result.senders).toEqual([userAddress]);
80
+ expect(result.recipients).toEqual(["0.0.5678"]);
81
+ });
82
+
83
+ it("should exclude system accounts that are not nodes from recipients", () => {
84
+ const userAddress = "0.0.1234";
85
+ const systemAccount = "0.0.500";
86
+ const transfers = [
87
+ createMirrorCoinTransfer(userAddress, -100),
88
+ createMirrorCoinTransfer(systemAccount, 100),
89
+ ];
90
+
91
+ const result = parseTransfers(transfers, userAddress);
92
+
93
+ expect(result.type).toBe("OUT");
94
+ expect(result.value).toEqual(new BigNumber(100));
95
+ expect(result.senders).toEqual([userAddress]);
96
+ expect(result.recipients).toEqual([]);
97
+ });
98
+
99
+ it("should include node accounts as recipients only if no other recipients", () => {
100
+ const userAddress = "0.0.1234";
101
+ const nodeAccount = "0.0.3";
102
+ const transfers = [
103
+ createMirrorCoinTransfer(userAddress, -100),
104
+ createMirrorCoinTransfer(nodeAccount, 100),
105
+ ];
106
+
107
+ const result = parseTransfers(transfers, userAddress);
108
+
109
+ expect(result.type).toBe("OUT");
110
+ expect(result.value).toEqual(new BigNumber(100));
111
+ expect(result.senders).toEqual([userAddress]);
112
+ expect(result.recipients).toEqual([nodeAccount]);
113
+ });
114
+
115
+ it("should exclude node accounts if there are other recipients", () => {
116
+ const userAddress = "0.0.1234";
117
+ const normalAccount = "0.0.5678";
118
+ const nodeAccount = "0.0.3";
119
+ const transfers = [
120
+ createMirrorCoinTransfer(userAddress, -100),
121
+ createMirrorCoinTransfer(normalAccount, 50),
122
+ createMirrorCoinTransfer(nodeAccount, 50),
123
+ ];
124
+
125
+ const result = parseTransfers(transfers, userAddress);
126
+
127
+ expect(result.type).toBe("OUT");
128
+ expect(result.value).toEqual(new BigNumber(100));
129
+ expect(result.senders).toEqual([userAddress]);
130
+ expect(result.recipients).toEqual([normalAccount]);
131
+ });
132
+
133
+ it("should handle transactions where user is not involved", () => {
134
+ const userAddress = "0.0.1234";
135
+ const transfers = [
136
+ createMirrorCoinTransfer("0.0.5678", -100),
137
+ createMirrorCoinTransfer("0.0.9999", 100),
138
+ ];
139
+
140
+ const result = parseTransfers(transfers, userAddress);
141
+
142
+ expect(result.type).toBe("NONE");
143
+ expect(result.value).toEqual(new BigNumber(0));
144
+ expect(result.senders).toEqual(["0.0.5678"]);
145
+ expect(result.recipients).toEqual(["0.0.9999"]);
146
+ });
147
+
148
+ it("should handle empty transfers array", () => {
149
+ const userAddress = "0.0.1234";
150
+ const transfers: HederaMirrorCoinTransfer[] = [];
151
+
152
+ const result = parseTransfers(transfers, userAddress);
153
+
154
+ expect(result.type).toBe("NONE");
155
+ expect(result.value).toEqual(new BigNumber(0));
156
+ expect(result.senders).toEqual([]);
157
+ expect(result.recipients).toEqual([]);
158
+ });
159
+
160
+ it("should reverse the order of senders and recipients", () => {
161
+ const userAddress = "0.0.1234";
162
+ const transfers = [
163
+ createMirrorCoinTransfer("0.0.900", -5),
164
+ createMirrorCoinTransfer("0.0.5678", -95),
165
+ createMirrorCoinTransfer(userAddress, 100),
166
+ ];
167
+
168
+ const result = parseTransfers(transfers, userAddress);
169
+
170
+ expect(result.type).toBe("IN");
171
+ expect(result.value).toEqual(new BigNumber(100));
172
+ expect(result.senders).toEqual(["0.0.5678", "0.0.900"]);
173
+ expect(result.recipients).toEqual([userAddress]);
174
+ });
175
+ });
@@ -0,0 +1,58 @@
1
+ import BigNumber from "bignumber.js";
2
+ import { AccountId } from "@hashgraph/sdk";
3
+ import type { Operation, OperationType } from "@ledgerhq/types-live";
4
+ import type { HederaMirrorTokenTransfer, HederaMirrorCoinTransfer } from "../types";
5
+
6
+ function isValidRecipient(accountId: AccountId, recipients: string[]): boolean {
7
+ if (accountId.shard.eq(0) && accountId.realm.eq(0)) {
8
+ // account is a node, only add to list if we have none
9
+ if (accountId.num.lt(100)) {
10
+ return recipients.length === 0;
11
+ }
12
+
13
+ // account is a system account that is not a node, do NOT add
14
+ if (accountId.num.lt(1000)) {
15
+ return false;
16
+ }
17
+ }
18
+
19
+ return true;
20
+ }
21
+
22
+ export function parseTransfers(
23
+ mirrorTransfers: (HederaMirrorCoinTransfer | HederaMirrorTokenTransfer)[],
24
+ address: string,
25
+ ): Pick<Operation, "type" | "value" | "senders" | "recipients"> {
26
+ let value = new BigNumber(0);
27
+ let type: OperationType = "NONE";
28
+
29
+ const senders: string[] = [];
30
+ const recipients: string[] = [];
31
+
32
+ for (const transfer of mirrorTransfers) {
33
+ const amount = new BigNumber(transfer.amount);
34
+ const accountId = AccountId.fromString(transfer.account);
35
+
36
+ if (transfer.account === address) {
37
+ value = amount.abs();
38
+ type = amount.isNegative() ? "OUT" : "IN";
39
+ }
40
+
41
+ if (amount.isNegative()) {
42
+ senders.push(transfer.account);
43
+ } else if (isValidRecipient(accountId, recipients)) {
44
+ recipients.push(transfer.account);
45
+ }
46
+ }
47
+
48
+ // NOTE: earlier addresses are the "fee" addresses
49
+ senders.reverse();
50
+ recipients.reverse();
51
+
52
+ return {
53
+ type,
54
+ value,
55
+ senders,
56
+ recipients,
57
+ };
58
+ }