@ledgerhq/coin-hedera 1.16.0-nightly.20251211024123 → 1.16.0-nightly.20251213023821

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 (149) hide show
  1. package/CHANGELOG.md +14 -10
  2. package/lib/api/index.d.ts.map +1 -1
  3. package/lib/api/index.js +4 -3
  4. package/lib/api/index.js.map +1 -1
  5. package/lib/bridge/buildOptimisticOperation.d.ts.map +1 -1
  6. package/lib/bridge/buildOptimisticOperation.js +14 -43
  7. package/lib/bridge/buildOptimisticOperation.js.map +1 -1
  8. package/lib/bridge/index.d.ts.map +1 -1
  9. package/lib/bridge/index.js +2 -0
  10. package/lib/bridge/index.js.map +1 -1
  11. package/lib/bridge/validateAddress.d.ts +3 -0
  12. package/lib/bridge/validateAddress.d.ts.map +1 -0
  13. package/lib/bridge/validateAddress.js +10 -0
  14. package/lib/bridge/validateAddress.js.map +1 -0
  15. package/lib/constants.d.ts +11 -6
  16. package/lib/constants.d.ts.map +1 -1
  17. package/lib/constants.js +20 -1
  18. package/lib/constants.js.map +1 -1
  19. package/lib/deviceTransactionConfig.d.ts.map +1 -1
  20. package/lib/deviceTransactionConfig.js +1 -3
  21. package/lib/deviceTransactionConfig.js.map +1 -1
  22. package/lib/logic/getBalance.d.ts.map +1 -1
  23. package/lib/logic/getBalance.js +21 -4
  24. package/lib/logic/getBalance.js.map +1 -1
  25. package/lib/logic/getBlock.d.ts.map +1 -1
  26. package/lib/logic/getBlock.js +39 -2
  27. package/lib/logic/getBlock.js.map +1 -1
  28. package/lib/logic/getValidators.d.ts +3 -0
  29. package/lib/logic/getValidators.d.ts.map +1 -0
  30. package/lib/logic/getValidators.js +24 -0
  31. package/lib/logic/getValidators.js.map +1 -0
  32. package/lib/logic/index.d.ts +1 -0
  33. package/lib/logic/index.d.ts.map +1 -1
  34. package/lib/logic/index.js +3 -1
  35. package/lib/logic/index.js.map +1 -1
  36. package/lib/logic/listOperations.d.ts.map +1 -1
  37. package/lib/logic/listOperations.js +16 -2
  38. package/lib/logic/listOperations.js.map +1 -1
  39. package/lib/logic/utils.d.ts +17 -1
  40. package/lib/logic/utils.d.ts.map +1 -1
  41. package/lib/logic/utils.js +54 -1
  42. package/lib/logic/utils.js.map +1 -1
  43. package/lib/network/api.d.ts +22 -2
  44. package/lib/network/api.d.ts.map +1 -1
  45. package/lib/network/api.js +49 -14
  46. package/lib/network/api.js.map +1 -1
  47. package/lib/preload.js +2 -2
  48. package/lib/preload.js.map +1 -1
  49. package/lib/test/fixtures/account.fixture.d.ts +8 -0
  50. package/lib/test/fixtures/account.fixture.d.ts.map +1 -1
  51. package/lib/test/fixtures/account.fixture.js +8 -0
  52. package/lib/test/fixtures/account.fixture.js.map +1 -1
  53. package/lib/test/fixtures/mirror.fixture.d.ts +2 -1
  54. package/lib/test/fixtures/mirror.fixture.d.ts.map +1 -1
  55. package/lib/test/fixtures/mirror.fixture.js +16 -1
  56. package/lib/test/fixtures/mirror.fixture.js.map +1 -1
  57. package/lib/types/bridge.d.ts +1 -0
  58. package/lib/types/bridge.d.ts.map +1 -1
  59. package/lib/types/logic.d.ts +6 -0
  60. package/lib/types/logic.d.ts.map +1 -1
  61. package/lib-es/api/index.d.ts.map +1 -1
  62. package/lib-es/api/index.js +5 -4
  63. package/lib-es/api/index.js.map +1 -1
  64. package/lib-es/bridge/buildOptimisticOperation.d.ts.map +1 -1
  65. package/lib-es/bridge/buildOptimisticOperation.js +15 -44
  66. package/lib-es/bridge/buildOptimisticOperation.js.map +1 -1
  67. package/lib-es/bridge/index.d.ts.map +1 -1
  68. package/lib-es/bridge/index.js +2 -0
  69. package/lib-es/bridge/index.js.map +1 -1
  70. package/lib-es/bridge/validateAddress.d.ts +3 -0
  71. package/lib-es/bridge/validateAddress.d.ts.map +1 -0
  72. package/lib-es/bridge/validateAddress.js +6 -0
  73. package/lib-es/bridge/validateAddress.js.map +1 -0
  74. package/lib-es/constants.d.ts +11 -6
  75. package/lib-es/constants.d.ts.map +1 -1
  76. package/lib-es/constants.js +19 -0
  77. package/lib-es/constants.js.map +1 -1
  78. package/lib-es/deviceTransactionConfig.d.ts.map +1 -1
  79. package/lib-es/deviceTransactionConfig.js +2 -4
  80. package/lib-es/deviceTransactionConfig.js.map +1 -1
  81. package/lib-es/logic/getBalance.d.ts.map +1 -1
  82. package/lib-es/logic/getBalance.js +21 -4
  83. package/lib-es/logic/getBalance.js.map +1 -1
  84. package/lib-es/logic/getBlock.d.ts.map +1 -1
  85. package/lib-es/logic/getBlock.js +40 -3
  86. package/lib-es/logic/getBlock.js.map +1 -1
  87. package/lib-es/logic/getValidators.d.ts +3 -0
  88. package/lib-es/logic/getValidators.d.ts.map +1 -0
  89. package/lib-es/logic/getValidators.js +20 -0
  90. package/lib-es/logic/getValidators.js.map +1 -0
  91. package/lib-es/logic/index.d.ts +1 -0
  92. package/lib-es/logic/index.d.ts.map +1 -1
  93. package/lib-es/logic/index.js +1 -0
  94. package/lib-es/logic/index.js.map +1 -1
  95. package/lib-es/logic/listOperations.d.ts.map +1 -1
  96. package/lib-es/logic/listOperations.js +17 -3
  97. package/lib-es/logic/listOperations.js.map +1 -1
  98. package/lib-es/logic/utils.d.ts +17 -1
  99. package/lib-es/logic/utils.d.ts.map +1 -1
  100. package/lib-es/logic/utils.js +52 -1
  101. package/lib-es/logic/utils.js.map +1 -1
  102. package/lib-es/network/api.d.ts +22 -2
  103. package/lib-es/network/api.d.ts.map +1 -1
  104. package/lib-es/network/api.js +49 -14
  105. package/lib-es/network/api.js.map +1 -1
  106. package/lib-es/preload.js +2 -2
  107. package/lib-es/preload.js.map +1 -1
  108. package/lib-es/test/fixtures/account.fixture.d.ts +8 -0
  109. package/lib-es/test/fixtures/account.fixture.d.ts.map +1 -1
  110. package/lib-es/test/fixtures/account.fixture.js +8 -0
  111. package/lib-es/test/fixtures/account.fixture.js.map +1 -1
  112. package/lib-es/test/fixtures/mirror.fixture.d.ts +2 -1
  113. package/lib-es/test/fixtures/mirror.fixture.d.ts.map +1 -1
  114. package/lib-es/test/fixtures/mirror.fixture.js +14 -0
  115. package/lib-es/test/fixtures/mirror.fixture.js.map +1 -1
  116. package/lib-es/types/bridge.d.ts +1 -0
  117. package/lib-es/types/bridge.d.ts.map +1 -1
  118. package/lib-es/types/logic.d.ts +6 -0
  119. package/lib-es/types/logic.d.ts.map +1 -1
  120. package/package.json +10 -10
  121. package/src/api/index.integ.test.ts +226 -1
  122. package/src/api/index.test.ts +5 -2
  123. package/src/api/index.ts +5 -5
  124. package/src/bridge/{buildOptimisticOperation.integration.test.ts → buildOptimisticOperation.test.ts} +23 -68
  125. package/src/bridge/buildOptimisticOperation.ts +16 -45
  126. package/src/bridge/index.ts +2 -0
  127. package/src/bridge/validateAddress.test.ts +31 -0
  128. package/src/bridge/validateAddress.ts +10 -0
  129. package/src/constants.ts +23 -1
  130. package/src/deviceTransactionConfig.test.ts +59 -43
  131. package/src/deviceTransactionConfig.ts +2 -5
  132. package/src/logic/getBalance.test.ts +50 -0
  133. package/src/logic/getBalance.ts +21 -4
  134. package/src/logic/getBlock.test.ts +283 -1
  135. package/src/logic/getBlock.ts +57 -6
  136. package/src/logic/getValidators.test.ts +50 -0
  137. package/src/logic/getValidators.ts +22 -0
  138. package/src/logic/index.ts +1 -0
  139. package/src/logic/listOperations.ts +33 -3
  140. package/src/logic/utils.test.ts +113 -0
  141. package/src/logic/utils.ts +67 -1
  142. package/src/network/api.test.ts +55 -9
  143. package/src/network/api.ts +66 -14
  144. package/src/preload.ts +2 -2
  145. package/src/test/fixtures/account.fixture.ts +8 -0
  146. package/src/test/fixtures/mirror.fixture.ts +18 -0
  147. package/src/types/bridge.ts +1 -0
  148. package/src/types/logic.ts +7 -0
  149. package/tsconfig.json +17 -12
