@ledgerhq/coin-multiversx 0.2.0-next.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 (378) hide show
  1. package/.eslintrc.js +23 -0
  2. package/.turbo/turbo-build.log +4 -0
  3. package/.unimportedrc.json +31 -0
  4. package/CHANGELOG.md +400 -0
  5. package/LICENSE.txt +21 -0
  6. package/jest.config.js +8 -0
  7. package/lib/api/apiCalls.d.ts +22 -0
  8. package/lib/api/apiCalls.d.ts.map +1 -0
  9. package/lib/api/apiCalls.js +153 -0
  10. package/lib/api/apiCalls.js.map +1 -0
  11. package/lib/api/dtos/multiversx-account.d.ts +9 -0
  12. package/lib/api/dtos/multiversx-account.d.ts.map +1 -0
  13. package/lib/api/dtos/multiversx-account.js +17 -0
  14. package/lib/api/dtos/multiversx-account.js.map +1 -0
  15. package/lib/api/index.d.ts +2 -0
  16. package/lib/api/index.d.ts.map +1 -0
  17. package/lib/api/index.js +16 -0
  18. package/lib/api/index.js.map +1 -0
  19. package/lib/api/sdk.d.ts +29 -0
  20. package/lib/api/sdk.d.ts.map +1 -0
  21. package/lib/api/sdk.js +281 -0
  22. package/lib/api/sdk.js.map +1 -0
  23. package/lib/bridge/js.d.ts +11 -0
  24. package/lib/bridge/js.d.ts.map +1 -0
  25. package/lib/bridge/js.js +62 -0
  26. package/lib/bridge/js.js.map +1 -0
  27. package/lib/bridge.integration.test.d.ts +4 -0
  28. package/lib/bridge.integration.test.d.ts.map +1 -0
  29. package/lib/bridge.integration.test.js +142 -0
  30. package/lib/bridge.integration.test.js.map +1 -0
  31. package/lib/broadcast.d.ts +9 -0
  32. package/lib/broadcast.d.ts.map +1 -0
  33. package/lib/broadcast.js +16 -0
  34. package/lib/broadcast.js.map +1 -0
  35. package/lib/buildOptimisticOperation.d.ts +4 -0
  36. package/lib/buildOptimisticOperation.d.ts.map +1 -0
  37. package/lib/buildOptimisticOperation.js +100 -0
  38. package/lib/buildOptimisticOperation.js.map +1 -0
  39. package/lib/buildOptimisticOperation.test.d.ts +2 -0
  40. package/lib/buildOptimisticOperation.test.d.ts.map +1 -0
  41. package/lib/buildOptimisticOperation.test.js +78 -0
  42. package/lib/buildOptimisticOperation.test.js.map +1 -0
  43. package/lib/buildSubAccounts.d.ts +11 -0
  44. package/lib/buildSubAccounts.d.ts.map +1 -0
  45. package/lib/buildSubAccounts.js +117 -0
  46. package/lib/buildSubAccounts.js.map +1 -0
  47. package/lib/buildTransaction.d.ts +19 -0
  48. package/lib/buildTransaction.d.ts.map +1 -0
  49. package/lib/buildTransaction.js +49 -0
  50. package/lib/buildTransaction.js.map +1 -0
  51. package/lib/buildTransaction.unit.test.d.ts +2 -0
  52. package/lib/buildTransaction.unit.test.d.ts.map +1 -0
  53. package/lib/buildTransaction.unit.test.js +47 -0
  54. package/lib/buildTransaction.unit.test.js.map +1 -0
  55. package/lib/cli-transaction.d.ts +16 -0
  56. package/lib/cli-transaction.d.ts.map +1 -0
  57. package/lib/cli-transaction.js +35 -0
  58. package/lib/cli-transaction.js.map +1 -0
  59. package/lib/config.d.ts +14 -0
  60. package/lib/config.d.ts.map +1 -0
  61. package/lib/config.js +16 -0
  62. package/lib/config.js.map +1 -0
  63. package/lib/constants.d.ts +21 -0
  64. package/lib/constants.d.ts.map +1 -0
  65. package/lib/constants.js +27 -0
  66. package/lib/constants.js.map +1 -0
  67. package/lib/createTransaction.d.ts +9 -0
  68. package/lib/createTransaction.d.ts.map +1 -0
  69. package/lib/createTransaction.js +26 -0
  70. package/lib/createTransaction.js.map +1 -0
  71. package/lib/datasets/multiversx1.d.ts +3 -0
  72. package/lib/datasets/multiversx1.d.ts.map +1 -0
  73. package/lib/datasets/multiversx1.js +21 -0
  74. package/lib/datasets/multiversx1.js.map +1 -0
  75. package/lib/deviceTransactionConfig.d.ts +10 -0
  76. package/lib/deviceTransactionConfig.d.ts.map +1 -0
  77. package/lib/deviceTransactionConfig.js +60 -0
  78. package/lib/deviceTransactionConfig.js.map +1 -0
  79. package/lib/encode.d.ts +11 -0
  80. package/lib/encode.d.ts.map +1 -0
  81. package/lib/encode.js +39 -0
  82. package/lib/encode.js.map +1 -0
  83. package/lib/errors.d.ts +16 -0
  84. package/lib/errors.d.ts.map +1 -0
  85. package/lib/errors.js +10 -0
  86. package/lib/errors.js.map +1 -0
  87. package/lib/estimateMaxSpendable.d.ts +10 -0
  88. package/lib/estimateMaxSpendable.d.ts.map +1 -0
  89. package/lib/estimateMaxSpendable.js +35 -0
  90. package/lib/estimateMaxSpendable.js.map +1 -0
  91. package/lib/formatters.d.ts +11 -0
  92. package/lib/formatters.d.ts.map +1 -0
  93. package/lib/formatters.js +65 -0
  94. package/lib/formatters.js.map +1 -0
  95. package/lib/getTransactionStatus.d.ts +5 -0
  96. package/lib/getTransactionStatus.d.ts.map +1 -0
  97. package/lib/getTransactionStatus.js +107 -0
  98. package/lib/getTransactionStatus.js.map +1 -0
  99. package/lib/helpers/denominate.d.ts +9 -0
  100. package/lib/helpers/denominate.d.ts.map +1 -0
  101. package/lib/helpers/denominate.js +75 -0
  102. package/lib/helpers/denominate.js.map +1 -0
  103. package/lib/helpers/handleTransactionStatus.d.ts +7 -0
  104. package/lib/helpers/handleTransactionStatus.d.ts.map +1 -0
  105. package/lib/helpers/handleTransactionStatus.js +18 -0
  106. package/lib/helpers/handleTransactionStatus.js.map +1 -0
  107. package/lib/helpers/hasMinimumDelegableBalance.d.ts +3 -0
  108. package/lib/helpers/hasMinimumDelegableBalance.d.ts.map +1 -0
  109. package/lib/helpers/hasMinimumDelegableBalance.js +7 -0
  110. package/lib/helpers/hasMinimumDelegableBalance.js.map +1 -0
  111. package/lib/helpers/randomizeProviders.d.ts +7 -0
  112. package/lib/helpers/randomizeProviders.d.ts.map +1 -0
  113. package/lib/helpers/randomizeProviders.js +12 -0
  114. package/lib/helpers/randomizeProviders.js.map +1 -0
  115. package/lib/hw-getAddress.d.ts +6 -0
  116. package/lib/hw-getAddress.d.ts.map +1 -0
  117. package/lib/hw-getAddress.js +14 -0
  118. package/lib/hw-getAddress.js.map +1 -0
  119. package/lib/logic.d.ts +15 -0
  120. package/lib/logic.d.ts.map +1 -0
  121. package/lib/logic.js +77 -0
  122. package/lib/logic.js.map +1 -0
  123. package/lib/preload.d.ts +11 -0
  124. package/lib/preload.d.ts.map +1 -0
  125. package/lib/preload.js +94 -0
  126. package/lib/preload.js.map +1 -0
  127. package/lib/prepareTransaction.d.ts +10 -0
  128. package/lib/prepareTransaction.d.ts.map +1 -0
  129. package/lib/prepareTransaction.js +72 -0
  130. package/lib/prepareTransaction.js.map +1 -0
  131. package/lib/reconciliation.d.ts +3 -0
  132. package/lib/reconciliation.d.ts.map +1 -0
  133. package/lib/reconciliation.js +56 -0
  134. package/lib/reconciliation.js.map +1 -0
  135. package/lib/serialization.d.ts +9 -0
  136. package/lib/serialization.d.ts.map +1 -0
  137. package/lib/serialization.js +65 -0
  138. package/lib/serialization.js.map +1 -0
  139. package/lib/signOperation.d.ts +10 -0
  140. package/lib/signOperation.d.ts.map +1 -0
  141. package/lib/signOperation.js +65 -0
  142. package/lib/signOperation.js.map +1 -0
  143. package/lib/signer.d.ts +16 -0
  144. package/lib/signer.d.ts.map +1 -0
  145. package/lib/signer.js +3 -0
  146. package/lib/signer.js.map +1 -0
  147. package/lib/specs.d.ts +7 -0
  148. package/lib/specs.d.ts.map +1 -0
  149. package/lib/specs.js +286 -0
  150. package/lib/specs.js.map +1 -0
  151. package/lib/speculos-deviceActions.d.ts +16 -0
  152. package/lib/speculos-deviceActions.d.ts.map +1 -0
  153. package/lib/speculos-deviceActions.js +250 -0
  154. package/lib/speculos-deviceActions.js.map +1 -0
  155. package/lib/synchronisation.d.ts +5 -0
  156. package/lib/synchronisation.d.ts.map +1 -0
  157. package/lib/synchronisation.js +69 -0
  158. package/lib/synchronisation.js.map +1 -0
  159. package/lib/transaction.d.ts +15 -0
  160. package/lib/transaction.d.ts.map +1 -0
  161. package/lib/transaction.js +62 -0
  162. package/lib/transaction.js.map +1 -0
  163. package/lib/types.d.ts +188 -0
  164. package/lib/types.d.ts.map +1 -0
  165. package/lib/types.js +17 -0
  166. package/lib/types.js.map +1 -0
  167. package/lib/utils/binary.utils.d.ts +5 -0
  168. package/lib/utils/binary.utils.d.ts.map +1 -0
  169. package/lib/utils/binary.utils.js +16 -0
  170. package/lib/utils/binary.utils.js.map +1 -0
  171. package/lib-es/api/apiCalls.d.ts +22 -0
  172. package/lib-es/api/apiCalls.d.ts.map +1 -0
  173. package/lib-es/api/apiCalls.js +147 -0
  174. package/lib-es/api/apiCalls.js.map +1 -0
  175. package/lib-es/api/dtos/multiversx-account.d.ts +9 -0
  176. package/lib-es/api/dtos/multiversx-account.d.ts.map +1 -0
  177. package/lib-es/api/dtos/multiversx-account.js +13 -0
  178. package/lib-es/api/dtos/multiversx-account.js.map +1 -0
  179. package/lib-es/api/index.d.ts +2 -0
  180. package/lib-es/api/index.d.ts.map +1 -0
  181. package/lib-es/api/index.js +2 -0
  182. package/lib-es/api/index.js.map +1 -0
  183. package/lib-es/api/sdk.d.ts +29 -0
  184. package/lib-es/api/sdk.d.ts.map +1 -0
  185. package/lib-es/api/sdk.js +264 -0
  186. package/lib-es/api/sdk.js.map +1 -0
  187. package/lib-es/bridge/js.d.ts +11 -0
  188. package/lib-es/bridge/js.d.ts.map +1 -0
  189. package/lib-es/bridge/js.js +53 -0
  190. package/lib-es/bridge/js.js.map +1 -0
  191. package/lib-es/bridge.integration.test.d.ts +4 -0
  192. package/lib-es/bridge.integration.test.d.ts.map +1 -0
  193. package/lib-es/bridge.integration.test.js +139 -0
  194. package/lib-es/bridge.integration.test.js.map +1 -0
  195. package/lib-es/broadcast.d.ts +9 -0
  196. package/lib-es/broadcast.d.ts.map +1 -0
  197. package/lib-es/broadcast.js +12 -0
  198. package/lib-es/broadcast.js.map +1 -0
  199. package/lib-es/buildOptimisticOperation.d.ts +4 -0
  200. package/lib-es/buildOptimisticOperation.d.ts.map +1 -0
  201. package/lib-es/buildOptimisticOperation.js +93 -0
  202. package/lib-es/buildOptimisticOperation.js.map +1 -0
  203. package/lib-es/buildOptimisticOperation.test.d.ts +2 -0
  204. package/lib-es/buildOptimisticOperation.test.d.ts.map +1 -0
  205. package/lib-es/buildOptimisticOperation.test.js +73 -0
  206. package/lib-es/buildOptimisticOperation.test.js.map +1 -0
  207. package/lib-es/buildSubAccounts.d.ts +11 -0
  208. package/lib-es/buildSubAccounts.d.ts.map +1 -0
  209. package/lib-es/buildSubAccounts.js +112 -0
  210. package/lib-es/buildSubAccounts.js.map +1 -0
  211. package/lib-es/buildTransaction.d.ts +19 -0
  212. package/lib-es/buildTransaction.d.ts.map +1 -0
  213. package/lib-es/buildTransaction.js +44 -0
  214. package/lib-es/buildTransaction.js.map +1 -0
  215. package/lib-es/buildTransaction.unit.test.d.ts +2 -0
  216. package/lib-es/buildTransaction.unit.test.d.ts.map +1 -0
  217. package/lib-es/buildTransaction.unit.test.js +42 -0
  218. package/lib-es/buildTransaction.unit.test.js.map +1 -0
  219. package/lib-es/cli-transaction.d.ts +16 -0
  220. package/lib-es/cli-transaction.d.ts.map +1 -0
  221. package/lib-es/cli-transaction.js +29 -0
  222. package/lib-es/cli-transaction.js.map +1 -0
  223. package/lib-es/config.d.ts +14 -0
  224. package/lib-es/config.d.ts.map +1 -0
  225. package/lib-es/config.js +11 -0
  226. package/lib-es/config.js.map +1 -0
  227. package/lib-es/constants.d.ts +21 -0
  228. package/lib-es/constants.d.ts.map +1 -0
  229. package/lib-es/constants.js +21 -0
  230. package/lib-es/constants.js.map +1 -0
  231. package/lib-es/createTransaction.d.ts +9 -0
  232. package/lib-es/createTransaction.d.ts.map +1 -0
  233. package/lib-es/createTransaction.js +19 -0
  234. package/lib-es/createTransaction.js.map +1 -0
  235. package/lib-es/datasets/multiversx1.d.ts +3 -0
  236. package/lib-es/datasets/multiversx1.d.ts.map +1 -0
  237. package/lib-es/datasets/multiversx1.js +18 -0
  238. package/lib-es/datasets/multiversx1.js.map +1 -0
  239. package/lib-es/deviceTransactionConfig.d.ts +10 -0
  240. package/lib-es/deviceTransactionConfig.d.ts.map +1 -0
  241. package/lib-es/deviceTransactionConfig.js +55 -0
  242. package/lib-es/deviceTransactionConfig.js.map +1 -0
  243. package/lib-es/encode.d.ts +11 -0
  244. package/lib-es/encode.d.ts.map +1 -0
  245. package/lib-es/encode.js +35 -0
  246. package/lib-es/encode.js.map +1 -0
  247. package/lib-es/errors.d.ts +16 -0
  248. package/lib-es/errors.d.ts.map +1 -0
  249. package/lib-es/errors.js +7 -0
  250. package/lib-es/errors.js.map +1 -0
  251. package/lib-es/estimateMaxSpendable.d.ts +10 -0
  252. package/lib-es/estimateMaxSpendable.d.ts.map +1 -0
  253. package/lib-es/estimateMaxSpendable.js +31 -0
  254. package/lib-es/estimateMaxSpendable.js.map +1 -0
  255. package/lib-es/formatters.d.ts +11 -0
  256. package/lib-es/formatters.d.ts.map +1 -0
  257. package/lib-es/formatters.js +60 -0
  258. package/lib-es/formatters.js.map +1 -0
  259. package/lib-es/getTransactionStatus.d.ts +5 -0
  260. package/lib-es/getTransactionStatus.d.ts.map +1 -0
  261. package/lib-es/getTransactionStatus.js +100 -0
  262. package/lib-es/getTransactionStatus.js.map +1 -0
  263. package/lib-es/helpers/denominate.d.ts +9 -0
  264. package/lib-es/helpers/denominate.d.ts.map +1 -0
  265. package/lib-es/helpers/denominate.js +71 -0
  266. package/lib-es/helpers/denominate.js.map +1 -0
  267. package/lib-es/helpers/handleTransactionStatus.d.ts +7 -0
  268. package/lib-es/helpers/handleTransactionStatus.d.ts.map +1 -0
  269. package/lib-es/helpers/handleTransactionStatus.js +14 -0
  270. package/lib-es/helpers/handleTransactionStatus.js.map +1 -0
  271. package/lib-es/helpers/hasMinimumDelegableBalance.d.ts +3 -0
  272. package/lib-es/helpers/hasMinimumDelegableBalance.d.ts.map +1 -0
  273. package/lib-es/helpers/hasMinimumDelegableBalance.js +3 -0
  274. package/lib-es/helpers/hasMinimumDelegableBalance.js.map +1 -0
  275. package/lib-es/helpers/randomizeProviders.d.ts +7 -0
  276. package/lib-es/helpers/randomizeProviders.d.ts.map +1 -0
  277. package/lib-es/helpers/randomizeProviders.js +8 -0
  278. package/lib-es/helpers/randomizeProviders.js.map +1 -0
  279. package/lib-es/hw-getAddress.d.ts +6 -0
  280. package/lib-es/hw-getAddress.d.ts.map +1 -0
  281. package/lib-es/hw-getAddress.js +12 -0
  282. package/lib-es/hw-getAddress.js.map +1 -0
  283. package/lib-es/logic.d.ts +15 -0
  284. package/lib-es/logic.d.ts.map +1 -0
  285. package/lib-es/logic.js +65 -0
  286. package/lib-es/logic.js.map +1 -0
  287. package/lib-es/preload.d.ts +11 -0
  288. package/lib-es/preload.d.ts.map +1 -0
  289. package/lib-es/preload.js +85 -0
  290. package/lib-es/preload.js.map +1 -0
  291. package/lib-es/prepareTransaction.d.ts +10 -0
  292. package/lib-es/prepareTransaction.d.ts.map +1 -0
  293. package/lib-es/prepareTransaction.js +68 -0
  294. package/lib-es/prepareTransaction.js.map +1 -0
  295. package/lib-es/reconciliation.d.ts +3 -0
  296. package/lib-es/reconciliation.d.ts.map +1 -0
  297. package/lib-es/reconciliation.js +52 -0
  298. package/lib-es/reconciliation.js.map +1 -0
  299. package/lib-es/serialization.d.ts +9 -0
  300. package/lib-es/serialization.d.ts.map +1 -0
  301. package/lib-es/serialization.js +53 -0
  302. package/lib-es/serialization.js.map +1 -0
  303. package/lib-es/signOperation.d.ts +10 -0
  304. package/lib-es/signOperation.d.ts.map +1 -0
  305. package/lib-es/signOperation.js +61 -0
  306. package/lib-es/signOperation.js.map +1 -0
  307. package/lib-es/signer.d.ts +16 -0
  308. package/lib-es/signer.d.ts.map +1 -0
  309. package/lib-es/signer.js +2 -0
  310. package/lib-es/signer.js.map +1 -0
  311. package/lib-es/specs.d.ts +7 -0
  312. package/lib-es/specs.d.ts.map +1 -0
  313. package/lib-es/specs.js +281 -0
  314. package/lib-es/specs.js.map +1 -0
  315. package/lib-es/speculos-deviceActions.d.ts +16 -0
  316. package/lib-es/speculos-deviceActions.d.ts.map +1 -0
  317. package/lib-es/speculos-deviceActions.js +244 -0
  318. package/lib-es/speculos-deviceActions.js.map +1 -0
  319. package/lib-es/synchronisation.d.ts +5 -0
  320. package/lib-es/synchronisation.d.ts.map +1 -0
  321. package/lib-es/synchronisation.js +62 -0
  322. package/lib-es/synchronisation.js.map +1 -0
  323. package/lib-es/transaction.d.ts +15 -0
  324. package/lib-es/transaction.d.ts.map +1 -0
  325. package/lib-es/transaction.js +56 -0
  326. package/lib-es/transaction.js.map +1 -0
  327. package/lib-es/types.d.ts +188 -0
  328. package/lib-es/types.d.ts.map +1 -0
  329. package/lib-es/types.js +12 -0
  330. package/lib-es/types.js.map +1 -0
  331. package/lib-es/utils/binary.utils.d.ts +5 -0
  332. package/lib-es/utils/binary.utils.d.ts.map +1 -0
  333. package/lib-es/utils/binary.utils.js +12 -0
  334. package/lib-es/utils/binary.utils.js.map +1 -0
  335. package/package.json +86 -0
  336. package/src/__snapshots__/bridge.integration.test.ts.snap +181 -0
  337. package/src/api/apiCalls.ts +243 -0
  338. package/src/api/dtos/multiversx-account.ts +20 -0
  339. package/src/api/index.ts +13 -0
  340. package/src/api/sdk.ts +368 -0
  341. package/src/bridge/js.ts +77 -0
  342. package/src/bridge.integration.test.ts +147 -0
  343. package/src/broadcast.ts +16 -0
  344. package/src/buildOptimisticOperation.test.ts +88 -0
  345. package/src/buildOptimisticOperation.ts +120 -0
  346. package/src/buildSubAccounts.ts +153 -0
  347. package/src/buildTransaction.ts +67 -0
  348. package/src/buildTransaction.unit.test.ts +49 -0
  349. package/src/cli-transaction.ts +41 -0
  350. package/src/config.ts +26 -0
  351. package/src/constants.ts +24 -0
  352. package/src/createTransaction.ts +21 -0
  353. package/src/datasets/multiversx1.ts +19 -0
  354. package/src/deviceTransactionConfig.ts +74 -0
  355. package/src/encode.ts +46 -0
  356. package/src/errors.ts +19 -0
  357. package/src/estimateMaxSpendable.ts +43 -0
  358. package/src/formatters.ts +76 -0
  359. package/src/getTransactionStatus.ts +151 -0
  360. package/src/helpers/denominate.ts +95 -0
  361. package/src/helpers/handleTransactionStatus.ts +26 -0
  362. package/src/helpers/hasMinimumDelegableBalance.ts +6 -0
  363. package/src/helpers/randomizeProviders.ts +20 -0
  364. package/src/hw-getAddress.ts +19 -0
  365. package/src/logic.ts +83 -0
  366. package/src/preload.ts +95 -0
  367. package/src/prepareTransaction.ts +78 -0
  368. package/src/reconciliation.ts +64 -0
  369. package/src/serialization.ts +72 -0
  370. package/src/signOperation.ts +99 -0
  371. package/src/signer.ts +21 -0
  372. package/src/specs.ts +387 -0
  373. package/src/speculos-deviceActions.ts +269 -0
  374. package/src/synchronisation.ts +74 -0
  375. package/src/transaction.ts +76 -0
  376. package/src/types.ts +235 -0
  377. package/src/utils/binary.utils.ts +13 -0
  378. package/tsconfig.json +13 -0
