@ledgerhq/coin-hedera 1.15.0-nightly.20251206023719 → 1.15.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 (187) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +25 -12
  3. package/lib/bridge/buildOptimisticOperation.d.ts.map +1 -1
  4. package/lib/bridge/buildOptimisticOperation.js +0 -33
  5. package/lib/bridge/buildOptimisticOperation.js.map +1 -1
  6. package/lib/bridge/getTransactionStatus.d.ts.map +1 -1
  7. package/lib/bridge/getTransactionStatus.js +0 -54
  8. package/lib/bridge/getTransactionStatus.js.map +1 -1
  9. package/lib/bridge/index.d.ts.map +1 -1
  10. package/lib/bridge/index.js +2 -4
  11. package/lib/bridge/index.js.map +1 -1
  12. package/lib/bridge/prepareTransaction.d.ts.map +1 -1
  13. package/lib/bridge/prepareTransaction.js +0 -16
  14. package/lib/bridge/prepareTransaction.js.map +1 -1
  15. package/lib/bridge/serialization.d.ts.map +1 -1
  16. package/lib/bridge/serialization.js +0 -20
  17. package/lib/bridge/serialization.js.map +1 -1
  18. package/lib/bridge/signOperation.d.ts +4 -4
  19. package/lib/bridge/signOperation.d.ts.map +1 -1
  20. package/lib/bridge/signOperation.js +0 -10
  21. package/lib/bridge/signOperation.js.map +1 -1
  22. package/lib/bridge/synchronisation.d.ts.map +1 -1
  23. package/lib/bridge/synchronisation.js +0 -8
  24. package/lib/bridge/synchronisation.js.map +1 -1
  25. package/lib/constants.d.ts +1 -21
  26. package/lib/constants.d.ts.map +1 -1
  27. package/lib/constants.js +1 -22
  28. package/lib/constants.js.map +1 -1
  29. package/lib/deviceTransactionConfig.d.ts.map +1 -1
  30. package/lib/deviceTransactionConfig.js +0 -30
  31. package/lib/deviceTransactionConfig.js.map +1 -1
  32. package/lib/errors.d.ts +0 -9
  33. package/lib/errors.d.ts.map +1 -1
  34. package/lib/errors.js +1 -4
  35. package/lib/errors.js.map +1 -1
  36. package/lib/logic/craftTransaction.d.ts +2 -2
  37. package/lib/logic/craftTransaction.d.ts.map +1 -1
  38. package/lib/logic/craftTransaction.js +8 -42
  39. package/lib/logic/craftTransaction.js.map +1 -1
  40. package/lib/logic/getBlock.d.ts.map +1 -1
  41. package/lib/logic/getBlock.js +0 -1
  42. package/lib/logic/getBlock.js.map +1 -1
  43. package/lib/logic/listOperations.d.ts.map +1 -1
  44. package/lib/logic/listOperations.js +7 -39
  45. package/lib/logic/listOperations.js.map +1 -1
  46. package/lib/logic/utils.d.ts +3 -61
  47. package/lib/logic/utils.d.ts.map +1 -1
  48. package/lib/logic/utils.js +3 -116
  49. package/lib/logic/utils.js.map +1 -1
  50. package/lib/network/api.d.ts +1 -3
  51. package/lib/network/api.d.ts.map +1 -1
  52. package/lib/network/api.js +0 -19
  53. package/lib/network/api.js.map +1 -1
  54. package/lib/test/fixtures/account.fixture.d.ts +1 -1
  55. package/lib/test/fixtures/account.fixture.d.ts.map +1 -1
  56. package/lib/test/fixtures/account.fixture.js +0 -2
  57. package/lib/test/fixtures/account.fixture.js.map +1 -1
  58. package/lib/transaction.d.ts.map +1 -1
  59. package/lib/transaction.js +0 -34
  60. package/lib/transaction.js.map +1 -1
  61. package/lib/types/alpaca.d.ts +0 -3
  62. package/lib/types/alpaca.d.ts.map +1 -1
  63. package/lib/types/bridge.d.ts +3 -87
  64. package/lib/types/bridge.d.ts.map +1 -1
  65. package/lib/types/logic.d.ts +1 -5
  66. package/lib/types/logic.d.ts.map +1 -1
  67. package/lib/types/mirror.d.ts +0 -19
  68. package/lib/types/mirror.d.ts.map +1 -1
  69. package/lib-es/bridge/buildOptimisticOperation.d.ts.map +1 -1
  70. package/lib-es/bridge/buildOptimisticOperation.js +1 -34
  71. package/lib-es/bridge/buildOptimisticOperation.js.map +1 -1
  72. package/lib-es/bridge/getTransactionStatus.d.ts.map +1 -1
  73. package/lib-es/bridge/getTransactionStatus.js +3 -57
  74. package/lib-es/bridge/getTransactionStatus.js.map +1 -1
  75. package/lib-es/bridge/index.d.ts.map +1 -1
  76. package/lib-es/bridge/index.js +2 -4
  77. package/lib-es/bridge/index.js.map +1 -1
  78. package/lib-es/bridge/prepareTransaction.d.ts.map +1 -1
  79. package/lib-es/bridge/prepareTransaction.js +2 -15
  80. package/lib-es/bridge/prepareTransaction.js.map +1 -1
  81. package/lib-es/bridge/serialization.d.ts.map +1 -1
  82. package/lib-es/bridge/serialization.js +0 -17
  83. package/lib-es/bridge/serialization.js.map +1 -1
  84. package/lib-es/bridge/signOperation.d.ts +4 -4
  85. package/lib-es/bridge/signOperation.d.ts.map +1 -1
  86. package/lib-es/bridge/signOperation.js +1 -11
  87. package/lib-es/bridge/signOperation.js.map +1 -1
  88. package/lib-es/bridge/synchronisation.d.ts.map +1 -1
  89. package/lib-es/bridge/synchronisation.js +0 -8
  90. package/lib-es/bridge/synchronisation.js.map +1 -1
  91. package/lib-es/constants.d.ts +1 -21
  92. package/lib-es/constants.d.ts.map +1 -1
  93. package/lib-es/constants.js +0 -21
  94. package/lib-es/constants.js.map +1 -1
  95. package/lib-es/deviceTransactionConfig.d.ts.map +1 -1
  96. package/lib-es/deviceTransactionConfig.js +1 -31
  97. package/lib-es/deviceTransactionConfig.js.map +1 -1
  98. package/lib-es/errors.d.ts +0 -9
  99. package/lib-es/errors.d.ts.map +1 -1
  100. package/lib-es/errors.js +0 -3
  101. package/lib-es/errors.js.map +1 -1
  102. package/lib-es/logic/craftTransaction.d.ts +2 -2
  103. package/lib-es/logic/craftTransaction.d.ts.map +1 -1
  104. package/lib-es/logic/craftTransaction.js +10 -44
  105. package/lib-es/logic/craftTransaction.js.map +1 -1
  106. package/lib-es/logic/getBlock.d.ts.map +1 -1
  107. package/lib-es/logic/getBlock.js +1 -2
  108. package/lib-es/logic/getBlock.js.map +1 -1
  109. package/lib-es/logic/listOperations.d.ts.map +1 -1
  110. package/lib-es/logic/listOperations.js +7 -39
  111. package/lib-es/logic/listOperations.js.map +1 -1
  112. package/lib-es/logic/utils.d.ts +3 -61
  113. package/lib-es/logic/utils.d.ts.map +1 -1
  114. package/lib-es/logic/utils.js +3 -106
  115. package/lib-es/logic/utils.js.map +1 -1
  116. package/lib-es/network/api.d.ts +1 -3
  117. package/lib-es/network/api.d.ts.map +1 -1
  118. package/lib-es/network/api.js +0 -19
  119. package/lib-es/network/api.js.map +1 -1
  120. package/lib-es/test/fixtures/account.fixture.d.ts +1 -1
  121. package/lib-es/test/fixtures/account.fixture.d.ts.map +1 -1
  122. package/lib-es/test/fixtures/account.fixture.js +0 -2
  123. package/lib-es/test/fixtures/account.fixture.js.map +1 -1
  124. package/lib-es/transaction.d.ts.map +1 -1
  125. package/lib-es/transaction.js +0 -34
  126. package/lib-es/transaction.js.map +1 -1
  127. package/lib-es/types/alpaca.d.ts +0 -3
  128. package/lib-es/types/alpaca.d.ts.map +1 -1
  129. package/lib-es/types/bridge.d.ts +3 -87
  130. package/lib-es/types/bridge.d.ts.map +1 -1
  131. package/lib-es/types/logic.d.ts +1 -5
  132. package/lib-es/types/logic.d.ts.map +1 -1
  133. package/lib-es/types/mirror.d.ts +0 -19
  134. package/lib-es/types/mirror.d.ts.map +1 -1
  135. package/package.json +11 -12
  136. package/src/api/index.integ.test.ts +1 -11
  137. package/src/bridge/buildOptimisticOperation.integration.test.ts +4 -159
  138. package/src/bridge/buildOptimisticOperation.ts +2 -50
  139. package/src/bridge/getTransactionStatus.test.ts +21 -191
  140. package/src/bridge/getTransactionStatus.ts +1 -75
  141. package/src/bridge/index.ts +2 -4
  142. package/src/bridge/prepareTransaction.test.ts +8 -112
  143. package/src/bridge/prepareTransaction.ts +2 -20
  144. package/src/bridge/serialization.ts +0 -17
  145. package/src/bridge/signOperation.ts +5 -15
  146. package/src/bridge/synchronisation.ts +0 -9
  147. package/src/bridge/utils.integration.test.ts +10 -3
  148. package/src/constants.ts +0 -22
  149. package/src/deviceTransactionConfig.ts +1 -37
  150. package/src/errors.ts +0 -7
  151. package/src/logic/craftTransaction.ts +13 -70
  152. package/src/logic/getBalance.test.ts +16 -15
  153. package/src/logic/getBlock.ts +1 -2
  154. package/src/logic/listOperations.test.ts +29 -86
  155. package/src/logic/listOperations.ts +6 -46
  156. package/src/logic/utils.test.ts +8 -362
  157. package/src/logic/utils.ts +3 -157
  158. package/src/network/api.test.ts +6 -58
  159. package/src/network/api.ts +0 -25
  160. package/src/network/thirdweb.test.ts +2 -2
  161. package/src/network/utils.test.ts +6 -4
  162. package/src/test/fixtures/account.fixture.ts +1 -3
  163. package/src/transaction.ts +0 -42
  164. package/src/types/alpaca.ts +0 -4
  165. package/src/types/bridge.ts +3 -108
  166. package/src/types/logic.ts +1 -6
  167. package/src/types/mirror.ts +0 -21
  168. package/lib/preload-data.d.ts +0 -7
  169. package/lib/preload-data.d.ts.map +0 -1
  170. package/lib/preload-data.js +0 -37
  171. package/lib/preload-data.js.map +0 -1
  172. package/lib/preload.d.ts +0 -8
  173. package/lib/preload.d.ts.map +0 -1
  174. package/lib/preload.js +0 -76
  175. package/lib/preload.js.map +0 -1
  176. package/lib-es/preload-data.d.ts +0 -7
  177. package/lib-es/preload-data.d.ts.map +0 -1
  178. package/lib-es/preload-data.js +0 -31
  179. package/lib-es/preload-data.js.map +0 -1
  180. package/lib-es/preload.d.ts +0 -8
  181. package/lib-es/preload.d.ts.map +0 -1
  182. package/lib-es/preload.js +0 -67
  183. package/lib-es/preload.js.map +0 -1
  184. package/src/deviceTransactionConfig.test.ts +0 -315
  185. package/src/preload-data.ts +0 -38
  186. package/src/preload.test.ts +0 -64
  187. package/src/preload.ts +0 -80