@@ -4,6 +4,7 @@ import network from "@ledgerhq/live-network";
4
4
  import type { LiveNetworkResponse } from "@ledgerhq/live-network/network";
5
5
  import { getEnv } from "@ledgerhq/live-env";
6
6
  import { LedgerAPI4xx } from "@ledgerhq/errors";
7
+ import { HEDERA_TRANSACTION_NAMES } from "../constants";
7
8
  import { HederaAddAccountError } from "../errors";
8
9
  import type {
9
10
  HederaMirrorAccountTokensResponse,
@@ -39,11 +40,28 @@ async function getAccountsForPublicKey(publicKey: string): Promise<HederaMirrorA
39
40
  return accounts;
40
41
  }
41
42
 
42
- async function getAccount(address: string): Promise<HederaMirrorAccount> {
43
+ /**
44
+ * Fetches account information from the Hedera Mirror Node API, excluding transactions.
45
+ *
46
+ * @param address - The Hedera account ID (e.g., "0.0.12345")
47
+ * @param timestamp - Optional timestamp filter to get historical account state.
48
+ * Supports comparison operators:
49
+ * - "lt:1234567890.123456789" - state before the timestamp
50
+ * - "eq:1234567890.123456789" - state at the timestamp
51
+ * Used primarily for analyzing state changes in staking operations.
52
+ * @returns Promise resolving to account data
53
+ * @throws HederaAddAccountError if account not found (404)
54
+ */
55
+ async function getAccount(address: string, timestamp?: string): Promise<HederaMirrorAccount> {
43
56
  try {
57
+ const params = new URLSearchParams({
58
+ transactions: "false",
59
+ ...(timestamp && { timestamp }),
60
+ });
61
+
44
62
  const res = await network<HederaMirrorAccount>({
45
63
  method: "GET",
46
- url: `${API_URL}/api/v1/accounts/${address}`,
64
+ url: `${API_URL}/api/v1/accounts/${address}?${params.toString()}`,
47
65
  });
48
66
  const account = res.data;
49
67
 
@@ -57,6 +75,12 @@ async function getAccount(address: string): Promise<HederaMirrorAccount> {
57
75
  }
58
76
  }
59
77
 
78
+ // keeps old behavior when all pages are fetched
79
+ const getPaginationDirection = (fetchAllPages: boolean, order: string) => {
80
+ if (fetchAllPages) return "gt";
81
+ return order === "asc" ? "gt" : "lt";
82
+ };
83
+
60
84
  async function getAccountTransactions({
61
85
  address,
62
86
  pagingToken,
@@ -77,14 +101,8 @@ async function getAccountTransactions({
77
101
  order,
78
102
  });
79
103
 
80
- // keeps old behavior when all pages are fetched
81
- const getTimestampDirection = () => {
82
- if (fetchAllPages) return "gt";
83
- return order === "asc" ? "gt" : "lt";
84
- };
85
-
86
104
  if (pagingToken) {
87
- params.append("timestamp", `${getTimestampDirection()}:${pagingToken}`);
105
+ params.append("timestamp", `${getPaginationDirection(fetchAllPages, order)}:${pagingToken}`);
88
106
  }
89
107
 
90
108
  let nextCursor: string | null = null;
@@ -191,8 +209,11 @@ async function findTransactionByContractCall(
191
209
  url: `${API_URL}/api/v1/transactions?timestamp=${timestamp}`,
192
210
  });
193
211
  const transactions = res.data.transactions;
212
+ const relatedTx = transactions.find(
213
+ el => el.name === HEDERA_TRANSACTION_NAMES.ContractCall && el.entity_id === contractId,
214
+ );
194
215
 
195
- return transactions.find(el => el.name === "CONTRACTCALL" && el.entity_id === contractId) ?? null;
216
+ return relatedTx ?? null;
196
217
  }
197
218
 
198
219
  async function getERC20Balance(
@@ -269,13 +290,28 @@ async function getTransactionsByTimestampRange(
269
290
  return transactions;
270
291
  }
271
292
 
272
- async function getNodes(): Promise<HederaMirrorNode[]> {
293
+ async function getNodes({
294
+ cursor,
295
+ limit = 100,
296
+ order = "desc",
297
+ fetchAllPages,
298
+ }: {
299
+ cursor?: string;
300
+ limit?: number;
301
+ order?: "asc" | "desc";
302
+ fetchAllPages: boolean;
303
+ }): Promise<{ nodes: HederaMirrorNode[]; nextCursor: string | null }> {
273
304
  const nodes: HederaMirrorNode[] = [];
274
305
  const params = new URLSearchParams({
275
- order: "desc",
276
- limit: "100",
306
+ order,
307
+ limit: limit.toString(),
277
308
  });
278
309
 
310
+ if (cursor) {
311
+ params.append("node.id", `${getPaginationDirection(fetchAllPages, order)}:${cursor}`);
312
+ }
313
+
314
+ let nextCursor: string | null = null;
279
315
  let nextPath: string | null = `/api/v1/network/nodes?${params.toString()}`;
280
316
 
281
317
  while (nextPath) {
@@ -286,9 +322,25 @@ async function getNodes(): Promise<HederaMirrorNode[]> {
286
322
  const newNodes = res.data.nodes;
287
323
  nodes.push(...newNodes);
288
324
  nextPath = res.data.links.next;
325
+
326
+ // stop fetching if pagination mode is used and we reached the limit
327
+ if (!fetchAllPages && nodes.length >= limit) {
328
+ break;
329
+ }
330
+ }
331
+
332
+ // ensure we don't exceed the limit in pagination mode
333
+ if (!fetchAllPages && nodes.length > limit) {
334
+ nodes.splice(limit);
335
+ }
336
+
337
+ // set the next cursor only if we have more nodes to fetch
338
+ if (!fetchAllPages && nextPath) {
339
+ const lastNode = nodes.at(-1);
340
+ nextCursor = lastNode?.node_id?.toString() ?? null;
289
341
  }
290
342
 
291
- return nodes;
343
+ return { nodes, nextCursor };
292
344
  }
293
345
 
294
346
  export const apiClient = {
package/src/preload.ts CHANGED
@@ -12,9 +12,9 @@ export const getPreloadStrategy = () => ({
12
12
 
13
13
  export async function preload(currency: CryptoCurrency): Promise<HederaPreloadData> {
14
14
  log("hedera/preload", "preloading hedera data...");
15
- const nodes = await apiClient.getNodes();
15
+ const result = await apiClient.getNodes({ fetchAllPages: true });
16
16
 
17
- const validators: HederaValidator[] = nodes.map(mirrorNode => {
17
+ const validators: HederaValidator[] = result.nodes.map(mirrorNode => {
18
18
  const minStake = new BigNumber(mirrorNode.min_stake);
19
19
  const maxStake = new BigNumber(mirrorNode.max_stake);
20
20
  const activeStake = new BigNumber(mirrorNode.stake_rewarded);
@@ -140,4 +140,12 @@ export const MAINNET_TEST_ACCOUNTS = {
140
140
  associatedTokenWithoutBalance: "0.0.7243470",
141
141
  notAssociatedToken: "0.0.3176721",
142
142
  },
143
+ activeStaking: {
144
+ accountId: "0.0.8835924",
145
+ publicKey: "34e26415574250721e8869bd33ea2678c2bbccff5fc70bd8b0ec9239295fd2cf",
146
+ },
147
+ inactiveStaking: {
148
+ accountId: "0.0.9806001",
149
+ publicKey: "0283ef0997da7161c9a3aec45c57f4e074cb67916c97c1e5339d9f988e702e0450",
150
+ },
143
151
  };
@@ -1,4 +1,5 @@
1
1
  import type {
2
+ HederaMirrorAccount,
2
3
  HederaMirrorCoinTransfer,
3
4
  HederaMirrorToken,
4
5
  HederaMirrorTokenTransfer,
@@ -17,6 +18,23 @@ export const getMockedMirrorToken = (overrides?: Partial<HederaMirrorToken>): He
17
18
  };
18
19
  };
19
20
 
21
+ export const getMockedMirrorAccount = (
22
+ overrides?: Partial<HederaMirrorAccount>,
23
+ ): HederaMirrorAccount => {
24
+ return {
25
+ account: "0.0.12345",
26
+ balance: {
27
+ balance: 1000,
28
+ timestamp: "1764932745.835883000",
29
+ tokens: [],
30
+ },
31
+ max_automatic_token_associations: -1,
32
+ pending_reward: 0,
33
+ staked_node_id: null,
34
+ ...overrides,
35
+ };
36
+ };
37
+
20
38
  export const createMirrorCoinTransfer = (
21
39
  account: string,
22
40
  amount: number,
@@ -171,6 +171,7 @@ export type HederaOperationExtra = {
171
171
  memo?: string | null;
172
172
  targetStakingNodeId?: number | null;
173
173
  previousStakingNodeId?: number | null;
174
+ stakedAmount?: BigNumber;
174
175
  };
175
176
 
176
177
  export type HederaValidator = {
@@ -47,3 +47,10 @@ export interface OperationDetailsExtraField {
47
47
  key: string;
48
48
  value: string | number;
49
49
  }
50
+
51
+ export interface StakingAnalysis {
52
+ operationType: OperationType;
53
+ targetStakingNodeId: number | null;
54
+ previousStakingNodeId: number | null;
55
+ stakedAmount: bigint;
56
+ }
package/tsconfig.json CHANGED
@@ -1,13 +1,18 @@
1
1
  {
2
- "extends": "../../../tsconfig.base",
3
- "compilerOptions": {
4
- "declaration": true,
5
- "declarationMap": true,
6
- "downlevelIteration": true,
7
- "lib": ["es2020", "dom"],
8
- "exactOptionalPropertyTypes": true,
9
- "module": "esnext",
10
- "moduleResolution": "bundler",
11
- },
12
- "include": ["src/**/*"]
13
- }
2
+ "extends": "../../../tsconfig.base",
3
+ "compilerOptions": {
4
+ "declaration": true,
5
+ "declarationMap": true,
6
+ "downlevelIteration": true,
7
+ "lib": [
8
+ "es2020",
9
+ "dom"
10
+ ],
11
+ "exactOptionalPropertyTypes": true,
12
+ "module": "esnext",
13
+ "moduleResolution": "bundler",
14
+ },
15
+ "include": [
16
+ "src/**/*"
17
+ ]
18
+ }