@ledgerhq/coin-hedera 1.10.1 → 1.10.2-nightly.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 (248) hide show
  1. package/.eslintrc.js +1 -0
  2. package/CHANGELOG.md +10 -0
  3. package/lib/api/mirror.d.ts +3 -20
  4. package/lib/api/mirror.d.ts.map +1 -1
  5. package/lib/api/mirror.js +32 -90
  6. package/lib/api/mirror.js.map +1 -1
  7. package/lib/api/mirror.test.js +59 -4
  8. package/lib/api/mirror.test.js.map +1 -1
  9. package/lib/api/network.d.ts +3 -3
  10. package/lib/api/network.d.ts.map +1 -1
  11. package/lib/api/network.js +46 -3
  12. package/lib/api/network.js.map +1 -1
  13. package/lib/api/types.d.ts +44 -0
  14. package/lib/api/types.d.ts.map +1 -0
  15. package/lib/api/types.js +3 -0
  16. package/lib/api/types.js.map +1 -0
  17. package/lib/api/utils.d.ts +8 -0
  18. package/lib/api/utils.d.ts.map +1 -0
  19. package/lib/api/utils.js +132 -0
  20. package/lib/api/utils.js.map +1 -0
  21. package/lib/bridge/broadcast.d.ts.map +1 -1
  22. package/lib/bridge/broadcast.js +2 -0
  23. package/lib/bridge/broadcast.js.map +1 -1
  24. package/lib/bridge/buildOptimisticOperation.d.ts +2 -2
  25. package/lib/bridge/buildOptimisticOperation.d.ts.map +1 -1
  26. package/lib/bridge/buildOptimisticOperation.integration.test.d.ts +2 -0
  27. package/lib/bridge/buildOptimisticOperation.integration.test.d.ts.map +1 -0
  28. package/lib/bridge/buildOptimisticOperation.integration.test.js +82 -0
  29. package/lib/bridge/buildOptimisticOperation.integration.test.js.map +1 -0
  30. package/lib/bridge/buildOptimisticOperation.js +87 -5
  31. package/lib/bridge/buildOptimisticOperation.js.map +1 -1
  32. package/lib/bridge/estimateMaxSpendable.d.ts.map +1 -1
  33. package/lib/bridge/estimateMaxSpendable.js +8 -2
  34. package/lib/bridge/estimateMaxSpendable.js.map +1 -1
  35. package/lib/bridge/getTransactionStatus.d.ts +3 -3
  36. package/lib/bridge/getTransactionStatus.d.ts.map +1 -1
  37. package/lib/bridge/getTransactionStatus.js +116 -23
  38. package/lib/bridge/getTransactionStatus.js.map +1 -1
  39. package/lib/bridge/getTransactionStatus.test.d.ts +2 -0
  40. package/lib/bridge/getTransactionStatus.test.d.ts.map +1 -0
  41. package/lib/bridge/getTransactionStatus.test.js +176 -0
  42. package/lib/bridge/getTransactionStatus.test.js.map +1 -0
  43. package/lib/bridge/index.d.ts +4 -4
  44. package/lib/bridge/index.d.ts.map +1 -1
  45. package/lib/bridge/index.js +9 -6
  46. package/lib/bridge/index.js.map +1 -1
  47. package/lib/bridge/js-estimateMaxSpendable.integration.test.js +28 -44
  48. package/lib/bridge/js-estimateMaxSpendable.integration.test.js.map +1 -1
  49. package/lib/bridge/js-transaction.test.js +10 -49
  50. package/lib/bridge/js-transaction.test.js.map +1 -1
  51. package/lib/bridge/prepareTransaction.d.ts +0 -1
  52. package/lib/bridge/prepareTransaction.d.ts.map +1 -1
  53. package/lib/bridge/prepareTransaction.js +0 -1
  54. package/lib/bridge/prepareTransaction.js.map +1 -1
  55. package/lib/bridge/serialization.d.ts +7 -0
  56. package/lib/bridge/serialization.d.ts.map +1 -0
  57. package/lib/bridge/serialization.js +36 -0
  58. package/lib/bridge/serialization.js.map +1 -0
  59. package/lib/bridge/serialization.test.d.ts +2 -0
  60. package/lib/bridge/serialization.test.d.ts.map +1 -0
  61. package/lib/bridge/serialization.test.js +27 -0
  62. package/lib/bridge/serialization.test.js.map +1 -0
  63. package/lib/bridge/synchronisation.d.ts +3 -3
  64. package/lib/bridge/synchronisation.d.ts.map +1 -1
  65. package/lib/bridge/synchronisation.js +37 -15
  66. package/lib/bridge/synchronisation.js.map +1 -1
  67. package/lib/bridge/transaction.test.js +18 -59
  68. package/lib/bridge/transaction.test.js.map +1 -1
  69. package/lib/bridge/utils.d.ts +22 -8
  70. package/lib/bridge/utils.d.ts.map +1 -1
  71. package/lib/bridge/utils.integration.test.js +415 -73
  72. package/lib/bridge/utils.integration.test.js.map +1 -1
  73. package/lib/bridge/utils.js +300 -15
  74. package/lib/bridge/utils.js.map +1 -1
  75. package/lib/constants.d.ts +32 -0
  76. package/lib/constants.d.ts.map +1 -0
  77. package/lib/constants.js +37 -0
  78. package/lib/constants.js.map +1 -0
  79. package/lib/deviceTransactionConfig.d.ts.map +1 -1
  80. package/lib/deviceTransactionConfig.js +17 -15
  81. package/lib/deviceTransactionConfig.js.map +1 -1
  82. package/lib/logic.d.ts +9 -3
  83. package/lib/logic.d.ts.map +1 -1
  84. package/lib/logic.js +31 -3
  85. package/lib/logic.js.map +1 -1
  86. package/lib/logic.test.js +103 -50
  87. package/lib/logic.test.js.map +1 -1
  88. package/lib/test/fixtures/account.fixture.d.ts +19 -0
  89. package/lib/test/fixtures/account.fixture.d.ts.map +1 -0
  90. package/lib/test/fixtures/account.fixture.js +116 -0
  91. package/lib/test/fixtures/account.fixture.js.map +1 -0
  92. package/lib/test/fixtures/currency.fixture.d.ts +5 -0
  93. package/lib/test/fixtures/currency.fixture.d.ts.map +1 -0
  94. package/lib/test/fixtures/currency.fixture.js +67 -0
  95. package/lib/test/fixtures/currency.fixture.js.map +1 -0
  96. package/lib/test/fixtures/mirror.fixture.d.ts +3 -0
  97. package/lib/test/fixtures/mirror.fixture.d.ts.map +1 -0
  98. package/lib/test/fixtures/mirror.fixture.js +17 -0
  99. package/lib/test/fixtures/mirror.fixture.js.map +1 -0
  100. package/lib/test/fixtures/operation.fixture.d.ts +3 -0
  101. package/lib/test/fixtures/operation.fixture.d.ts.map +1 -0
  102. package/lib/test/fixtures/operation.fixture.js +26 -0
  103. package/lib/test/fixtures/operation.fixture.js.map +1 -0
  104. package/lib/test/fixtures/transaction.fixture.d.ts +4 -0
  105. package/lib/test/fixtures/transaction.fixture.d.ts.map +1 -0
  106. package/lib/test/fixtures/transaction.fixture.js +28 -0
  107. package/lib/test/fixtures/transaction.fixture.js.map +1 -0
  108. package/lib/types/bridge.d.ts +25 -1
  109. package/lib/types/bridge.d.ts.map +1 -1
  110. package/lib-es/api/mirror.d.ts +3 -20
  111. package/lib-es/api/mirror.d.ts.map +1 -1
  112. package/lib-es/api/mirror.js +29 -88
  113. package/lib-es/api/mirror.js.map +1 -1
  114. package/lib-es/api/mirror.test.js +60 -5
  115. package/lib-es/api/mirror.test.js.map +1 -1
  116. package/lib-es/api/network.d.ts +3 -3
  117. package/lib-es/api/network.d.ts.map +1 -1
  118. package/lib-es/api/network.js +44 -4
  119. package/lib-es/api/network.js.map +1 -1
  120. package/lib-es/api/types.d.ts +44 -0
  121. package/lib-es/api/types.d.ts.map +1 -0
  122. package/lib-es/api/types.js +2 -0
  123. package/lib-es/api/types.js.map +1 -0
  124. package/lib-es/api/utils.d.ts +8 -0
  125. package/lib-es/api/utils.d.ts.map +1 -0
  126. package/lib-es/api/utils.js +124 -0
  127. package/lib-es/api/utils.js.map +1 -0
  128. package/lib-es/bridge/broadcast.d.ts.map +1 -1
  129. package/lib-es/bridge/broadcast.js +2 -0
  130. package/lib-es/bridge/broadcast.js.map +1 -1
  131. package/lib-es/bridge/buildOptimisticOperation.d.ts +2 -2
  132. package/lib-es/bridge/buildOptimisticOperation.d.ts.map +1 -1
  133. package/lib-es/bridge/buildOptimisticOperation.integration.test.d.ts +2 -0
  134. package/lib-es/bridge/buildOptimisticOperation.integration.test.d.ts.map +1 -0
  135. package/lib-es/bridge/buildOptimisticOperation.integration.test.js +77 -0
  136. package/lib-es/bridge/buildOptimisticOperation.integration.test.js.map +1 -0
  137. package/lib-es/bridge/buildOptimisticOperation.js +84 -5
  138. package/lib-es/bridge/buildOptimisticOperation.js.map +1 -1
  139. package/lib-es/bridge/estimateMaxSpendable.d.ts.map +1 -1
  140. package/lib-es/bridge/estimateMaxSpendable.js +8 -2
  141. package/lib-es/bridge/estimateMaxSpendable.js.map +1 -1
  142. package/lib-es/bridge/getTransactionStatus.d.ts +3 -3
  143. package/lib-es/bridge/getTransactionStatus.d.ts.map +1 -1
  144. package/lib-es/bridge/getTransactionStatus.js +114 -24
  145. package/lib-es/bridge/getTransactionStatus.js.map +1 -1
  146. package/lib-es/bridge/getTransactionStatus.test.d.ts +2 -0
  147. package/lib-es/bridge/getTransactionStatus.test.d.ts.map +1 -0
  148. package/lib-es/bridge/getTransactionStatus.test.js +148 -0
  149. package/lib-es/bridge/getTransactionStatus.test.js.map +1 -0
  150. package/lib-es/bridge/index.d.ts +4 -4
  151. package/lib-es/bridge/index.d.ts.map +1 -1
  152. package/lib-es/bridge/index.js +9 -6
  153. package/lib-es/bridge/index.js.map +1 -1
  154. package/lib-es/bridge/js-estimateMaxSpendable.integration.test.js +28 -44
  155. package/lib-es/bridge/js-estimateMaxSpendable.integration.test.js.map +1 -1
  156. package/lib-es/bridge/js-transaction.test.js +10 -49
  157. package/lib-es/bridge/js-transaction.test.js.map +1 -1
  158. package/lib-es/bridge/prepareTransaction.d.ts +0 -1
  159. package/lib-es/bridge/prepareTransaction.d.ts.map +1 -1
  160. package/lib-es/bridge/prepareTransaction.js +0 -1
  161. package/lib-es/bridge/prepareTransaction.js.map +1 -1
  162. package/lib-es/bridge/serialization.d.ts +7 -0
  163. package/lib-es/bridge/serialization.d.ts.map +1 -0
  164. package/lib-es/bridge/serialization.js +29 -0
  165. package/lib-es/bridge/serialization.js.map +1 -0
  166. package/lib-es/bridge/serialization.test.d.ts +2 -0
  167. package/lib-es/bridge/serialization.test.d.ts.map +1 -0
  168. package/lib-es/bridge/serialization.test.js +25 -0
  169. package/lib-es/bridge/serialization.test.js.map +1 -0
  170. package/lib-es/bridge/synchronisation.d.ts +3 -3
  171. package/lib-es/bridge/synchronisation.d.ts.map +1 -1
  172. package/lib-es/bridge/synchronisation.js +39 -17
  173. package/lib-es/bridge/synchronisation.js.map +1 -1
  174. package/lib-es/bridge/transaction.test.js +18 -59
  175. package/lib-es/bridge/transaction.test.js.map +1 -1
  176. package/lib-es/bridge/utils.d.ts +22 -8
  177. package/lib-es/bridge/utils.d.ts.map +1 -1
  178. package/lib-es/bridge/utils.integration.test.js +416 -74
  179. package/lib-es/bridge/utils.integration.test.js.map +1 -1
  180. package/lib-es/bridge/utils.js +295 -15
  181. package/lib-es/bridge/utils.js.map +1 -1
  182. package/lib-es/constants.d.ts +32 -0
  183. package/lib-es/constants.d.ts.map +1 -0
  184. package/lib-es/constants.js +34 -0
  185. package/lib-es/constants.js.map +1 -0
  186. package/lib-es/deviceTransactionConfig.d.ts.map +1 -1
  187. package/lib-es/deviceTransactionConfig.js +17 -15
  188. package/lib-es/deviceTransactionConfig.js.map +1 -1
  189. package/lib-es/logic.d.ts +9 -3
  190. package/lib-es/logic.d.ts.map +1 -1
  191. package/lib-es/logic.js +26 -3
  192. package/lib-es/logic.js.map +1 -1
  193. package/lib-es/logic.test.js +104 -51
  194. package/lib-es/logic.test.js.map +1 -1
  195. package/lib-es/test/fixtures/account.fixture.d.ts +19 -0
  196. package/lib-es/test/fixtures/account.fixture.d.ts.map +1 -0
  197. package/lib-es/test/fixtures/account.fixture.js +107 -0
  198. package/lib-es/test/fixtures/account.fixture.js.map +1 -0
  199. package/lib-es/test/fixtures/currency.fixture.d.ts +5 -0
  200. package/lib-es/test/fixtures/currency.fixture.d.ts.map +1 -0
  201. package/lib-es/test/fixtures/currency.fixture.js +58 -0
  202. package/lib-es/test/fixtures/currency.fixture.js.map +1 -0
  203. package/lib-es/test/fixtures/mirror.fixture.d.ts +3 -0
  204. package/lib-es/test/fixtures/mirror.fixture.d.ts.map +1 -0
  205. package/lib-es/test/fixtures/mirror.fixture.js +13 -0
  206. package/lib-es/test/fixtures/mirror.fixture.js.map +1 -0
  207. package/lib-es/test/fixtures/operation.fixture.d.ts +3 -0
  208. package/lib-es/test/fixtures/operation.fixture.d.ts.map +1 -0
  209. package/lib-es/test/fixtures/operation.fixture.js +19 -0
  210. package/lib-es/test/fixtures/operation.fixture.js.map +1 -0
  211. package/lib-es/test/fixtures/transaction.fixture.d.ts +4 -0
  212. package/lib-es/test/fixtures/transaction.fixture.d.ts.map +1 -0
  213. package/lib-es/test/fixtures/transaction.fixture.js +20 -0
  214. package/lib-es/test/fixtures/transaction.fixture.js.map +1 -0
  215. package/lib-es/types/bridge.d.ts +25 -1
  216. package/lib-es/types/bridge.d.ts.map +1 -1
  217. package/package.json +11 -9
  218. package/src/api/mirror.test.ts +79 -5
  219. package/src/api/mirror.ts +30 -111
  220. package/src/api/network.ts +71 -4
  221. package/src/api/types.ts +48 -0
  222. package/src/api/utils.ts +150 -0
  223. package/src/bridge/broadcast.ts +2 -0
  224. package/src/bridge/buildOptimisticOperation.integration.test.ts +88 -0
  225. package/src/bridge/buildOptimisticOperation.ts +118 -7
  226. package/src/bridge/estimateMaxSpendable.ts +8 -2
  227. package/src/bridge/getTransactionStatus.test.ts +200 -0
  228. package/src/bridge/getTransactionStatus.ts +166 -32
  229. package/src/bridge/index.ts +13 -10
  230. package/src/bridge/js-estimateMaxSpendable.integration.test.ts +37 -46
  231. package/src/bridge/js-transaction.test.ts +13 -54
  232. package/src/bridge/prepareTransaction.ts +1 -2
  233. package/src/bridge/serialization.test.ts +39 -0
  234. package/src/bridge/serialization.ts +43 -0
  235. package/src/bridge/synchronisation.ts +65 -27
  236. package/src/bridge/transaction.test.ts +22 -64
  237. package/src/bridge/utils.integration.test.ts +525 -76
  238. package/src/bridge/utils.ts +423 -24
  239. package/src/constants.ts +35 -0
  240. package/src/deviceTransactionConfig.ts +16 -15
  241. package/src/logic.test.ts +147 -57
  242. package/src/logic.ts +58 -7
  243. package/src/test/fixtures/account.fixture.ts +123 -0
  244. package/src/test/fixtures/currency.fixture.ts +66 -0
  245. package/src/test/fixtures/mirror.fixture.ts +14 -0
  246. package/src/test/fixtures/operation.fixture.ts +20 -0
  247. package/src/test/fixtures/transaction.fixture.ts +22 -0
  248. package/src/types/bridge.ts +33 -0