@@ -1,33 +1,19 @@
1
1
  import BigNumber from "bignumber.js";
2
2
  import { createHash } from "crypto";
3
- import { Transaction as SDKTransaction, TransactionId } from "@hashgraph/sdk";
4
- import type { AssetInfo, TransactionIntent } from "@ledgerhq/coin-framework/api/types";
3
+ import { Transaction, TransactionId } from "@hashgraph/sdk";
4
+ import type { AssetInfo } from "@ledgerhq/coin-framework/api/types";
5
5
  import { getCryptoCurrencyById } from "@ledgerhq/cryptoassets/currencies";
6
6
  import { InvalidAddress } from "@ledgerhq/errors";
7
- import { getEnv, setEnv } from "@ledgerhq/live-env";
8
- import {
9
- HEDERA_OPERATION_TYPES,
10
- HEDERA_TRANSACTION_MODES,
11
- SYNTHETIC_BLOCK_WINDOW_SECONDS,
12
- } from "../constants";
7
+ import { HEDERA_TRANSACTION_MODES, SYNTHETIC_BLOCK_WINDOW_SECONDS } from "../constants";
13
8
  import { HederaRecipientInvalidChecksum } from "../errors";
14
9
  import { apiClient } from "../network/api";
15
10
  import { rpcClient } from "../network/rpc";