@@ -0,0 +1,49 @@
1
+ import BigNumber from "bignumber.js";
2
+ import { doBuildTransactionToSign } from "./buildTransaction";
3
+
4
+ describe("doBuildTransactionToSign", () => {
5
+ it("should serialize transaction without data field", async () => {
6
+ const serializedTransaction = await doBuildTransactionToSign({
7
+ transaction: {
8
+ family: "multiversx",
9
+ mode: "send",
10
+ fees: null,
11
+ amount: new BigNumber("1"),
12
+ recipient: "erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th",
13
+ gasLimit: 50000000,
14
+ },
15
+ sender: "erd1spyavw0956vq68xj8y4tenjpq2wd5a9p2c6j8gsz7ztyrnpxrruqzu66jx",
16
+ nonce: 1,
17
+ value: "0",
18
+ minGasLimit: 50000000,
19
+ chainID: "1",
20
+ });
21
+
22
+ expect(serializedTransaction).toEqual(
23
+ `{"nonce":1,"value":"0","receiver":"erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th","sender":"erd1spyavw0956vq68xj8y4tenjpq2wd5a9p2c6j8gsz7ztyrnpxrruqzu66jx","gasPrice":1000000000,"gasLimit":50000000,"chainID":"1","version":2,"options":1}`,
24
+ );
25
+ });
26
+
27
+ it("should serialize transaction with data field", async () => {
28
+ const serializedTransaction = await doBuildTransactionToSign({
29
+ transaction: {
30
+ family: "multiversx",
31
+ mode: "send",
32
+ fees: null,
33
+ amount: new BigNumber("1"),
34
+ recipient: "erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th",
35
+ data: Buffer.from("ESDTTransfer@55544b2d326638306539@0de0b6b3a7640000").toString("base64"),
36
+ gasLimit: 50000000,
37
+ },
38
+ sender: "erd1spyavw0956vq68xj8y4tenjpq2wd5a9p2c6j8gsz7ztyrnpxrruqzu66jx",
39
+ nonce: 1,
40
+ value: "0",
41
+ minGasLimit: 50000000,
42
+ chainID: "1",
43
+ });
44
+
45
+ expect(serializedTransaction).toEqual(
46
+ `{"nonce":1,"value":"0","receiver":"erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th","sender":"erd1spyavw0956vq68xj8y4tenjpq2wd5a9p2c6j8gsz7ztyrnpxrruqzu66jx","gasPrice":1000000000,"gasLimit":50000000,"data":"RVNEVFRyYW5zZmVyQDU1NTQ0YjJkMzI2NjM4MzA2NTM5QDBkZTBiNmIzYTc2NDAwMDA=","chainID":"1","version":2,"options":1}`,
47
+ );
48
+ });
49
+ });
@@ -0,0 +1,41 @@
1
+ import type { AccountLike } from "@ledgerhq/types-live";
2
+ import invariant from "invariant";
3
+ import flatMap from "lodash/flatMap";
4
+ import type { MultiversXAccount, Transaction } from "./types";
5
+ const options = [
6
+ {
7
+ name: "mode",
8
+ type: String,
9
+ desc: "mode of transaction: send, delegate, unDelegate, claimRewards",
10
+ },
11
+ ];
12
+
13
+ function inferTransactions(
14
+ transactions: Array<{
15
+ account: AccountLike;
16
+ transaction: Transaction;
17
+ }>,
18
+ _opts: Record<string, any>,
19
+ ): Transaction[] {
20
+ return flatMap(transactions, ({ transaction, account }) => {
21
+ invariant(transaction.family === "multiversx", "multiversx family");
22
+
23
+ if (account.type === "Account") {
24
+ invariant((account as MultiversXAccount).multiversxResources, "unactivated account");
25
+ }
26
+
27
+ transaction.family = "multiversx";
28
+
29
+ return {
30
+ ...transaction,
31
+ mode: _opts.mode || "send",
32
+ };
33
+ });
34
+ }
35
+
36
+ export default function makeCliTools() {
37
+ return {
38
+ options,
39
+ inferTransactions,
40
+ };
41
+ }
package/src/config.ts ADDED
@@ -0,0 +1,26 @@
1
+ import { CurrencyConfig } from "@ledgerhq/coin-framework/config";
2
+
3
+ export type MultiversXCoinConfig = () => CurrencyConfig & {
4
+ config_currency_multiversx: {
5
+ type: "object";
6
+ default: {
7
+ status: {
8
+ type: "active";
9
+ };
10
+ };
11
+ };
12
+ };
13
+
14
+ let coinConfig: MultiversXCoinConfig | undefined;
15
+
16
+ export const setCoinConfig = (config: MultiversXCoinConfig): void => {
17
+ coinConfig = config;
18
+ };
19
+
20
+ export const getCoinConfig = (): ReturnType<MultiversXCoinConfig> => {
21
+ if (!coinConfig?.()) {
22
+ throw new Error("MultiversX module config not set");
23
+ }
24
+
25
+ return coinConfig();
26
+ };
@@ -0,0 +1,24 @@
1
+ import BigNumber from "bignumber.js";
2
+
3
+ export const TRANSACTION_OPTIONS_TX_HASH_SIGN = 0b0001;
4
+ export const TRANSACTION_VERSION_DEFAULT = 2;
5
+ export const METACHAIN_SHARD = 4294967295;
6
+ export const MAX_PAGINATION_SIZE = 50;
7
+ export const GAS = {
8
+ ESDT_TRANSFER: 500000,
9
+ DELEGATE: 75000000,
10
+ CLAIM: 6000000,
11
+ };
12
+ export const GAS_PRICE = 1000000000;
13
+ export const MIN_GAS_LIMIT = 50000;
14
+ export const GAS_PER_DATA_BYTE = 1500;
15
+ export const GAS_PRICE_MODIFIER = 0.01;
16
+ export const CHAIN_ID = "1";
17
+ export const MIN_DELEGATION_AMOUNT: BigNumber = new BigNumber("1000000000000000000");
18
+ export const DECIMALS_LIMIT = 18;
19
+
20
+ export const MULTIVERSX_EXPLORER_URL = "https://explorer.multiversx.com";
21
+ export const MULTIVERSX_STAKING_POOL =
22
+ "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqplllst77y4l";
23
+ export const MULTIVERSX_LEDGER_VALIDATOR_ADDRESS =
24
+ "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqppllllls9ftvxy";
@@ -0,0 +1,21 @@
1
+ import BigNumber from "bignumber.js";
2
+ import { AccountBridge } from "@ledgerhq/types-live";
3
+ import { MIN_GAS_LIMIT } from "./constants";
4
+ import { Transaction } from "./types";
5
+
6
+ /**
7
+ * Create an empty t
8
+ *
9
+ * @returns {Transaction}
10
+ */
11
+ export const createTransaction: AccountBridge<Transaction>["createTransaction"] = () => {
12
+ return {
13
+ family: "multiversx",
14
+ mode: "send",
15
+ amount: new BigNumber(0),
16
+ recipient: "",
17
+ useAllAmount: false,
18
+ fees: new BigNumber(50000),
19
+ gasLimit: MIN_GAS_LIMIT,
20
+ };
21
+ };
@@ -0,0 +1,19 @@
1
+ import { AccountRaw } from "@ledgerhq/types-live";
2
+
3
+ export const multiversx1: AccountRaw = {
4
+ id: "js:2:multiversx:erd1rnq7m8kdrpyfany4fweqtydsk4pgx0l6dtl6tvcad5wesagruxts62e9rk:",
5
+ seedIdentifier: "erd1rnq7m8kdrpyfany4fweqtydsk4pgx0l6dtl6tvcad5wesagruxts62e9rk",
6
+ name: "MultiversX 1",
7
+ derivationMode: "",
8
+ index: 0,
9
+ freshAddress: "erd1rnq7m8kdrpyfany4fweqtydsk4pgx0l6dtl6tvcad5wesagruxts62e9rk",
10
+ freshAddressPath: "44'/508'/0'/0'/0'",
11
+ pendingOperations: [],
12
+ operations: [],
13
+ // currencyId: "multiversx",
14
+ currencyId: "elrond",
15
+ balance: "",
16
+ blockHeight: 0,
17
+ lastSyncDate: "",
18
+ xpub: "",
19
+ };
@@ -0,0 +1,74 @@
1
+ import type { CommonDeviceTransactionField as DeviceTransactionField } from "@ledgerhq/coin-framework/transaction/common";
2
+ import type { TransactionStatus, Transaction } from "./types";
3
+ import BigNumber from "bignumber.js";
4
+ import { formatCurrencyUnit } from "@ledgerhq/coin-framework/currencies";
5
+ import { decodeTokenAccountId, getAccountCurrency } from "@ledgerhq/coin-framework/account";
6
+ import { Account } from "@ledgerhq/types-live";
7
+ import { isAmountSpentFromBalance } from "./logic";
8
+
9
+ function getDeviceTransactionConfig({
10
+ account,
11
+ transaction,
12
+ status: { estimatedFees },
13
+ }: {
14
+ account: Account;
15
+ transaction: Transaction;
16
+ status: TransactionStatus;
17
+ }): Array<DeviceTransactionField> {
18
+ const fields: Array<DeviceTransactionField> = [];
19
+
20
+ const { subAccountId } = transaction;
21
+ const isEsdtTransfer = subAccountId !== undefined && subAccountId !== null;
22
+
23
+ if (isEsdtTransfer) {
24
+ const { token } = decodeTokenAccountId(subAccountId);
25
+
26
+ if (token) {
27
+ fields.push({
28
+ type: "text",
29
+ label: "Token",
30
+ value: token.name,
31
+ });
32
+
33
+ fields.push({
34
+ type: "amount",
35
+ label: "Value",
36
+ });
37
+ }
38
+ }
39
+
40
+ fields.push({
41
+ type: "address",
42
+ label: "Receiver",
43
+ address: transaction.recipient,
44
+ });
45
+
46
+ if (!isEsdtTransfer) {
47
+ if (!isAmountSpentFromBalance(transaction.mode)) {
48
+ fields.push({
49
+ type: "text",
50
+ label: "Amount",
51
+ value: formatCurrencyUnit(getAccountCurrency(account).units[0], new BigNumber(0), {
52
+ showCode: true,
53
+ disableRounding: true,
54
+ }),
55
+ });
56
+ } else {
57
+ fields.push({
58
+ type: "amount",
59
+ label: "Amount",
60
+ });
61
+ }
62
+ }
63
+
64
+ if (!estimatedFees.isZero()) {
65
+ fields.push({
66
+ type: "fees",
67
+ label: "Fee",
68
+ });
69
+ }
70
+
71
+ return fields;
72
+ }
73
+
74
+ export default getDeviceTransactionConfig;
package/src/encode.ts ADDED
@@ -0,0 +1,46 @@
1
+ import { SubAccount } from "@ledgerhq/types-live";
2
+ import { decodeTokenAccountId } from "@ledgerhq/coin-framework/account";
3
+ import type { Transaction } from "./types";
4
+ import { extractTokenId } from "./logic";
5
+
6
+ export class MultiversXEncodeTransaction {
7
+ static ESDTTransfer(t: Transaction, ta: SubAccount): string {
8
+ const { token } = decodeTokenAccountId(ta.id);
9
+ const tokenIdentifierHex = token && extractTokenId(token.id);
10
+ let amountHex = t.useAllAmount ? ta.balance.toString(16) : t.amount.toString(16);
11
+
12
+ //hex amount length must be even so protocol would treat it as an ESDT transfer
13
+ if (amountHex.length % 2 !== 0) {
14
+ amountHex = "0" + amountHex;
15
+ }
16
+
17
+ return Buffer.from(`ESDTTransfer@${tokenIdentifierHex}@${amountHex}`).toString("base64");
18
+ }
19
+
20
+ static delegate(): string {
21
+ return Buffer.from(`delegate`).toString("base64");
22
+ }
23
+
24
+ static claimRewards(): string {
25
+ return Buffer.from(`claimRewards`).toString("base64");
26
+ }
27
+
28
+ static withdraw(): string {
29
+ return Buffer.from(`withdraw`).toString("base64");
30
+ }
31
+
32
+ static reDelegateRewards(): string {
33
+ return Buffer.from(`reDelegateRewards`).toString("base64");
34
+ }
35
+
36
+ static unDelegate(t: Transaction): string {
37
+ let amountHex = t.amount.toString(16);
38
+
39
+ //hex amount length must be even
40
+ if (amountHex.length % 2 !== 0) {
41
+ amountHex = "0" + amountHex;
42
+ }
43
+
44
+ return Buffer.from(`unDelegate@${amountHex}`).toString("base64");
45
+ }
46
+ }
package/src/errors.ts ADDED
@@ -0,0 +1,19 @@
1
+ import { createCustomErrorClass } from "@ledgerhq/errors";
2
+
3
+ export const MultiversXDecimalsLimitReached = createCustomErrorClass(
4
+ "MultiversXDecimalsLimitReached",
5
+ );
6
+
7
+ export const MultiversXMinDelegatedAmountError = createCustomErrorClass(
8
+ "MultiversXMinDelegatedAmountError",
9
+ );
10
+
11
+ export const MultiversXMinUndelegatedAmountError = createCustomErrorClass(
12
+ "MultiversXMinUndelegatedAmountError",
13
+ );
14
+
15
+ export const MultiversXDelegationBelowMinimumError = createCustomErrorClass(
16
+ "MultiversXDelegationBelowMinimumError",
17
+ );
18
+
19
+ export const NotEnoughEGLDForFees = createCustomErrorClass("NotEnoughEGLDForFees");
@@ -0,0 +1,43 @@
1
+ import { BigNumber } from "bignumber.js";
2
+ import type { AccountBridge } from "@ledgerhq/types-live";
3
+ import { findSubAccountById, getMainAccount } from "@ledgerhq/coin-framework/account";
4
+ import type { Transaction } from "./types";
5
+ import { getFees } from "./api";
6
+ import { createTransaction } from "./createTransaction";
7
+
8
+ /**
9
+ * Returns the maximum possible amount for transaction
10
+ *
11
+ * @param {Object} param - the account, parentAccount and transaction
12
+ */
13
+ export const estimateMaxSpendable: AccountBridge<Transaction>["estimateMaxSpendable"] = async ({
14
+ account,
15
+ parentAccount,
16
+ transaction,
17
+ }) => {
18
+ const mainAccount = getMainAccount(account, parentAccount);
19
+ const tx: Transaction = {
20
+ ...createTransaction(account),
21
+ subAccountId: account.type === "Account" ? null : account.id,
22
+ ...transaction,
23
+ useAllAmount: true,
24
+ };
25
+
26
+ const tokenAccount = tx.subAccountId
27
+ ? findSubAccountById(mainAccount, tx.subAccountId)
28
+ : undefined;
29
+
30
+ if (tokenAccount) {
31
+ return tokenAccount.balance;
32
+ }
33
+
34
+ const fees = await getFees(tx);
35
+
36
+ if (fees.gt(mainAccount.spendableBalance)) {
37
+ return new BigNumber(0);
38
+ }
39
+
40
+ return mainAccount.spendableBalance.minus(fees);
41
+ };
42
+
43
+ export default estimateMaxSpendable;
@@ -0,0 +1,76 @@
1
+ import invariant from "invariant";
2
+ import type { Operation } from "@ledgerhq/types-live";
3
+ import { getAccountCurrency } from "@ledgerhq/coin-framework/account";
4
+ import { formatCurrencyUnit } from "@ledgerhq/coin-framework/currencies";
5
+ import type { Unit } from "@ledgerhq/types-cryptoassets";
6
+ import type { MultiversXAccount, MultiversXOperation } from "./types";
7
+ import BigNumber from "bignumber.js";
8
+
9
+ function formatAccountSpecifics(account: MultiversXAccount): string {
10
+ const { multiversxResources } = account;
11
+ invariant(multiversxResources, "multiversx account expected");
12
+ const unit = getAccountCurrency(account).units[0];
13
+ const formatConfig = {
14
+ disableRounding: true,
15
+ alwaysShowSign: false,
16
+ showCode: true,
17
+ };
18
+ let str = " ";
19
+
20
+ if (account.spendableBalance) {
21
+ str += formatCurrencyUnit(unit, account.spendableBalance, formatConfig) + " spendable. ";
22
+ } else {
23
+ str += " 0 spendable.";
24
+ }
25
+
26
+ if (multiversxResources && multiversxResources.nonce) {
27
+ str += "\n nonce : " + multiversxResources.nonce;
28
+ }
29
+
30
+ if (multiversxResources && multiversxResources.delegations) {
31
+ let delegated = new BigNumber(0);
32
+ let undelegating = new BigNumber(0);
33
+ let rewards = new BigNumber(0);
34
+ for (const delegation of multiversxResources.delegations) {
35
+ delegated = delegated.plus(delegation.userActiveStake);
36
+ undelegating = delegation.userUndelegatedList.reduce(
37
+ (sum, undelegation) => sum.plus(undelegation.amount),
38
+ undelegating,
39
+ );
40
+ rewards = rewards.plus(delegation.claimableRewards);
41
+ }
42
+
43
+ str +=
44
+ delegated && delegated.gt(0)
45
+ ? `\n delegated: ${unit ? formatCurrencyUnit(unit, delegated, formatConfig) : delegated}`
46
+ : undelegating && undelegating.gt(0)
47
+ ? `\n undelegating: ${
48
+ unit ? formatCurrencyUnit(unit, undelegating, formatConfig) : undelegating
49
+ }`
50
+ : rewards && rewards.gt(0)
51
+ ? `\n rewards: ${unit ? formatCurrencyUnit(unit, rewards, formatConfig) : rewards}`
52
+ : "";
53
+ }
54
+
55
+ return str;
56
+ }
57
+
58
+ function formatOperationSpecifics(op: Operation, unit: Unit | null | undefined): string {
59
+ const { amount } = (op as MultiversXOperation).extra;
60
+ return amount?.gt && amount.gt(0)
61
+ ? " amount: " +
62
+ `${
63
+ unit
64
+ ? formatCurrencyUnit(unit, new BigNumber(amount), {
65
+ showCode: true,
66
+ disableRounding: true,
67
+ }).padEnd(16)
68
+ : amount
69
+ }`
70
+ : "";
71
+ }
72
+
73
+ export default {
74
+ formatAccountSpecifics,
75
+ formatOperationSpecifics,
76
+ };
@@ -0,0 +1,151 @@
1
+ import BigNumber from "bignumber.js";
2
+ import {
3
+ NotEnoughBalance,
4
+ RecipientRequired,
5
+ InvalidAddress,
6
+ FeeNotLoaded,
7
+ InvalidAddressBecauseDestinationIsAlsoSource,
8
+ FeeTooHigh,
9
+ AmountRequired,
10
+ } from "@ledgerhq/errors";
11
+ import { formatCurrencyUnit } from "@ledgerhq/coin-framework/currencies";
12
+ import { getAccountCurrency } from "@ledgerhq/coin-framework/account";
13
+ import { DECIMALS_LIMIT, MIN_DELEGATION_AMOUNT } from "./constants";
14
+ import type { MultiversXAccount, Transaction, TransactionStatus } from "./types";
15
+ import { isValidAddress, isSelfTransaction, isAmountSpentFromBalance } from "./logic";
16
+ import {
17
+ MultiversXDecimalsLimitReached,
18
+ MultiversXMinDelegatedAmountError,
19
+ MultiversXMinUndelegatedAmountError,
20
+ MultiversXDelegationBelowMinimumError,
21
+ NotEnoughEGLDForFees,
22
+ } from "./errors";
23
+ import { AccountBridge } from "@ledgerhq/types-live";
24
+
25
+ export const getTransactionStatus: AccountBridge<
26
+ Transaction,
27
+ MultiversXAccount,
28
+ TransactionStatus
29
+ >["getTransactionStatus"] = async (account, transaction) => {
30
+ const errors: Record<string, Error> = {};
31
+ const warnings: Record<string, Error> = {};
32
+
33
+ if (!transaction.recipient) {
34
+ errors.recipient = new RecipientRequired();
35
+ } else if (isSelfTransaction(account, transaction)) {
36
+ errors.recipient = new InvalidAddressBecauseDestinationIsAlsoSource();
37
+ } else if (!isValidAddress(transaction.recipient)) {
38
+ errors.recipient = new InvalidAddress("", {
39
+ currencyName: account.currency.name,
40
+ });
41
+ }
42
+
43
+ if (!transaction.fees) {
44
+ errors.fees = new FeeNotLoaded();
45
+ }
46
+
47
+ if (
48
+ !errors.amount &&
49
+ transaction.amount.eq(0) &&
50
+ !transaction.useAllAmount &&
51
+ !["unDelegate", "withdraw", "reDelegateRewards", "claimRewards"].includes(transaction.mode)
52
+ ) {
53
+ errors.amount = new AmountRequired();
54
+ }
55
+
56
+ let totalSpent = new BigNumber(0); // Will be in token amount for token transactions
57
+ let totalSpentEgld = new BigNumber(0); // Amount spent in main currency (EGLD)
58
+
59
+ const tokenAccount =
60
+ (transaction.subAccountId &&
61
+ account.subAccounts &&
62
+ account.subAccounts.find(ta => ta.id === transaction.subAccountId)) ||
63
+ null;
64
+
65
+ if (tokenAccount) {
66
+ totalSpent = transaction.amount;
67
+ totalSpentEgld = transaction.fees || new BigNumber(0);
68
+
69
+ if (!errors.amount && transaction.amount.gt(tokenAccount.balance)) {
70
+ errors.amount = new NotEnoughBalance();
71
+ }
72
+
73
+ if (!errors.amount && !totalSpentEgld.decimalPlaces(DECIMALS_LIMIT).isEqualTo(totalSpentEgld)) {
74
+ errors.amount = new MultiversXDecimalsLimitReached();
75
+ }
76
+ } else {
77
+ totalSpent = totalSpentEgld = isAmountSpentFromBalance(transaction.mode)
78
+ ? transaction.fees?.plus(transaction.amount) || transaction.amount
79
+ : transaction.fees || new BigNumber(0);
80
+
81
+ if (
82
+ transaction.mode === "send" &&
83
+ transaction.fees &&
84
+ transaction.amount.div(10).lt(transaction.fees)
85
+ ) {
86
+ warnings.feeTooHigh = new FeeTooHigh();
87
+ }
88
+
89
+ // All delegate and undelegate transactions must have an amount >= 1 EGLD
90
+ if (!errors.amount && transaction.amount.lt(MIN_DELEGATION_AMOUNT)) {
91
+ const formattedAmount = formatCurrencyUnit(
92
+ getAccountCurrency(account).units[0],
93
+ MIN_DELEGATION_AMOUNT,
94
+ {
95
+ showCode: true,
96
+ },
97
+ );
98
+ if (transaction.mode === "delegate") {
99
+ errors.amount = new MultiversXMinDelegatedAmountError("", {
100
+ formattedAmount,
101
+ });
102
+ } else if (transaction.mode === "unDelegate") {
103
+ errors.amount = new MultiversXMinUndelegatedAmountError("", {
104
+ formattedAmount,
105
+ });
106
+ }
107
+ }
108
+
109
+ // When undelegating, unless undelegating all, the delegation must remain >= 1 EGLD
110
+ const delegationBalance = account.multiversxResources.delegations.find(
111
+ d => d.contract === transaction.recipient,
112
+ )?.userActiveStake;
113
+
114
+ const delegationRemainingBalance = new BigNumber(delegationBalance || 0).minus(
115
+ transaction.amount,
116
+ );
117
+
118
+ const delegationBalanceForbidden =
119
+ delegationRemainingBalance.gt(0) && delegationRemainingBalance.lt(MIN_DELEGATION_AMOUNT);
120
+
121
+ if (!errors.amount && transaction.mode === "unDelegate" && delegationBalanceForbidden) {
122
+ const formattedAmount = formatCurrencyUnit(
123
+ getAccountCurrency(account).units[0],
124
+ MIN_DELEGATION_AMOUNT,
125
+ {
126
+ showCode: true,
127
+ },
128
+ );
129
+ errors.amount = new MultiversXDelegationBelowMinimumError("", {
130
+ formattedAmount,
131
+ });
132
+ }
133
+ }
134
+
135
+ if (!errors.amount && totalSpentEgld.gt(account.spendableBalance)) {
136
+ errors.amount =
137
+ tokenAccount || !["delegate", "send"].includes(transaction.mode)
138
+ ? new NotEnoughEGLDForFees()
139
+ : new NotEnoughBalance();
140
+ }
141
+
142
+ return {
143
+ errors,
144
+ warnings,
145
+ estimatedFees: transaction.fees || new BigNumber(0),
146
+ amount: transaction.amount,
147
+ totalSpent,
148
+ };
149
+ };
150
+
151
+ export default getTransactionStatus;
@@ -0,0 +1,95 @@
1
+ /*
2
+ * Declare the type of the denomination function's parameters.
3
+ */
4
+
5
+ export interface DenominateType {
6
+ input: string;
7
+ denomination?: number;
8
+ decimals?: number;
9
+ showLastNonZeroDecimal?: boolean;
10
+ addCommas?: boolean;
11
+ }
12
+
13
+ /*
14
+ * Declare function itself and return the denominated value as a string.
15
+ */
16
+
17
+ export const denominate = (parameters: DenominateType) => {
18
+ const { denomination, decimals, showLastNonZeroDecimal = false, addCommas = true } = parameters;
19
+ let { input } = parameters;
20
+
21
+ if (input === "...") {
22
+ return input;
23
+ }
24
+ if (input === "" || input === "0" || input === undefined) {
25
+ input = "0";
26
+ }
27
+
28
+ const format = (
29
+ big: string,
30
+ denomination = 18,
31
+ decimals = 2,
32
+ showLastNonZeroDecimal: boolean,
33
+ addCommas: boolean,
34
+ ) => {
35
+ const showLastNonZeroDecimalCheck =
36
+ typeof showLastNonZeroDecimal !== "undefined" ? showLastNonZeroDecimal : false;
37
+
38
+ let array = big.toString().split("");
39
+ if (denomination !== 0) {
40
+ // make sure we have enough characters
41
+ while (array.length < denomination + 1) {
42
+ array.unshift("0");
43
+ }
44
+ // add our dot
45
+ array.splice(array.length - denomination, 0, ".");
46
+ // make sure there are enough decimals after the dot
47
+ while (array.length - array.indexOf(".") <= decimals) {
48
+ array.push("0");
49
+ }
50
+
51
+ if (showLastNonZeroDecimalCheck) {
52
+ let nonZeroDigitIndex = 0;
53
+ for (let i = array.length - 1; i > 0; i--) {
54
+ if (array[i] !== "0") {
55
+ nonZeroDigitIndex = i + 1;
56
+ break;
57
+ }
58
+ }
59
+ const decimalsIndex = array.indexOf(".") + decimals + 1;
60
+ const sliceIndex = Math.max(decimalsIndex, nonZeroDigitIndex);
61
+ array = array.slice(0, sliceIndex);
62
+ } else {
63
+ // trim unnecessary characters after the dot
64
+ array = array.slice(0, array.indexOf(".") + decimals + 1);
65
+ }
66
+ }
67
+ if (addCommas) {
68
+ // add comas every 3 characters
69
+ array = array.reverse();
70
+ const reference = denomination ? array.length - array.indexOf(".") - 1 : array.length;
71
+ const count = Math.floor(reference / 3);
72
+ for (let i = 1; i <= count; i++) {
73
+ const position = array.indexOf(".") + 3 * i + i;
74
+ if (position !== array.length) {
75
+ array.splice(position, 0, ",");
76
+ }
77
+ }
78
+ array = array.reverse();
79
+ }
80
+
81
+ const allDecimalsZero = array
82
+ .slice(array.indexOf(".") + 1)
83
+ .every(digit => digit.toString() === "0");
84
+
85
+ const string = array.join("");
86
+
87
+ if (allDecimalsZero) {
88
+ return string.split(".")[0];
89
+ }
90
+
91
+ return decimals === 0 ? string.split(".").join("") : string;
92
+ };
93
+
94
+ return format(input, denomination, decimals, showLastNonZeroDecimal, addCommas);
95
+ };