@@ -1,63 +1,54 @@
1
1
  import BigNumber from "bignumber.js";
2
- import type { Account } from "@ledgerhq/types-live";
3
2
  import { createBridges } from ".";
4
3
  import { getEstimatedFees } from "./utils";
5
-
6
- // Balance is 1 Hbar
7
- const account: Account = {
8
- type: "Account",
9
- id: "",
10
- seedIdentifier: "",
11
- derivationMode: "",
12
- index: 0,
13
- freshAddress: "",
14
- freshAddressPath: "",
15
- used: false,
16
- balance: new BigNumber(100000000),
17
- spendableBalance: new BigNumber(0),
18
- creationDate: new Date(),
19
- blockHeight: 0,
20
- currency: {
21
- type: "CryptoCurrency",
22
- id: "hedera",
23
- managerAppName: "",
24
- coinType: 0,
25
- scheme: "",
26
- color: "",
27
- family: "",
28
- explorerViews: [],
29
- name: "",
30
- ticker: "",
31
- units: [],
32
- },
33
- operationsCount: 0,
34
- operations: [],
35
- pendingOperations: [],
36
- lastSyncDate: new Date(),
37
- balanceHistoryCache: {
38
- HOUR: { latestDate: null, balances: [] },
39
- DAY: { latestDate: null, balances: [] },
40
- WEEK: { latestDate: null, balances: [] },
41
- },
42
- swapHistory: [],
43
- };
4
+ import { getMockedAccount, getMockedTokenAccount } from "../test/fixtures/account.fixture";
5
+ import { getMockedTokenCurrency } from "../test/fixtures/currency.fixture";
6
+ import { HEDERA_OPERATION_TYPES } from "../constants";
44
7
 