16
- import * as preloadData from "../preload-data";
17
11
  import { getMockedOperation } from "../test/fixtures/operation.fixture";
18
12
  import {
19
13
  getMockedERC20TokenCurrency,
20
14
  getMockedHTSTokenCurrency,
21
15
  } from "../test/fixtures/currency.fixture";
22
16
  import { getMockedAccount, getMockedTokenAccount } from "../test/fixtures/account.fixture";
23
- import type {
24
- HederaAccount,
25
- HederaMemo,
26
- HederaPreloadData,
27
- HederaTxData,
28
- HederaValidator,
29
- Transaction,
30
- } from "../types";
31
17
  import {
32
18
  serializeSignature,
33
19
  deserializeSignature,
@@ -49,36 +35,15 @@ import {
49
35
  formatTransactionId,
50
36
  getTimestampRangeFromBlockHeight,
51
37
  getBlockHash,
52
- isStakingTransaction,
53
- extractCompanyFromNodeDescription,
54
- sortValidators,
55
- getValidatorFromAccount,
56
- getDefaultValidator,
57
- getDelegationStatus,
58
- filterValidatorBySearchTerm,
59
- hasSpecificIntentData,
60
- getChecksum,
61
- mapIntentToSDKOperation,
62
- getOperationDetailsExtraFields,
63
38
  } from "./utils";
64
39
 
65
40
  jest.mock("../network/api");
66
41
 
67
42
  describe("logic utils", () => {
68
- let oldStakingLedgerNodeIdEnv: number;
69
-
70
43
  beforeEach(() => {
71
44
  jest.clearAllMocks();
72
45
  });
73
46
 
74
- afterEach(() => {
75
- setEnv("HEDERA_STAKING_LEDGER_NODE_ID", oldStakingLedgerNodeIdEnv);
76
- });
77
-
78
- beforeAll(() => {
79
- oldStakingLedgerNodeIdEnv = getEnv("HEDERA_STAKING_LEDGER_NODE_ID");
80
- });
81
-
82
47
  afterAll(() => {
83
48
  rpcClient._resetInstance();
84
49
  });
@@ -101,7 +66,7 @@ describe("logic utils", () => {
101
66
 
102
67
  describe("transaction serialization", () => {
103
68
  beforeEach(() => {
104
- jest.spyOn(SDKTransaction, "fromBytes");
69
+ jest.spyOn(Transaction, "fromBytes");
105
70
  });
106
71
 
107
72
  afterEach(() => {
@@ -111,7 +76,7 @@ describe("logic utils", () => {
111
76
  it("should serialize a transaction to hex", () => {
112
77
  const mockTransaction = {
113
78
  toBytes: jest.fn().mockReturnValue(Buffer.from([10, 20, 30, 40, 50])),
114
- } as unknown as SDKTransaction;
79
+ } as unknown as Transaction;
115
80
 
116
81
  const serialized = serializeTransaction(mockTransaction);
117
82
 
@@ -121,14 +86,14 @@ describe("logic utils", () => {
121
86
 
122
87
  it("should deserialize a hex string to a Transaction", () => {
123
88
  const mockTransaction = { id: "mock-transaction-id" };
124
- (SDKTransaction.fromBytes as jest.Mock).mockReturnValue(mockTransaction);
89
+ (Transaction.fromBytes as jest.Mock).mockReturnValue(mockTransaction);
125
90
 
126
91
  const hexTransaction = "0a141e2832";
127
92
  const deserialized = deserializeTransaction(hexTransaction);
128
93
 
129
94
  const hexTransactionBuffer = Buffer.from([10, 20, 30, 40, 50]);
130
- expect(SDKTransaction.fromBytes).toHaveBeenCalledTimes(1);
131
- expect(SDKTransaction.fromBytes).toHaveBeenCalledWith(hexTransactionBuffer);
95
+ expect(Transaction.fromBytes).toHaveBeenCalledTimes(1);
96
+ expect(Transaction.fromBytes).toHaveBeenCalledWith(hexTransactionBuffer);
132
97
  expect(deserialized).toBe(mockTransaction);
133
98
  });
134
99
  });
@@ -177,75 +142,6 @@ describe("logic utils", () => {
177
142
  });
178
143
  });
179
144
 
180
- describe("mapIntentToSDKOperation", () => {
181
- it("should return TokenAssociate for TokenAssociate intent", () => {
182
- const txIntent = {
183
- type: HEDERA_TRANSACTION_MODES.TokenAssociate,
184
- } as TransactionIntent;
185
-
186
- expect(mapIntentToSDKOperation(txIntent)).toBe(HEDERA_OPERATION_TYPES.TokenAssociate);
187
- });
188
-
189
- it("should return TokenTransfer for Send intent with HTS asset", () => {
190
- const txIntent = {
191
- type: HEDERA_TRANSACTION_MODES.Send,
192
- asset: { type: "hts", assetReference: "0.0.1234" },
193
- } as TransactionIntent;
194
-
195
- expect(mapIntentToSDKOperation(txIntent)).toBe(HEDERA_OPERATION_TYPES.TokenTransfer);
196
- });
197
-
198
- it("should return ContractCall for Send intent with ERC20 asset", () => {
199
- const txIntent = {
200
- type: HEDERA_TRANSACTION_MODES.Send,
201
- asset: { type: "erc20", assetReference: "0x1234" },
202
- } as TransactionIntent;
203
-
204
- expect(mapIntentToSDKOperation(txIntent)).toBe(HEDERA_OPERATION_TYPES.ContractCall);
205
- });
206
-
207
- it("should return CryptoUpdate for Delegate intent", () => {
208
- const txIntent = {
209
- type: HEDERA_TRANSACTION_MODES.Delegate,
210
- } as TransactionIntent;
211
-
212
- expect(mapIntentToSDKOperation(txIntent)).toBe(HEDERA_OPERATION_TYPES.CryptoUpdate);
213
- });
214
-
215
- it("should return CryptoUpdate for Undelegate intent", () => {
216
- const txIntent = {
217
- type: HEDERA_TRANSACTION_MODES.Undelegate,
218
- } as TransactionIntent;
219
-
220
- expect(mapIntentToSDKOperation(txIntent)).toBe(HEDERA_OPERATION_TYPES.CryptoUpdate);
221
- });
222
-
223
- it("should return CryptoUpdate for Redelegate intent", () => {
224
- const txIntent = {
225
- type: HEDERA_TRANSACTION_MODES.Redelegate,
226
- } as TransactionIntent;
227
-
228
- expect(mapIntentToSDKOperation(txIntent)).toBe(HEDERA_OPERATION_TYPES.CryptoUpdate);
229
- });
230
-
231
- it("should return CryptoTransfer for Send intent with native asset", () => {
232
- const txIntent = {
233
- type: HEDERA_TRANSACTION_MODES.Send,
234
- asset: { type: "native" },
235
- } as TransactionIntent;
236
-
237
- expect(mapIntentToSDKOperation(txIntent)).toBe(HEDERA_OPERATION_TYPES.CryptoTransfer);
238
- });
239
-
240
- it("should return CryptoTransfer for other intent types", () => {
241
- const txIntent = {
242
- type: HEDERA_TRANSACTION_MODES.ClaimRewards,
243
- } as TransactionIntent;
244
-
245
- expect(mapIntentToSDKOperation(txIntent)).toBe(HEDERA_OPERATION_TYPES.CryptoTransfer);
246
- });
247
- });
248
-
249
145
  describe("getMemoFromBase64", () => {
250
146
  it("decodes a simple base64 string", () => {
251
147
  expect(getMemoFromBase64("YnJkZw==")).toBe("brdg");
@@ -351,7 +247,6 @@ describe("logic utils", () => {
351
247
  hederaResources: {
352
248
  maxAutomaticTokenAssociations: -1,
353
249
  isAutoTokenAssociationEnabled: true,
354
- delegation: null,
355
250
  },
356
251
  });
357
252
 
@@ -496,22 +391,6 @@ describe("logic utils", () => {
496
391
  });
497
392
  });
498
393
 
499
- describe("getChecksum", () => {
500
- it("should return correct checksum for valid account ID", () => {
501
- const accountId = "0.0.9124531-xrxlv";
502
- const checksum = getChecksum(accountId);
503
-
504
- expect(checksum).toBe("xrxlv");
505
- });
506
-
507
- it("should return null for invalid account ID", () => {
508
- const accountId = "invalid-account-id";
509
- const checksum = getChecksum(accountId);
510
-
511
- expect(checksum).toBeNull();
512
- });
513
- });
514
-
515
394
  describe("safeParseAccountId", () => {
516
395
  it("returns account id and no checksum for valid address without checksum", () => {
517
396
  const [error, result] = safeParseAccountId("0.0.9124531");
@@ -718,237 +597,4 @@ describe("logic utils", () => {
718
597
  expect(result.end).toMatch(/^\d+\.000000000$/);
719
598
  });
720
599
  });
721
-
722
- describe("isStakingTransaction", () => {
723
- it("returns correct value based on tx.mode", () => {
724
- const stakingDelegateTx = { mode: HEDERA_TRANSACTION_MODES.Delegate } as Transaction;
725
- const stakingUndelegateTx = { mode: HEDERA_TRANSACTION_MODES.Undelegate } as Transaction;
726
- const stakingRedelegateTx = { mode: HEDERA_TRANSACTION_MODES.Redelegate } as Transaction;
727
- const stakingClaimRewardsTx = { mode: HEDERA_TRANSACTION_MODES.ClaimRewards } as Transaction;
728
- const transferTx = { recipient: "", amount: new BigNumber(1) } as Transaction;
729
- const emptyTx = {} as Transaction;
730
-
731
- expect(isStakingTransaction(stakingDelegateTx)).toBe(true);
732
- expect(isStakingTransaction(stakingUndelegateTx)).toBe(true);
733
- expect(isStakingTransaction(stakingRedelegateTx)).toBe(true);
734
- expect(isStakingTransaction(stakingClaimRewardsTx)).toBe(true);
735
- expect(isStakingTransaction(transferTx)).toBe(false);
736
- expect(isStakingTransaction(emptyTx)).toBe(false);
737
- });
738
-
739
- it("returns false for undefined or null transactions", () => {
740
- expect(isStakingTransaction(undefined as unknown as Transaction)).toBe(false);
741
- expect(isStakingTransaction(null as unknown as Transaction)).toBe(false);
742
- });
743
- });
744
-
745
- describe("extractCompanyFromNodeDescription", () => {
746
- it("extracts company name from description", () => {
747
- expect(extractCompanyFromNodeDescription("Hosted by Ledger | Paris, France")).toBe("Ledger");
748
- expect(extractCompanyFromNodeDescription("Hosted by LG | Seoul, South Korea")).toBe("LG");
749
- expect(extractCompanyFromNodeDescription("TestCompany | something else")).toBe("TestCompany");
750
- expect(extractCompanyFromNodeDescription("NoSeparator ")).toBe("NoSeparator");
751
- });
752
- });
753
-
754
- describe("sortValidators", () => {
755
- it("sorts validators by active stake DESC, Ledger node first if set", () => {
756
- setEnv("HEDERA_STAKING_LEDGER_NODE_ID", 2);
757
-
758
- const validators = [
759
- { nodeId: 3, activeStake: new BigNumber(1000) },
760
- { nodeId: 2, activeStake: new BigNumber(2000) },
761
- { nodeId: 1, activeStake: new BigNumber(3000) },
762
- ] as HederaValidator[];
763
-
764
- const sorted = sortValidators(validators);
765
-
766
- expect(sorted[0].nodeId).toBe(2);
767
- expect(sorted[1].nodeId).toBe(1);
768
- expect(sorted[2].nodeId).toBe(3);
769
- });
770
- });
771
-
772
- describe("getValidatorFromAccount", () => {
773
- const mockValidator = { nodeId: 1 };
774
- const mockPreload = { validators: [mockValidator] } as HederaPreloadData;
775
-
776
- beforeEach(() => {
777
- jest.clearAllMocks();
778
-
779
- jest.spyOn(preloadData, "getCurrentHederaPreloadData").mockReturnValueOnce(mockPreload);
780
- });
781
-
782
- it("returns validator matching delegation nodeId", () => {
783
- const mockAccount = {
784
- currency: "hedera",
785
- hederaResources: { delegation: { nodeId: 1 } },
786
- } as unknown as HederaAccount;
787
-
788
- expect(getValidatorFromAccount(mockAccount)).toEqual(mockValidator);
789
- });
790
-
791
- it("returns null if no delegation", () => {
792
- const mockAccount = {
793
- currency: "hedera",
794
- hederaResources: {},
795
- } as unknown as HederaAccount;
796
-
797
- expect(getValidatorFromAccount(mockAccount)).toBeNull();
798
- });
799
- });
800
-
801
- describe("getDefaultValidator", () => {
802
- const mockValidators = [
803
- { nodeId: 1, activeStake: new BigNumber(2000) },
804
- { nodeId: 2, activeStake: new BigNumber(1000) },
805
- { nodeId: 3, activeStake: new BigNumber(10000) },
806
- ] as HederaValidator[];
807
-
808
- it("returns Ledger validator if present", () => {
809
- setEnv("HEDERA_STAKING_LEDGER_NODE_ID", 2);
810
- expect(getDefaultValidator(mockValidators)?.nodeId).toBe(2);
811
- });
812
-
813
- it("returns null if no Ledger validator is present", () => {
814
- expect(getDefaultValidator([])).toBeNull();
815
- });
816
- });
817
-
818
- describe("getDelegationStatus", () => {
819
- const mockValidator = { address: "0.0.3", overstaked: false } as HederaValidator;
820
- const mockOverstakedValidator = { address: "0.0.3", overstaked: true } as HederaValidator;
821
-
822
- it("returns inactive if validator or validator's address is missing", () => {
823
- expect(getDelegationStatus(null)).toBe("inactive");
824
- expect(getDelegationStatus({ address: "" } as any)).toBe("inactive");
825
- });
826
-
827
- it("returns overstaked if validator.overstaked is true", () => {
828
- expect(getDelegationStatus(mockOverstakedValidator)).toBe("overstaked");
829
- });
830
-
831
- it("returns active otherwise", () => {
832
- expect(getDelegationStatus(mockValidator)).toBe("active");
833
- });
834
- });
835
-
836
- describe("filterValidatorBySearchTerm", () => {
837
- const mockValidator: HederaValidator = {
838
- nodeId: 123,
839
- name: "Validator Test",
840
- address: "0.0.456",
841
- addressChecksum: "abcde",
842
- minStake: new BigNumber(0),
843
- maxStake: new BigNumber(0),
844
- activeStake: new BigNumber(0),
845
- activeStakePercentage: new BigNumber(0),
846
- overstaked: false,
847
- };
848
-
849
- it("should match by nodeId", () => {
850
- expect(filterValidatorBySearchTerm(mockValidator, "123")).toBe(true);
851
- });
852
-
853
- it("should match by name with case insensitivity", () => {
854
- expect(filterValidatorBySearchTerm(mockValidator, "validator")).toBe(true);
855
- expect(filterValidatorBySearchTerm(mockValidator, "VALIDATOR")).toBe(true);
856
- expect(filterValidatorBySearchTerm(mockValidator, "test")).toBe(true);
857
- expect(filterValidatorBySearchTerm(mockValidator, "unknown")).toBe(false);
858
- });
859
-
860
- it("should match by address", () => {
861
- expect(filterValidatorBySearchTerm(mockValidator, "0.0.456")).toBe(true);
862
- expect(filterValidatorBySearchTerm(mockValidator, "456")).toBe(true);
863
- expect(filterValidatorBySearchTerm(mockValidator, "789")).toBe(false);
864
- });
865
-
866
- it("should match by address with checksum", () => {
867
- expect(filterValidatorBySearchTerm(mockValidator, "0.0.456-abcde")).toBe(true);
868
- expect(filterValidatorBySearchTerm(mockValidator, "abcde")).toBe(true);
869
- expect(filterValidatorBySearchTerm(mockValidator, "ABC")).toBe(true);
870
- });
871
-
872
- it("should handle validator without checksum", () => {
873
- const validatorWithoutChecksum = { ...mockValidator, addressChecksum: null };
874
- expect(filterValidatorBySearchTerm(validatorWithoutChecksum, "0.0.456")).toBe(true);
875
- expect(filterValidatorBySearchTerm(validatorWithoutChecksum, "abcde")).toBe(false);
876
- });
877
-
878
- it("should handle empty search term", () => {
879
- expect(filterValidatorBySearchTerm(mockValidator, "")).toBe(true);
880
- });
881
-
882
- it("should handle partial matches", () => {
883
- expect(filterValidatorBySearchTerm(mockValidator, "valid")).toBe(true);
884
- expect(filterValidatorBySearchTerm(mockValidator, "0.0")).toBe(true);
885
- expect(filterValidatorBySearchTerm(mockValidator, "12")).toBe(true);
886
- });
887
- });
888
-
889
- describe("hasSpecificIntentData", () => {
890
- it("should return true when txIntent has data matching expected type", () => {
891
- const stakingTxIntent = {
892
- data: { type: "staking" as const },
893
- } as TransactionIntent<HederaMemo, HederaTxData>;
894
- const erc20TxIntent = {
895
- data: { type: "erc20" as const },
896
- } as TransactionIntent<HederaMemo, HederaTxData>;
897
-
898
- expect(hasSpecificIntentData(stakingTxIntent, "staking")).toBe(true);
899
- expect(hasSpecificIntentData(erc20TxIntent, "erc20")).toBe(true);
900
- });
901
-
902
- it("should return false when txIntent has invalid data", () => {
903
- const txIntentNoData = {} as TransactionIntent<HederaMemo, HederaTxData>;
904
- const txIntentUnknown = {
905
- data: { type: "unknown" as const },
906
- } as unknown as TransactionIntent<HederaMemo, HederaTxData>;
907
-
908
- expect(hasSpecificIntentData(txIntentUnknown, "erc20")).toBe(false);
909
- expect(hasSpecificIntentData(txIntentNoData, "erc20")).toBe(false);
910
- });
911
- });
912
-
913
- describe("getOperationDetailsExtraFields", () => {
914
- it("should return empty array when no fields are present", () => {
915
- const result = getOperationDetailsExtraFields({});
916
-
917
- expect(result).toEqual([]);
918
- });
919
-
920
- it("should handle zero values correctly", () => {
921
- const result = getOperationDetailsExtraFields({
922
- gasConsumed: 0,
923
- targetStakingNodeId: 0,
924
- });
925
-
926
- expect(result).toEqual([
927
- { key: "targetStakingNodeId", value: "0" },
928
- { key: "gasConsumed", value: "0" },
929
- ]);
930
- });
931
-
932
- it("should return all fields when all are present", () => {
933
- const result = getOperationDetailsExtraFields({
934
- memo: "complete",
935
- associatedTokenId: "123",
936
- targetStakingNodeId: 5,
937
- previousStakingNodeId: 3,
938
- gasConsumed: 1000,
939
- gasUsed: 950,
940
- gasLimit: 2000,
941
- });
942
-
943
- expect(result).toEqual([
944
- { key: "memo", value: "complete" },
945
- { key: "associatedTokenId", value: "123" },
946
- { key: "targetStakingNodeId", value: "5" },
947
- { key: "previousStakingNodeId", value: "3" },
948
- { key: "gasConsumed", value: "1000" },
949
- { key: "gasUsed", value: "950" },
950
- { key: "gasLimit", value: "2000" },
951
- ]);
952
- });
953
- });
954
600
  });
@@ -12,12 +12,10 @@ import { findCryptoCurrencyById } from "@ledgerhq/cryptoassets/currencies";
12
12
  import { getFiatCurrencyByTicker } from "@ledgerhq/cryptoassets/fiats";
13
13
  import cvsApi from "@ledgerhq/live-countervalues/api/index";
14
14
  import { InvalidAddress } from "@ledgerhq/errors";
15
- import { getEnv } from "@ledgerhq/live-env";
16
15
  import { makeLRUCache, seconds } from "@ledgerhq/live-network/cache";
17
16
  import type { Currency, ExplorerView, TokenCurrency } from "@ledgerhq/types-cryptoassets";
18
17
  import type { AccountLike, Operation as LiveOperation } from "@ledgerhq/types-live";
19
18
  import {
20
- HEDERA_DELEGATION_STATUS,
21
19
  HEDERA_OPERATION_TYPES,
22
20
  HEDERA_TRANSACTION_MODES,
23
21
  SYNTHETIC_BLOCK_WINDOW_SECONDS,
@@ -25,19 +23,13 @@ import {
25
23
  import { apiClient } from "../network/api";
26
24
  import type {
27
25
  HederaAccount,
28
- HederaMemo,
29
26
  HederaOperationExtra,
30
- HederaTxData,
31
- HederaValidator,
32
- OperationDetailsExtraField,
33
27
  Transaction,
34
- TransactionStaking,
35
28
  TransactionStatus,
36
29
  TransactionTokenAssociate,
37
30
  } from "../types";
38
31
  import { rpcClient } from "../network/rpc";
39
32
  import { HederaRecipientInvalidChecksum } from "../errors";
40
- import { getCurrentHederaPreloadData } from "../preload-data";
41
33
 
42
34
  export const serializeSignature = (signature: Uint8Array) => {
43
35
  return Buffer.from(signature).toString("base64");
@@ -96,14 +88,6 @@ export const mapIntentToSDKOperation = (txIntent: TransactionIntent) => {
96
88
  return HEDERA_OPERATION_TYPES.ContractCall;
97
89
  }
98
90
 
99
- if (
100
- txIntent.type === HEDERA_TRANSACTION_MODES.Delegate ||
101
- txIntent.type === HEDERA_TRANSACTION_MODES.Undelegate ||
102
- txIntent.type === HEDERA_TRANSACTION_MODES.Redelegate
103
- ) {
104
- return HEDERA_OPERATION_TYPES.CryptoUpdate;
105
- }
106
-
107
91
  return HEDERA_OPERATION_TYPES.CryptoTransfer;
108
92
  };
109
93
 
@@ -138,10 +122,8 @@ export const getTransactionExplorer = (
138
122
  );
139
123
  };
140
124
 
141
- export const isTokenAssociateTransaction = (
142
- tx: Transaction | null | undefined,
143
- ): tx is TransactionTokenAssociate => {
144
- return tx?.mode === HEDERA_TRANSACTION_MODES.TokenAssociate;
125
+ export const isTokenAssociateTransaction = (tx: Transaction): tx is TransactionTokenAssociate => {
126
+ return tx.mode === HEDERA_TRANSACTION_MODES.TokenAssociate;
145
127
  };
146
128
 
147
129
  export const isAutoTokenAssociationEnabled = (account: AccountLike) => {
@@ -168,42 +150,6 @@ export const isValidExtra = (extra: unknown): extra is HederaOperationExtra => {
168
150
  return !!extra && typeof extra === "object" && !Array.isArray(extra);
169
151
  };
170
152
 
171
- export const getOperationDetailsExtraFields = (
172
- extra: HederaOperationExtra,
173
- ): OperationDetailsExtraField[] => {
174
- const fields: OperationDetailsExtraField[] = [];
175
-
176
- if (typeof extra.memo === "string") {
177
- fields.push({ key: "memo", value: extra.memo });
178
- }
179
-
180
- if (typeof extra.associatedTokenId === "string") {
181
- fields.push({ key: "associatedTokenId", value: extra.associatedTokenId });
182
- }
183
-
184
- if (typeof extra.targetStakingNodeId === "number") {
185
- fields.push({ key: "targetStakingNodeId", value: extra.targetStakingNodeId.toString() });
186
- }
187
-
188
- if (typeof extra.previousStakingNodeId === "number") {
189
- fields.push({ key: "previousStakingNodeId", value: extra.previousStakingNodeId.toString() });
190
- }
191
-
192
- if (typeof extra.gasConsumed === "number") {
193
- fields.push({ key: "gasConsumed", value: extra.gasConsumed.toString() });
194
- }
195
-
196
- if (typeof extra.gasUsed === "number") {
197
- fields.push({ key: "gasUsed", value: extra.gasUsed.toString() });
198
- }
199
-
200
- if (typeof extra.gasLimit === "number") {
201
- fields.push({ key: "gasLimit", value: extra.gasLimit.toString() });
202
- }
203
-
204
- return fields;
205
- };
206
-
207
153
  // disables the "Continue" button in the Send modal's Recipient step during token transfers if:
208
154
  // - the recipient is not associated with the token
209
155
  // - the association status can't be verified
@@ -266,15 +212,6 @@ export const checkAccountTokenAssociationStatus = makeLRUCache(
266
212
  seconds(30),
267
213
  );
268
214
 
269
- export const getChecksum = (accountId: string): string | null => {
270
- try {
271
- const entityId = EntityIdHelper.fromString(accountId);
272
- return entityId.checksum ?? null;
273
- } catch {
274
- return null;
275
- }
276
- };
277
-
278
215
  export const safeParseAccountId = (
279
216
  address: string,
280
217
  ): [Error, null] | [null, { accountId: string; checksum: string | null }] => {
@@ -283,7 +220,7 @@ export const safeParseAccountId = (
283
220
 
284
221
  try {
285
222
  const accountId = AccountId.fromString(address);
286
- const checksum = getChecksum(address);
223
+ const checksum = EntityIdHelper.fromString(address).checksum ?? null;
287
224
 
288
225
  if (checksum) {
289
226
  const client = rpcClient.getInstance();
@@ -402,94 +339,3 @@ export const fromEVMAddress = (evmAddress: string, shard = 0, realm = 0): string
402
339
  return null;
403
340
  }
404
341
  };
405
-
406
- export const extractCompanyFromNodeDescription = (description: string): string => {
407
- return description
408
- .split("|")[0]
409
- .replace(/hosted by/i, "")
410
- .replace(/hosted for/i, "")
411
- .trim();
412
- };
413
-
414
- export const sortValidators = (validators: HederaValidator[]): HederaValidator[] => {
415
- const ledgerNodeId = getEnv("HEDERA_STAKING_LEDGER_NODE_ID");
416
-
417
- // sort validators by active stake in DESC order, with Ledger node first if it exists
418
- return [...validators].sort((a, b) => {
419
- if (typeof ledgerNodeId === "number") {
420
- if (a.nodeId === ledgerNodeId) return -1;
421
- if (b.nodeId === ledgerNodeId) return 1;
422
- }
423
-
424
- return b.activeStake.toNumber() - a.activeStake.toNumber();
425
- });
426
- };
427
-
428
- export const filterValidatorBySearchTerm = (
429
- validator: HederaValidator,
430
- search: string,
431
- ): boolean => {
432
- const lowercaseSearch = search.toLowerCase();
433
- const addressWithChecksum = validator.addressChecksum
434
- ? `${validator.address}-${validator.addressChecksum}`
435
- : validator.address;
436
-
437
- return (
438
- validator.nodeId.toString().includes(lowercaseSearch) ||
439
- validator.name.toLowerCase().includes(lowercaseSearch) ||
440
- addressWithChecksum.toLowerCase().includes(lowercaseSearch)
441
- );
442
- };
443
-
444
- export const getValidatorFromAccount = (account: HederaAccount): HederaValidator | null => {
445
- const { delegation } = account.hederaResources ?? {};
446
-
447
- if (!delegation) {
448
- return null;
449
- }
450
-
451
- const validators = getCurrentHederaPreloadData(account.currency);
452
- const validator = validators.validators.find(v => v.nodeId === delegation.nodeId) ?? null;
453
-
454
- return validator;
455
- };
456
-
457
- export const getDefaultValidator = (validators: HederaValidator[]): HederaValidator | null => {
458
- const ledgerNodeId = getEnv("HEDERA_STAKING_LEDGER_NODE_ID");
459
-
460
- return validators.find(v => v.nodeId === ledgerNodeId) ?? null;
461
- };
462
-
463
- export const getDelegationStatus = (
464
- validator: HederaValidator | null,
465
- ): HEDERA_DELEGATION_STATUS => {
466
- if (!validator?.address) {
467
- return HEDERA_DELEGATION_STATUS.Inactive;
468
- }
469
-
470
- if (validator.overstaked) {
471
- return HEDERA_DELEGATION_STATUS.Overstaked;
472
- }
473
-
474
- return HEDERA_DELEGATION_STATUS.Active;
475
- };
476
-
477
- export const isStakingTransaction = (
478
- tx: Transaction | null | undefined,
479
- ): tx is TransactionStaking => {
480
- if (!tx) return false;
481
-
482
- return (
483
- tx.mode === HEDERA_TRANSACTION_MODES.Delegate ||
484
- tx.mode === HEDERA_TRANSACTION_MODES.Undelegate ||
485
- tx.mode === HEDERA_TRANSACTION_MODES.Redelegate ||
486
- tx.mode === HEDERA_TRANSACTION_MODES.ClaimRewards
487
- );
488
- };
489
-
490
- export const hasSpecificIntentData = <Type extends "staking" | "erc20">(
491
- txIntent: TransactionIntent<HederaMemo, HederaTxData>,
492
- expectedType: Type,
493
- ): txIntent is Extract<TransactionIntent<HederaMemo, HederaTxData>, { data: { type: Type } }> => {
494
- return "data" in txIntent && txIntent.data.type === expectedType;
495
- };