45
8
  describe("js-estimateMaxSpendable", () => {
46
9
  let bridge: ReturnType<typeof createBridges>;
47
- let estimatedFees = new BigNumber("150200").multipliedBy(2); // 0.001502 ℏ (as of 2023-03-14)
10
+ let estimatedFees: Record<"crypto", BigNumber>;
48
11
 
49
12
  beforeAll(async () => {
50
13
  const signer = jest.fn();
51
14
  bridge = createBridges(signer);
52
- estimatedFees = await getEstimatedFees(account);
15
+
16
+ const mockedAccount = getMockedAccount();
17
+ const crypto = await getEstimatedFees(mockedAccount, HEDERA_OPERATION_TYPES.CryptoTransfer);
18
+
19
+ estimatedFees = { crypto };
20
+ });
21
+
22
+ test("estimateMaxSpendable returns balance minus fee", async () => {
23
+ const mockedAccount = getMockedAccount();
24
+
25
+ const result = await bridge.accountBridge.estimateMaxSpendable({
26
+ account: mockedAccount,
27
+ });
28
+
29
+ expect(result).toEqual(mockedAccount.balance.minus(estimatedFees.crypto));
30
+ });
31
+
32
+ test("estimateMaxSpendable returns 0 if balance < estimated fees", async () => {
33
+ const mockedAccount = getMockedAccount({ balance: estimatedFees.crypto.minus(1) });
34
+
35
+ const result = await bridge.accountBridge.estimateMaxSpendable({
36
+ account: mockedAccount,
37
+ });
38
+
39
+ expect(result).toEqual(new BigNumber(0));
53
40
  });
54
41
 
55
- test("estimateMaxSpendable", async () => {
42
+ test("estimateMaxSpendable returns token balance for token account", async () => {
43
+ const mockedTokenCurrency = getMockedTokenCurrency();
44
+ const mockedTokenAccount = getMockedTokenAccount(mockedTokenCurrency);
45
+ const mockedAccount = getMockedAccount({ subAccounts: [mockedTokenAccount] });
46
+
56
47
  const result = await bridge.accountBridge.estimateMaxSpendable({
57
- account,
48
+ account: mockedTokenAccount,
49
+ parentAccount: mockedAccount,
58
50
  });
59
- const data = account.balance.minus(estimatedFees);
60
51
 
61
- expect(result).toEqual(data);
52
+ expect(result).toEqual(mockedTokenAccount.balance);
62
53
  });
63
54
  });
@@ -1,83 +1,42 @@
1
1
  import BigNumber from "bignumber.js";
2
- import type { Account } from "@ledgerhq/types-live";
3
2
  import { updateTransaction } from "@ledgerhq/coin-framework/bridge/jsHelpers";
4
- import type { Transaction } from "../types";
5
3
  import { createBridges } from ".";
6
-
7
- const account: Account = {
8
- type: "Account",
9
- id: "",
10
- seedIdentifier: "",
11
- derivationMode: "",
12
- index: 0,
13
- freshAddress: "",
14
- freshAddressPath: "",
15
- used: false,
16
- balance: new BigNumber(200000),
17
- spendableBalance: new BigNumber(0),
18
- creationDate: new Date(),
19
- blockHeight: 0,
20
- currency: {
21
- type: "CryptoCurrency",
22
- id: "hedera",
23
- managerAppName: "",
24
- coinType: 0,
25
- scheme: "",
26
- color: "",
27
- family: "",
28
- explorerViews: [],
29
- name: "",
30
- ticker: "",
31
- units: [],
32
- },
33
- operationsCount: 0,
34
- operations: [],
35
- pendingOperations: [],
36
- lastSyncDate: new Date(),
37
- balanceHistoryCache: {
38
- HOUR: { latestDate: null, balances: [] },
39
- DAY: { latestDate: null, balances: [] },
40
- WEEK: { latestDate: null, balances: [] },
41
- },
42
- swapHistory: [],
43
- };
44
-
45
- const transaction: Transaction = {
46
- family: "hedera",
47
- amount: new BigNumber(0),
48
- recipient: "",
49
- useAllAmount: false,
50
- };
4
+ import { getMockedAccount } from "../test/fixtures/account.fixture";
5
+ import { getMockedTransaction } from "../test/fixtures/transaction.fixture";
6
+ import type { Transaction } from "../types";
51
7
 
52
8
  describe("js-transaction", () => {
53
9
  let bridge: ReturnType<typeof createBridges>;
10
+ const mockedAccount = getMockedAccount();
11
+ const mockedTransaction = getMockedTransaction();
54
12
 
55
13
  beforeAll(() => {
56
14
  const signer = jest.fn();
57
15
  bridge = createBridges(signer);
58
16
  });
17
+
59
18
  test("createTransaction", () => {
60
- const data = transaction;
61
- const result = bridge.accountBridge.createTransaction(account);
19
+ const data = mockedTransaction;
20
+ const result = bridge.accountBridge.createTransaction(mockedAccount);
62
21
 
63
22
  expect(result).toEqual(data);
64
23
  });
65
24
 
66
25
  test("updateTransaction", () => {
67
- const patch = {
26
+ const patch: Partial<Transaction> = {
68
27
  amount: new BigNumber(5),
69
28
  recipient: "0.0.3",
70
29
  useAllAmount: true,
71
30
  };
72
- const data = { ...transaction, ...patch };
73
- const result = updateTransaction(transaction, patch);
31
+ const data = { ...mockedTransaction, ...patch };
32
+ const result = updateTransaction(mockedTransaction, patch);
74
33
 
75
34
  expect(result).toEqual(data);
76
35
  });
77
36
 
78
37
  test("prepareTransaction", async () => {
79
- const data = transaction;
80
- const result = await bridge.accountBridge.prepareTransaction(account, transaction);
38
+ const data = mockedTransaction;
39
+ const result = await bridge.accountBridge.prepareTransaction(mockedAccount, mockedTransaction);
81
40
 
82
41
  expect(result).toEqual(data);
83
42
  });
@@ -9,12 +9,11 @@ import { calculateAmount } from "./utils";
9
9
  * Hedera has fully client-side transactions and the fee
10
10
  * is not possible to estimate ahead-of-time.
11
11
  *
12
- * @returns {Transaction}
13
12
  */
14
13
  export const prepareTransaction: AccountBridge<Transaction>["prepareTransaction"] = async (
15
14
  account,
16
15
  transaction,
17
- ) => {
16
+ ): Promise<Transaction> => {
18
17
  // explicitly calculate transaction amount to account for `useAllAmount` flag (send max flow)
19
18
  // i.e. if `useAllAmount` has been toggled to true, this is where it will update the transaction to reflect that action
20
19
  const { amount } = await calculateAmount({ account, transaction });
@@ -0,0 +1,39 @@
1
+ import {
2
+ getMockedAccount,
3
+ getMockedAccountRaw,
4
+ mockHederaResources,
5
+ mockHederaResourcesRaw,
6
+ } from "../test/fixtures/account.fixture";
7
+ import {
8
+ assignFromAccountRaw,
9
+ assignToAccountRaw,
10
+ fromHederaResourcesRaw,
11
+ toHederaResourcesRaw,
12
+ } from "./serialization";
13
+
14
+ const mockedAccount = getMockedAccount();
15
+ const mockedAccountRaw = getMockedAccountRaw();
16
+
17
+ describe("serialization", () => {
18
+ test("toHederaResourcesRaw should convert HederaResources to HederaResourcesRaw", () => {
19
+ const result = toHederaResourcesRaw(mockHederaResources);
20
+ expect(result).toEqual(mockHederaResourcesRaw);
21
+ });
22
+
23
+ test("fromHederaResourcesRaw should convert HederaResourcesRaw to HederaResources", () => {
24
+ const result = fromHederaResourcesRaw(mockHederaResourcesRaw);
25
+ expect(result).toEqual(mockHederaResources);
26
+ });
27
+
28
+ test("assignToAccountRaw should assign HederaResources to AccountRaw", () => {
29
+ assignToAccountRaw(mockedAccount, mockedAccountRaw);
30
+ expect(typeof mockedAccountRaw.hederaResources).toBe("object");
31
+ expect(mockedAccountRaw.hederaResources).not.toBeNull();
32
+ });
33
+
34
+ test("assignFromAccountRaw should assign HederaResourcesRaw to Account", () => {
35
+ assignFromAccountRaw(mockedAccountRaw, mockedAccount);
36
+ expect(typeof mockedAccountRaw.hederaResources).toBe("object");
37
+ expect(mockedAccountRaw.hederaResources).not.toBeNull();
38
+ });
39
+ });
@@ -0,0 +1,43 @@
1
+ import type { AccountRaw, Account } from "@ledgerhq/types-live";
2
+ import type {
3
+ HederaAccount,
4
+ HederaAccountRaw,
5
+ HederaResources,
6
+ HederaResourcesRaw,
7
+ } from "../types";
8
+
9
+ export function toHederaResourcesRaw(resources: HederaResources): HederaResourcesRaw {
10
+ const { maxAutomaticTokenAssociations, isAutoTokenAssociationEnabled } = resources;
11
+
12
+ return {
13
+ maxAutomaticTokenAssociations,
14
+ isAutoTokenAssociationEnabled,
15
+ };
16
+ }
17
+
18
+ export function fromHederaResourcesRaw(rawResources: HederaResourcesRaw): HederaResources {
19
+ const { maxAutomaticTokenAssociations, isAutoTokenAssociationEnabled } = rawResources;
20
+
21
+ return {
22
+ maxAutomaticTokenAssociations,
23
+ isAutoTokenAssociationEnabled,
24
+ };
25
+ }
26
+
27
+ export function assignToAccountRaw(account: Account, accountRaw: AccountRaw): void {
28
+ const hederaAccount = account as HederaAccount;
29
+ const hederaAccountRaw = accountRaw as HederaAccountRaw;
30
+
31
+ if (hederaAccount.hederaResources) {
32
+ hederaAccountRaw.hederaResources = toHederaResourcesRaw(hederaAccount.hederaResources);
33
+ }
34
+ }
35
+
36
+ export function assignFromAccountRaw(accountRaw: AccountRaw, account: Account) {
37
+ const hederaAccount = account as HederaAccount;
38
+ const hederaAccountRaw = accountRaw as HederaAccountRaw;
39
+
40
+ if (hederaAccountRaw.hederaResources) {
41
+ hederaAccount.hederaResources = fromHederaResourcesRaw(hederaAccountRaw.hederaResources);
42
+ }
43
+ }
@@ -1,23 +1,28 @@
1
- import invariant from "invariant";
2
- import {
3
- getDerivationScheme,
4
- Result,
5
- runDerivationScheme,
6
- } from "@ledgerhq/coin-framework/derivation";
7
1
  import { BigNumber } from "bignumber.js";
8
- import type { Account } from "@ledgerhq/types-live";
9
- import { getAccountsForPublicKey, getOperationsForAccount } from "../api/mirror";
10
- import {
2
+ import invariant from "invariant";
3
+ import type { Result } from "@ledgerhq/coin-framework/derivation";
4
+ import { getDerivationScheme, runDerivationScheme } from "@ledgerhq/coin-framework/derivation";
5
+ import type {
11
6
  GetAccountShape,
12
7
  IterateResultBuilder,
13
- mergeOps,
14
8
  } from "@ledgerhq/coin-framework/bridge/jsHelpers";
9
+ import { mergeOps } from "@ledgerhq/coin-framework/bridge/jsHelpers";
15
10
  import { encodeAccountId } from "@ledgerhq/coin-framework/account";
16
- import { getAccountBalance } from "../api/network";
11
+ import { getAccount, getAccountsForPublicKey, getAccountTokens } from "../api/mirror";
12
+ import {
13
+ getSubAccounts,
14
+ prepareOperations,
15
+ applyPendingExtras,
16
+ mergeSubAccounts,
17
+ getSyncHash,
18
+ } from "./utils";
19
+ import type { HederaAccount } from "../types";
20
+ import { getOperationsForAccount } from "../api/utils";
17
21
 
18
- export const getAccountShape: GetAccountShape<Account> = async (
19
- info: any,
20
- ): Promise<Partial<Account>> => {
22
+ export const getAccountShape: GetAccountShape<HederaAccount> = async (
23
+ info,
24
+ { blacklistedTokenIds },
25
+ ): Promise<Partial<HederaAccount>> => {
21
26
  const { currency, derivationMode, address, initialAccount } = info;
22
27
 
23
28
  invariant(address, "an hedera address is expected");
@@ -30,39 +35,71 @@ export const getAccountShape: GetAccountShape<Account> = async (
30
35
  derivationMode,
31
36
  });
32
37
 
33
- // get current account balance
34
- const accountBalance = await getAccountBalance(address);
38
+ // get current account balance and tokens
39
+ // tokens are fetched with separate requests to get "created_timestamp" for each token
40
+ // based on this, ASSOCIATE_TOKEN operations can be connected with tokens
41
+ const [mirrorAccount, mirrorTokens] = await Promise.all([
42
+ getAccount(address),
43
+ getAccountTokens(address),
44
+ ]);
45
+
46
+ // we should sync again when new tokens are added or blacklist changes
47
+ const syncHash = getSyncHash(currency, blacklistedTokenIds);
48
+ const shouldSyncFromScratch = !initialAccount || syncHash !== initialAccount?.syncHash;
35
49
 
36
- // grab latest operation's consensus timestamp for incremental sync
37
50
  const oldOperations = initialAccount?.operations ?? [];
38
- const latestOperationTimestamp = oldOperations[0]
39
- ? new BigNumber(Math.floor(oldOperations[0].date.getTime() / 1000))
40
- : null;
51
+ const pendingOperations = initialAccount?.pendingOperations ?? [];
41
52
 
42
- // merge new operations w/ previously synced ones
43
- const newOperations = await getOperationsForAccount(
53
+ // grab latest operation's consensus timestamp for incremental sync
54
+ const latestOperationTimestamp =
55
+ !shouldSyncFromScratch && oldOperations[0]
56
+ ? new BigNumber(Math.floor(oldOperations[0].date.getTime() / 1000))
57
+ : null;
58
+ const latestAccountOperations = await getOperationsForAccount(
44
59
  liveAccountId,
45
60
  address,
46
61
  latestOperationTimestamp ? latestOperationTimestamp.toString() : null,
47
62
  );
48
- const operations = mergeOps(oldOperations, newOperations);
63
+
64
+ const newSubAccounts = await getSubAccounts(
65
+ liveAccountId,
66
+ latestAccountOperations.tokenOperations,
67
+ mirrorTokens,
68
+ );
69
+ const subAccounts = mergeSubAccounts(initialAccount, newSubAccounts);
70
+ const newOperations = prepareOperations(
71
+ latestAccountOperations.coinOperations,
72
+ latestAccountOperations.tokenOperations,
73
+ mirrorTokens,
74
+ );
75
+ const enrichedNewOperations = applyPendingExtras(newOperations, pendingOperations);
76
+ const operations = shouldSyncFromScratch
77
+ ? enrichedNewOperations
78
+ : mergeOps(oldOperations, enrichedNewOperations);
49
79
 
50
80
  return {
51
81
  id: liveAccountId,
52
82
  freshAddress: address,
53
- balance: accountBalance.balance,
54
- spendableBalance: accountBalance.balance,
83
+ syncHash,
84
+ lastSyncDate: new Date(),
85
+ balance: new BigNumber(mirrorAccount.balance.balance),
86
+ spendableBalance: new BigNumber(mirrorAccount.balance.balance),
55
87
  operations,
56
88
  operationsCount: operations.length,
57
89
  // NOTE: there are no "blocks" in hedera
58
90
  // Set a value just so that operations are considered confirmed according to isConfirmedOperation
59
91
  blockHeight: 10,
92
+ subAccounts,
93
+ hederaResources: {
94
+ maxAutomaticTokenAssociations: mirrorAccount.max_automatic_token_associations,
95
+ isAutoTokenAssociationEnabled: mirrorAccount.max_automatic_token_associations === -1,
96
+ },
60
97
  };
61
98
  };
62
99
 
63
100
  export const buildIterateResult: IterateResultBuilder = async ({ result: rootResult }) => {
64
- const accounts = await getAccountsForPublicKey(rootResult.publicKey);
65
- const addresses = accounts.map(a => a.accountId.toString());
101
+ const mirrorAccounts = await getAccountsForPublicKey(rootResult.publicKey);
102
+ const addresses = mirrorAccounts.map(a => a.account);
66
103
 
67
104
  return async ({ currency, derivationMode, index }) => {
68
105
  const derivationScheme = getDerivationScheme({
@@ -72,6 +109,7 @@ export const buildIterateResult: IterateResultBuilder = async ({ result: rootRes
72
109
  const freshAddressPath = runDerivationScheme(derivationScheme, currency, {
73
110
  account: index,
74
111
  });
112
+
75
113
  return addresses[index]
76
114
  ? ({
77
115
  address: addresses[index],
@@ -1,82 +1,40 @@
1
1
  import BigNumber from "bignumber.js";
2
- import type { Account } from "@ledgerhq/types-live";
3
- import type { Transaction, TransactionRaw } from "../types";
4
2
  import { formatTransaction, fromTransactionRaw, toTransactionRaw } from "../transaction";
5
-
6
- const account: Account = {
7
- type: "Account",
8
- id: "",
9
- seedIdentifier: "",
10
- derivationMode: "",
11
- index: 0,
12
- freshAddress: "",
13
- freshAddressPath: "",
14
- used: false,
15
- balance: new BigNumber(200000),
16
- spendableBalance: new BigNumber(0),
17
- creationDate: new Date(),
18
- blockHeight: 0,
19
- currency: {
20
- type: "CryptoCurrency",
21
- id: "hedera",
22
- managerAppName: "",
23
- coinType: 0,
24
- scheme: "",
25
- color: "",
26
- family: "",
27
- explorerViews: [],
28
- name: "",
29
- ticker: "",
30
- units: [
31
- {
32
- name: "",
33
- code: "",
34
- magnitude: 0,
35
- },
36
- ],
37
- },
38
- operationsCount: 0,
39
- operations: [],
40
- pendingOperations: [],
41
- lastSyncDate: new Date(),
42
- balanceHistoryCache: {
43
- HOUR: { latestDate: null, balances: [] },
44
- DAY: { latestDate: null, balances: [] },
45
- WEEK: { latestDate: null, balances: [] },
46
- },
47
- swapHistory: [],
48
- };
49
-
50
- const transaction: Transaction = {
51
- family: "hedera",
52
- amount: new BigNumber(1),
53
- recipient: "0.0.3",
54
- };
55
-
56
- const transactionRaw: TransactionRaw = {
57
- family: "hedera",
58
- amount: "1",
59
- recipient: "0.0.3",
60
- };
3
+ import { getMockedAccount } from "../test/fixtures/account.fixture";
4
+ import {
5
+ getMockedTransaction,
6
+ getMockedTransactionRaw,
7
+ } from "../test/fixtures/transaction.fixture";
61
8
 
62
9
  describe("transaction", () => {
10
+ const mockedAccount = getMockedAccount();
11
+ const mockedTransaction = getMockedTransaction({
12
+ amount: new BigNumber(100000000),
13
+ recipient: "0.0.3",
14
+ });
15
+ const mockedTransactionRaw = getMockedTransactionRaw({
16
+ amount: "100000000",
17
+ recipient: "0.0.3",
18
+ });
19
+
63
20
  test("formatTransaction", () => {
64
- const result = formatTransaction(transaction, account);
65
- const string = `SEND 1\nTO 0.0.3`;
21
+ const result = formatTransaction(mockedTransaction, mockedAccount);
22
+ const nonBreakingSpace = String.fromCharCode(160);
23
+ const string = `SEND 1${nonBreakingSpace}HBAR\nTO 0.0.3`;
66
24
 
67
25
  expect(result).toEqual(string);
68
26
  });
69
27
 
70
28
  test("fromTransactionRaw", () => {
71
- const result = fromTransactionRaw(transactionRaw);
72
- const data = transaction;
29
+ const result = fromTransactionRaw(mockedTransactionRaw);
30
+ const data = mockedTransaction;
73
31
 
74
32
  expect(result).toEqual(data);
75
33
  });
76
34
 
77
35
  test("toTransactionRaw", () => {
78
- const result = toTransactionRaw(transaction);
79
- const data = transactionRaw;
36
+ const result = toTransactionRaw(mockedTransaction);
37
+ const data = mockedTransactionRaw;
80
38
 
81
39
  expect(result).toEqual(data);
82
40
  });