@ledgerhq/coin-hedera 1.16.0-nightly.20251212024049 → 1.16.0-nightly.20251215100948

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 (131) hide show
  1. package/CHANGELOG.md +12 -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/constants.d.ts +11 -6
  9. package/lib/constants.d.ts.map +1 -1
  10. package/lib/constants.js +20 -1
  11. package/lib/constants.js.map +1 -1
  12. package/lib/deviceTransactionConfig.d.ts.map +1 -1
  13. package/lib/deviceTransactionConfig.js +1 -3
  14. package/lib/deviceTransactionConfig.js.map +1 -1
  15. package/lib/logic/getBalance.d.ts.map +1 -1
  16. package/lib/logic/getBalance.js +21 -4
  17. package/lib/logic/getBalance.js.map +1 -1
  18. package/lib/logic/getBlock.d.ts.map +1 -1
  19. package/lib/logic/getBlock.js +39 -2
  20. package/lib/logic/getBlock.js.map +1 -1
  21. package/lib/logic/getValidators.d.ts +3 -0
  22. package/lib/logic/getValidators.d.ts.map +1 -0
  23. package/lib/logic/getValidators.js +24 -0
  24. package/lib/logic/getValidators.js.map +1 -0
  25. package/lib/logic/index.d.ts +1 -0
  26. package/lib/logic/index.d.ts.map +1 -1
  27. package/lib/logic/index.js +3 -1
  28. package/lib/logic/index.js.map +1 -1
  29. package/lib/logic/listOperations.d.ts.map +1 -1
  30. package/lib/logic/listOperations.js +16 -2
  31. package/lib/logic/listOperations.js.map +1 -1
  32. package/lib/logic/utils.d.ts +17 -1
  33. package/lib/logic/utils.d.ts.map +1 -1
  34. package/lib/logic/utils.js +54 -1
  35. package/lib/logic/utils.js.map +1 -1
  36. package/lib/network/api.d.ts +22 -2
  37. package/lib/network/api.d.ts.map +1 -1
  38. package/lib/network/api.js +49 -14
  39. package/lib/network/api.js.map +1 -1
  40. package/lib/preload.js +2 -2
  41. package/lib/preload.js.map +1 -1
  42. package/lib/test/fixtures/account.fixture.d.ts +8 -0
  43. package/lib/test/fixtures/account.fixture.d.ts.map +1 -1
  44. package/lib/test/fixtures/account.fixture.js +8 -0
  45. package/lib/test/fixtures/account.fixture.js.map +1 -1
  46. package/lib/test/fixtures/mirror.fixture.d.ts +2 -1
  47. package/lib/test/fixtures/mirror.fixture.d.ts.map +1 -1
  48. package/lib/test/fixtures/mirror.fixture.js +16 -1
  49. package/lib/test/fixtures/mirror.fixture.js.map +1 -1
  50. package/lib/types/bridge.d.ts +1 -0
  51. package/lib/types/bridge.d.ts.map +1 -1
  52. package/lib/types/logic.d.ts +6 -0
  53. package/lib/types/logic.d.ts.map +1 -1
  54. package/lib-es/api/index.d.ts.map +1 -1
  55. package/lib-es/api/index.js +5 -4
  56. package/lib-es/api/index.js.map +1 -1
  57. package/lib-es/bridge/buildOptimisticOperation.d.ts.map +1 -1
  58. package/lib-es/bridge/buildOptimisticOperation.js +15 -44
  59. package/lib-es/bridge/buildOptimisticOperation.js.map +1 -1
  60. package/lib-es/constants.d.ts +11 -6
  61. package/lib-es/constants.d.ts.map +1 -1
  62. package/lib-es/constants.js +19 -0
  63. package/lib-es/constants.js.map +1 -1
  64. package/lib-es/deviceTransactionConfig.d.ts.map +1 -1
  65. package/lib-es/deviceTransactionConfig.js +2 -4
  66. package/lib-es/deviceTransactionConfig.js.map +1 -1
  67. package/lib-es/logic/getBalance.d.ts.map +1 -1
  68. package/lib-es/logic/getBalance.js +21 -4
  69. package/lib-es/logic/getBalance.js.map +1 -1
  70. package/lib-es/logic/getBlock.d.ts.map +1 -1
  71. package/lib-es/logic/getBlock.js +40 -3
  72. package/lib-es/logic/getBlock.js.map +1 -1
  73. package/lib-es/logic/getValidators.d.ts +3 -0
  74. package/lib-es/logic/getValidators.d.ts.map +1 -0
  75. package/lib-es/logic/getValidators.js +20 -0
  76. package/lib-es/logic/getValidators.js.map +1 -0
  77. package/lib-es/logic/index.d.ts +1 -0
  78. package/lib-es/logic/index.d.ts.map +1 -1
  79. package/lib-es/logic/index.js +1 -0
  80. package/lib-es/logic/index.js.map +1 -1
  81. package/lib-es/logic/listOperations.d.ts.map +1 -1
  82. package/lib-es/logic/listOperations.js +17 -3
  83. package/lib-es/logic/listOperations.js.map +1 -1
  84. package/lib-es/logic/utils.d.ts +17 -1
  85. package/lib-es/logic/utils.d.ts.map +1 -1
  86. package/lib-es/logic/utils.js +52 -1
  87. package/lib-es/logic/utils.js.map +1 -1
  88. package/lib-es/network/api.d.ts +22 -2
  89. package/lib-es/network/api.d.ts.map +1 -1
  90. package/lib-es/network/api.js +49 -14
  91. package/lib-es/network/api.js.map +1 -1
  92. package/lib-es/preload.js +2 -2
  93. package/lib-es/preload.js.map +1 -1
  94. package/lib-es/test/fixtures/account.fixture.d.ts +8 -0
  95. package/lib-es/test/fixtures/account.fixture.d.ts.map +1 -1
  96. package/lib-es/test/fixtures/account.fixture.js +8 -0
  97. package/lib-es/test/fixtures/account.fixture.js.map +1 -1
  98. package/lib-es/test/fixtures/mirror.fixture.d.ts +2 -1
  99. package/lib-es/test/fixtures/mirror.fixture.d.ts.map +1 -1
  100. package/lib-es/test/fixtures/mirror.fixture.js +14 -0
  101. package/lib-es/test/fixtures/mirror.fixture.js.map +1 -1
  102. package/lib-es/types/bridge.d.ts +1 -0
  103. package/lib-es/types/bridge.d.ts.map +1 -1
  104. package/lib-es/types/logic.d.ts +6 -0
  105. package/lib-es/types/logic.d.ts.map +1 -1
  106. package/package.json +10 -10
  107. package/src/api/index.integ.test.ts +226 -1
  108. package/src/api/index.test.ts +5 -2
  109. package/src/api/index.ts +5 -5
  110. package/src/bridge/{buildOptimisticOperation.integration.test.ts → buildOptimisticOperation.test.ts} +23 -68
  111. package/src/bridge/buildOptimisticOperation.ts +16 -45
  112. package/src/constants.ts +23 -1
  113. package/src/deviceTransactionConfig.test.ts +59 -43
  114. package/src/deviceTransactionConfig.ts +2 -5
  115. package/src/logic/getBalance.test.ts +50 -0
  116. package/src/logic/getBalance.ts +21 -4
  117. package/src/logic/getBlock.test.ts +283 -1
  118. package/src/logic/getBlock.ts +57 -6
  119. package/src/logic/getValidators.test.ts +50 -0
  120. package/src/logic/getValidators.ts +22 -0
  121. package/src/logic/index.ts +1 -0
  122. package/src/logic/listOperations.ts +33 -3
  123. package/src/logic/utils.test.ts +113 -0
  124. package/src/logic/utils.ts +67 -1
  125. package/src/network/api.test.ts +55 -9
  126. package/src/network/api.ts +66 -14
  127. package/src/preload.ts +2 -2
  128. package/src/test/fixtures/account.fixture.ts +8 -0
  129. package/src/test/fixtures/mirror.fixture.ts +18 -0
  130. package/src/types/bridge.ts +1 -0
  131. package/src/types/logic.ts +7 -0
@@ -1,7 +1,6 @@
1
1
  import BigNumber from "bignumber.js";
2
2
  import { buildOptimisticOperation } from "./buildOptimisticOperation";
3
- import { HEDERA_OPERATION_TYPES, HEDERA_TRANSACTION_MODES } from "../constants";
4
- import { estimateFees } from "../logic/estimateFees";
3
+ import { HEDERA_TRANSACTION_MODES } from "../constants";
5
4
  import { getMockedAccount, getMockedTokenAccount } from "../test/fixtures/account.fixture";
6
5
  import {
7
6
  getMockedERC20TokenCurrency,
@@ -17,16 +16,12 @@ describe("buildOptimisticOperation", () => {
17
16
  mode: HEDERA_TRANSACTION_MODES.TokenAssociate,
18
17
  amount: new BigNumber(0),
19
18
  recipient: "0.0.1234",
19
+ maxFee: new BigNumber(1000),
20
20
  properties: {
21
21
  token: mockedToken,
22
22
  },
23
23
  });
24
24
 
25
- const estimatedFee = await estimateFees({
26
- currency: mockedAccount.currency,
27
- operationType: HEDERA_OPERATION_TYPES.TokenAssociate,
28
- });
29
-
30
25
  const op = await buildOptimisticOperation({
31
26
  account: mockedAccount,
32
27
  transaction: mockedTransaction,
@@ -34,7 +29,7 @@ describe("buildOptimisticOperation", () => {
34
29
 
35
30
  expect(op.type).toBe("ASSOCIATE_TOKEN");
36
31
  expect(op.extra).toEqual({ associatedTokenId: mockedToken.contractAddress });
37
- expect(op.fee).toEqual(estimatedFee.tinybars);
32
+ expect(op.fee).toEqual(mockedTransaction.maxFee);
38
33
  expect(op.senders).toContain(mockedAccount.freshAddress);
39
34
  expect(op.recipients).toContain("0.0.1234");
40
35
  });
@@ -44,11 +39,7 @@ describe("buildOptimisticOperation", () => {
44
39
  const mockedTransaction = getMockedTransaction({
45
40
  amount: new BigNumber(123),
46
41
  recipient: "0.0.5678",
47
- });
48
-
49
- const estimatedFee = await estimateFees({
50
- currency: mockedAccount.currency,
51
- operationType: HEDERA_OPERATION_TYPES.CryptoTransfer,
42
+ maxFee: new BigNumber(1500),
52
43
  });
53
44
 
54
45
  const op = await buildOptimisticOperation({
@@ -57,14 +48,13 @@ describe("buildOptimisticOperation", () => {
57
48
  });
58
49
 
59
50
  expect(op.type).toBe("OUT");
60
- expect(op.fee).toEqual(estimatedFee.tinybars);
51
+ expect(op.fee).toEqual(mockedTransaction.maxFee);
61
52
  expect(op.value).toEqual(new BigNumber(123));
62
53
  expect(op.senders).toContain(mockedAccount.freshAddress);
63
54
  expect(op.recipients).toContain("0.0.5678");
64
55
  });
65
56
 
66
57
  it("builds optimistic operation for HTS token", async () => {
67
- const mockedAccount = getMockedAccount();
68
58
  const mockedTokenCurrency = getMockedHTSTokenCurrency();
69
59
  const tokenAccount = getMockedTokenAccount(mockedTokenCurrency);
70
60
  const parentAccount = getMockedAccount({ subAccounts: [tokenAccount] });
@@ -72,11 +62,7 @@ describe("buildOptimisticOperation", () => {
72
62
  subAccountId: tokenAccount.id,
73
63
  amount: new BigNumber(123),
74
64
  recipient: "0.0.9999",
75
- });
76
-
77
- const estimatedFee = await estimateFees({
78
- currency: mockedAccount.currency,
79
- operationType: HEDERA_OPERATION_TYPES.TokenTransfer,
65
+ maxFee: new BigNumber(2000),
80
66
  });
81
67
 
82
68
  const op = await buildOptimisticOperation({
@@ -86,11 +72,11 @@ describe("buildOptimisticOperation", () => {
86
72
  const subOp = (op.subOperations ?? [])[0];
87
73
 
88
74
  expect(op.type).toBe("FEES");
89
- expect(op.value).toEqual(estimatedFee.tinybars);
75
+ expect(op.value).toEqual(mockedTransaction.maxFee);
90
76
  expect(op.subOperations).toHaveLength(1);
91
77
  expect(subOp.type).toBe("OUT");
92
78
  expect(subOp.value).toEqual(new BigNumber(123));
93
- expect(subOp.fee).toEqual(estimatedFee.tinybars);
79
+ expect(subOp.fee).toEqual(mockedTransaction.maxFee);
94
80
  expect(subOp.accountId).toBe(tokenAccount.id);
95
81
  expect(subOp.recipients).toContain("0.0.9999");
96
82
  });
@@ -103,22 +89,7 @@ describe("buildOptimisticOperation", () => {
103
89
  subAccountId: tokenAccount.id,
104
90
  amount: new BigNumber(123),
105
91
  recipient: "0.0.9999",
106
- });
107
-
108
- const estimatedFee = await estimateFees({
109
- operationType: HEDERA_OPERATION_TYPES.ContractCall,
110
- txIntent: {
111
- intentType: "transaction",
112
- type: HEDERA_TRANSACTION_MODES.Send,
113
- asset: {
114
- type: "erc20",
115
- assetReference: tokenAccount.token.contractAddress,
116
- assetOwner: parentAccount.freshAddress,
117
- },
118
- amount: BigInt(mockedTransaction.amount.toString()),
119
- sender: parentAccount.freshAddress,
120
- recipient: mockedTransaction.recipient,
121
- },
92
+ maxFee: new BigNumber(2500),
122
93
  });
123
94
 
124
95
  const op = await buildOptimisticOperation({
@@ -128,11 +99,11 @@ describe("buildOptimisticOperation", () => {
128
99
  const subOp = (op.subOperations ?? [])[0];
129
100
 
130
101
  expect(op.type).toBe("FEES");
131
- expect(op.value).toEqual(estimatedFee.tinybars);
102
+ expect(op.value).toEqual(mockedTransaction.maxFee);
132
103
  expect(op.subOperations).toHaveLength(1);
133
104
  expect(subOp.type).toBe("OUT");
134
105
  expect(subOp.value).toEqual(new BigNumber(123));
135
- expect(subOp.fee).toEqual(estimatedFee.tinybars);
106
+ expect(subOp.fee).toEqual(mockedTransaction.maxFee);
136
107
  expect(subOp.accountId).toBe(tokenAccount.id);
137
108
  expect(subOp.recipients).toContain("0.0.9999");
138
109
  });
@@ -144,23 +115,19 @@ describe("buildOptimisticOperation", () => {
144
115
  mode: HEDERA_TRANSACTION_MODES.Delegate,
145
116
  amount: new BigNumber(0),
146
117
  recipient: "",
118
+ maxFee: new BigNumber(1200),
147
119
  properties: {
148
120
  stakingNodeId,
149
121
  },
150
122
  });
151
123
 
152
- const estimatedFee = await estimateFees({
153
- currency: mockedAccount.currency,
154
- operationType: HEDERA_OPERATION_TYPES.CryptoUpdate,
155
- });
156
-
157
124
  const op = await buildOptimisticOperation({
158
125
  account: mockedAccount,
159
126
  transaction: mockedTransaction,
160
127
  });
161
128
 
162
- expect(op.type).toBe("UPDATE_ACCOUNT");
163
- expect(op.fee).toEqual(estimatedFee.tinybars);
129
+ expect(op.type).toBe("DELEGATE");
130
+ expect(op.fee).toEqual(mockedTransaction.maxFee);
164
131
  expect(op.value).toEqual(new BigNumber(0));
165
132
  expect(op.senders).toContain(mockedAccount.freshAddress);
166
133
  expect(op.extra).toEqual({
@@ -188,15 +155,11 @@ describe("buildOptimisticOperation", () => {
188
155
  mode: HEDERA_TRANSACTION_MODES.Redelegate,
189
156
  amount: new BigNumber(0),
190
157
  recipient: "",
158
+ maxFee: new BigNumber(1300),
159
+ memo: "Redelegating to better validator",
191
160
  properties: {
192
161
  stakingNodeId: newNodeId,
193
162
  },
194
- memo: "Redelegating to better validator",
195
- });
196
-
197
- const estimatedFee = await estimateFees({
198
- currency: mockedAccount.currency,
199
- operationType: HEDERA_OPERATION_TYPES.CryptoUpdate,
200
163
  });
201
164
 
202
165
  const op = await buildOptimisticOperation({
@@ -204,8 +167,8 @@ describe("buildOptimisticOperation", () => {
204
167
  transaction: mockedTransaction,
205
168
  });
206
169
 
207
- expect(op.type).toBe("UPDATE_ACCOUNT");
208
- expect(op.fee).toEqual(estimatedFee.tinybars);
170
+ expect(op.type).toBe("REDELEGATE");
171
+ expect(op.fee).toEqual(mockedTransaction.maxFee);
209
172
  expect(op.extra).toEqual({
210
173
  memo: "Redelegating to better validator",
211
174
  targetStakingNodeId: newNodeId,
@@ -230,23 +193,19 @@ describe("buildOptimisticOperation", () => {
230
193
  mode: HEDERA_TRANSACTION_MODES.Undelegate,
231
194
  amount: new BigNumber(0),
232
195
  recipient: "",
196
+ maxFee: new BigNumber(1100),
233
197
  properties: {
234
198
  stakingNodeId: null,
235
199
  },
236
200
  });
237
201
 
238
- const estimatedFee = await estimateFees({
239
- currency: mockedAccount.currency,
240
- operationType: HEDERA_OPERATION_TYPES.CryptoUpdate,
241
- });
242
-
243
202
  const op = await buildOptimisticOperation({
244
203
  account: mockedAccount,
245
204
  transaction: mockedTransaction,
246
205
  });
247
206
 
248
- expect(op.type).toBe("UPDATE_ACCOUNT");
249
- expect(op.fee).toEqual(estimatedFee.tinybars);
207
+ expect(op.type).toBe("UNDELEGATE");
208
+ expect(op.fee).toEqual(mockedTransaction.maxFee);
250
209
  expect(op.value).toEqual(new BigNumber(0));
251
210
  expect(op.extra).toEqual({
252
211
  memo: null,
@@ -272,21 +231,17 @@ describe("buildOptimisticOperation", () => {
272
231
  mode: HEDERA_TRANSACTION_MODES.ClaimRewards,
273
232
  amount: new BigNumber(0),
274
233
  recipient: "",
234
+ maxFee: new BigNumber(1400),
275
235
  memo: "Claiming staking rewards",
276
236
  });
277
237
 
278
- const estimatedFee = await estimateFees({
279
- currency: mockedAccount.currency,
280
- operationType: HEDERA_OPERATION_TYPES.CryptoTransfer,
281
- });
282
-
283
238
  const op = await buildOptimisticOperation({
284
239
  account: mockedAccount,
285
240
  transaction: mockedTransaction,
286
241
  });
287
242
 
288
243
  expect(op.type).toBe("OUT");
289
- expect(op.fee).toEqual(estimatedFee.tinybars);
244
+ expect(op.fee).toEqual(mockedTransaction.maxFee);
290
245
  expect(op.extra).toEqual({
291
246
  memo: "Claiming staking rewards",
292
247
  });
@@ -3,8 +3,7 @@ import invariant from "invariant";
3
3
  import type { Account, Operation, OperationType, TokenAccount } from "@ledgerhq/types-live";
4
4
  import { encodeOperationId } from "@ledgerhq/coin-framework/operation";
5
5
  import { findSubAccountById } from "@ledgerhq/coin-framework/account/helpers";
6
- import { HEDERA_OPERATION_TYPES, HEDERA_TRANSACTION_MODES } from "../constants";
7
- import { estimateFees } from "../logic/estimateFees";
6
+ import { HEDERA_TRANSACTION_MODES, MAP_STAKING_MODE_TO_OPERATION_TYPE } from "../constants";
8
7
  import {
9
8
  safeParseAccountId,
10
9
  isTokenAssociateTransaction,
@@ -21,18 +20,15 @@ const buildOptimisticTokenAssociateOperation = async ({
21
20
  }): Promise<Operation> => {
22
21
  invariant(isTokenAssociateTransaction(transaction), "invalid transaction properties");
23
22
 
24
- const estimatedFee = await estimateFees({
25
- currency: account.currency,
26
- operationType: HEDERA_OPERATION_TYPES.TokenAssociate,
27
- });
23
+ const fee = transaction.maxFee ?? new BigNumber(0);
28
24
  const type: OperationType = "ASSOCIATE_TOKEN";
29
25
 
30
26
  const operation: Operation = {
31
27
  id: encodeOperationId(account.id, "", type),
32
28
  hash: "",
33
29
  type,
34
- value: estimatedFee.tinybars,
35
- fee: estimatedFee.tinybars,
30
+ value: fee,
31
+ fee,
36
32
  blockHash: null,
37
33
  blockHeight: null,
38
34
  senders: [account.freshAddress.toString()],
@@ -56,13 +52,8 @@ const buildOptimisticCoinOperation = async ({
56
52
  transaction: Transaction;
57
53
  transactionType?: OperationType;
58
54
  }): Promise<Operation> => {
59
- const estimatedFee =
60
- transactionType === "FEES"
61
- ? transaction.amount
62
- : await estimateFees({
63
- currency: account.currency,
64
- operationType: HEDERA_OPERATION_TYPES.CryptoTransfer,
65
- });
55
+ const fee =
56
+ transactionType === "FEES" ? transaction.amount : transaction.maxFee ?? new BigNumber(0);
66
57
  const value = transaction.amount;
67
58
  const type: OperationType = transactionType ?? "OUT";
68
59
  const [_, recipientAddress] = safeParseAccountId(transaction.recipient);
@@ -74,7 +65,7 @@ const buildOptimisticCoinOperation = async ({
74
65
  hash: "",
75
66
  type,
76
67
  value,
77
- fee: BigNumber.isBigNumber(estimatedFee) ? estimatedFee : estimatedFee.tinybars,
68
+ fee,
78
69
  blockHash: null,
79
70
  blockHeight: null,
80
71
  senders: [account.freshAddress.toString()],
@@ -98,10 +89,7 @@ const buildOptimisticHTSTokenOperation = async ({
98
89
  tokenAccount: TokenAccount;
99
90
  transaction: Transaction;
100
91
  }): Promise<Operation> => {
101
- const estimatedFee = await estimateFees({
102
- currency: account.currency,
103
- operationType: HEDERA_OPERATION_TYPES.TokenTransfer,
104
- });
92
+ const fee = transaction.maxFee ?? new BigNumber(0);
105
93
  const value = transaction.amount;
106
94
  const type: OperationType = "OUT";
107
95
  const [_, recipientAddress] = safeParseAccountId(transaction.recipient);
@@ -112,7 +100,7 @@ const buildOptimisticHTSTokenOperation = async ({
112
100
  account,
113
101
  transaction: {
114
102
  ...transaction,
115
- amount: estimatedFee.tinybars,
103
+ amount: fee,
116
104
  },
117
105
  transactionType: "FEES",
118
106
  });
@@ -125,7 +113,7 @@ const buildOptimisticHTSTokenOperation = async ({
125
113
  hash: "",
126
114
  type,
127
115
  value,
128
- fee: estimatedFee.tinybars,
116
+ fee,
129
117
  blockHash: null,
130
118
  blockHeight: null,
131
119
  senders: [account.freshAddress.toString()],
@@ -151,21 +139,7 @@ const buildOptimisticERC20TokenOperation = async ({
151
139
  tokenAccount: TokenAccount;
152
140
  transaction: Transaction;
153
141
  }): Promise<Operation> => {
154
- const estimatedFees = await estimateFees({
155
- operationType: HEDERA_OPERATION_TYPES.ContractCall,
156
- txIntent: {
157
- intentType: "transaction",
158
- type: HEDERA_TRANSACTION_MODES.Send,
159
- asset: {
160
- type: "erc20",
161
- assetReference: tokenAccount.token.contractAddress,
162
- assetOwner: account.freshAddress,
163
- },
164
- amount: BigInt(transaction.amount.toString()),
165
- sender: account.freshAddress,
166
- recipient: transaction.recipient,
167
- },
168
- });
142
+ const fee = transaction.maxFee ?? new BigNumber(0);
169
143
  const value = transaction.amount;
170
144
  const type: OperationType = "OUT";
171
145
  const memo = transaction.memo;
@@ -174,7 +148,7 @@ const buildOptimisticERC20TokenOperation = async ({
174
148
  account,
175
149
  transaction: {
176
150
  ...transaction,
177
- amount: estimatedFees.tinybars,
151
+ amount: fee,
178
152
  },
179
153
  transactionType: "FEES",
180
154
  });
@@ -187,7 +161,7 @@ const buildOptimisticERC20TokenOperation = async ({
187
161
  hash: "",
188
162
  type,
189
163
  value,
190
- fee: estimatedFees.tinybars,
164
+ fee,
191
165
  blockHash: null,
192
166
  blockHeight: null,
193
167
  senders: [account.freshAddress.toString()],
@@ -213,19 +187,16 @@ const buildOptimisticUpdateAccountOperation = async ({
213
187
  }): Promise<Operation> => {
214
188
  invariant(isStakingTransaction(transaction), "invalid transaction properties");
215
189
 
216
- const estimatedFee = await estimateFees({
217
- operationType: HEDERA_OPERATION_TYPES.CryptoUpdate,
218
- currency: account.currency,
219
- });
190
+ const fee = transaction.maxFee ?? new BigNumber(0);
220
191
  const value = transaction.amount;
221
- const type: OperationType = "UPDATE_ACCOUNT";
192
+ const type: OperationType = MAP_STAKING_MODE_TO_OPERATION_TYPE[transaction.mode];
222
193
 
223
194
  const operation: Operation = {
224
195
  id: encodeOperationId(account.id, "", type),
225
196
  hash: "",
226
197
  type,
227
198
  value,
228
- fee: estimatedFee.tinybars,
199
+ fee,
229
200
  blockHash: null,
230
201
  blockHeight: null,
231
202
  senders: [account.freshAddress.toString()],
package/src/constants.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import BigNumber from "bignumber.js";
2
+ import type { OperationType } from "@ledgerhq/types-live";
2
3
 
3
4
  /**
4
5
  * Internal types to distinguish custom Hedera transaction behaviors.
@@ -13,6 +14,14 @@ export enum HEDERA_TRANSACTION_MODES {
13
14
  ClaimRewards = "claim-rewards",
14
15
  }
15
16
 
17
+ /**
18
+ * Enum representing Hedera transaction names used in the Hedera Mirror Node API.
19
+ */
20
+ export enum HEDERA_TRANSACTION_NAMES {
21
+ ContractCall = "CONTRACTCALL",
22
+ UpdateAccount = "CRYPTOUPDATEACCOUNT",
23
+ }
24
+
16
25
  /**
17
26
  * Enum representing the supported Hedera operation types for fee estimation
18
27
  */
@@ -100,9 +109,22 @@ export const SUPPORTED_ERC20_TOKENS = [
100
109
  },
101
110
  ];
102
111
 
103
- export const MAP_STAKING_MODE_TO_MEMO = {
112
+ export const MAP_STAKING_MODE_TO_MEMO: Record<string, string> = {
104
113
  [HEDERA_TRANSACTION_MODES.ClaimRewards]: "Collect Staking Rewards",
105
114
  [HEDERA_TRANSACTION_MODES.Delegate]: "Stake",
106
115
  [HEDERA_TRANSACTION_MODES.Undelegate]: "Unstake",
107
116
  [HEDERA_TRANSACTION_MODES.Redelegate]: "Restake",
108
117
  } as const;
118
+
119
+ export const MAP_STAKING_MODE_TO_OPERATION_TYPE: Record<string, OperationType> = {
120
+ [HEDERA_TRANSACTION_MODES.Delegate]: "DELEGATE",
121
+ [HEDERA_TRANSACTION_MODES.Undelegate]: "UNDELEGATE",
122
+ [HEDERA_TRANSACTION_MODES.Redelegate]: "REDELEGATE",
123
+ };
124
+
125
+ export const MAP_STAKING_MODE_TO_METHOD: Record<string, string> = {
126
+ [HEDERA_TRANSACTION_MODES.Delegate]: "Delegate",
127
+ [HEDERA_TRANSACTION_MODES.Undelegate]: "Undelegate",
128
+ [HEDERA_TRANSACTION_MODES.Redelegate]: "Redelegate",
129
+ [HEDERA_TRANSACTION_MODES.ClaimRewards]: "Claim Rewards",
130
+ };
@@ -1,14 +1,12 @@
1
1
  import BigNumber from "bignumber.js";
2
- import type { Account } from "@ledgerhq/types-live";
3
2
  import { HEDERA_TRANSACTION_MODES } from "./constants";
4
3
  import getDeviceTransactionConfig from "./deviceTransactionConfig";
5
- import type { Transaction, TransactionStatus } from "./types";
4
+ import type { TransactionStatus } from "./types";
5
+ import { getMockedAccount } from "./test/fixtures/account.fixture";
6
+ import { getMockedTransaction } from "./test/fixtures/transaction.fixture";
6
7
 
7
8
  describe("getDeviceTransactionConfig", () => {
8
- const mockAccount = {
9
- id: "mock-account-id",
10
- currency: { id: "hedera" },
11
- } as Account;
9
+ const mockAccount = getMockedAccount({ id: "mock-account-id" });
12
10
 
13
11
  const createMockStatus = (estimatedFees: BigNumber): TransactionStatus => ({
14
12
  errors: {},
@@ -20,13 +18,11 @@ describe("getDeviceTransactionConfig", () => {
20
18
 
21
19
  describe("staking transactions", () => {
22
20
  it("should return correct fields for ClaimRewards transaction", async () => {
23
- const transaction = {
24
- family: "hedera",
21
+ const transaction = getMockedTransaction({
25
22
  mode: HEDERA_TRANSACTION_MODES.ClaimRewards,
26
23
  amount: new BigNumber(0),
27
- recipient: "",
28
24
  memo: "Claiming rewards",
29
- } as Transaction;
25
+ });
30
26
 
31
27
  const status = createMockStatus(new BigNumber(100000));
32
28
 
@@ -55,15 +51,48 @@ describe("getDeviceTransactionConfig", () => {
55
51
  });
56
52
 
57
53
  it("should return correct fields for Delegate transaction", async () => {
58
- const transaction = {
59
- family: "hedera",
54
+ const transaction = getMockedTransaction({
60
55
  mode: HEDERA_TRANSACTION_MODES.Delegate,
61
56
  amount: new BigNumber(0),
62
- recipient: "",
63
57
  properties: {
64
58
  stakingNodeId: 10,
65
59
  },
66
- } as Transaction;
60
+ });
61
+
62
+ const status = createMockStatus(new BigNumber(100000));
63
+
64
+ const fields = await getDeviceTransactionConfig({
65
+ account: mockAccount,
66
+ transaction,
67
+ status,
68
+ });
69
+
70
+ expect(fields).toEqual([
71
+ {
72
+ type: "text",
73
+ label: "Method",
74
+ value: "Delegate",
75
+ },
76
+ {
77
+ label: "Fees",
78
+ type: "fees",
79
+ },
80
+ {
81
+ type: "text",
82
+ label: "Staked Node ID",
83
+ value: "10",
84
+ },
85
+ ]);
86
+ });
87
+
88
+ it("should return correct fields for Redelegate transaction", async () => {
89
+ const transaction = getMockedTransaction({
90
+ mode: HEDERA_TRANSACTION_MODES.Redelegate,
91
+ amount: new BigNumber(0),
92
+ properties: {
93
+ stakingNodeId: 10,
94
+ },
95
+ });
67
96
 
68
97
  const status = createMockStatus(new BigNumber(100000));
69
98
 
@@ -77,7 +106,7 @@ describe("getDeviceTransactionConfig", () => {
77
106
  {
78
107
  type: "text",
79
108
  label: "Method",
80
- value: "Update Account",
109
+ value: "Redelegate",
81
110
  },
82
111
  {
83
112
  label: "Fees",
@@ -92,13 +121,10 @@ describe("getDeviceTransactionConfig", () => {
92
121
  });
93
122
 
94
123
  it("should not include staking node ID if not provided", async () => {
95
- const transaction = {
96
- family: "hedera",
124
+ const transaction = getMockedTransaction({
97
125
  mode: HEDERA_TRANSACTION_MODES.Undelegate,
98
126
  amount: new BigNumber(0),
99
- recipient: "",
100
- properties: {},
101
- } as Transaction;
127
+ });
102
128
 
103
129
  const status = createMockStatus(new BigNumber(100000));
104
130
 
@@ -112,7 +138,7 @@ describe("getDeviceTransactionConfig", () => {
112
138
  {
113
139
  type: "text",
114
140
  label: "Method",
115
- value: "Update Account",
141
+ value: "Undelegate",
116
142
  },
117
143
  {
118
144
  label: "Fees",
@@ -124,14 +150,11 @@ describe("getDeviceTransactionConfig", () => {
124
150
 
125
151
  describe("token associate transactions", () => {
126
152
  it("should return correct fields for TokenAssociate transaction", async () => {
127
- const transaction = {
128
- family: "hedera",
153
+ const transaction = getMockedTransaction({
129
154
  mode: HEDERA_TRANSACTION_MODES.TokenAssociate,
130
- amount: new BigNumber(0),
131
- recipient: "",
132
155
  subAccountId: "token-account-id",
133
156
  memo: "Associating token",
134
- } as Transaction;
157
+ });
135
158
 
136
159
  const status = createMockStatus(new BigNumber(50000));
137
160
 
@@ -160,13 +183,10 @@ describe("getDeviceTransactionConfig", () => {
160
183
  });
161
184
 
162
185
  it("should not include fees if they are zero", async () => {
163
- const transaction = {
164
- family: "hedera",
186
+ const transaction = getMockedTransaction({
165
187
  mode: HEDERA_TRANSACTION_MODES.TokenAssociate,
166
- amount: new BigNumber(0),
167
- recipient: "",
168
188
  subAccountId: "token-account-id",
169
- } as Transaction;
189
+ });
170
190
 
171
191
  const status = createMockStatus(new BigNumber(0));
172
192
 
@@ -188,14 +208,13 @@ describe("getDeviceTransactionConfig", () => {
188
208
 
189
209
  describe("regular transfer transactions", () => {
190
210
  it("should return correct fields for regular Send transaction", async () => {
191
- const transaction = {
192
- family: "hedera",
211
+ const transaction = getMockedTransaction({
193
212
  mode: HEDERA_TRANSACTION_MODES.Send,
194
213
  amount: new BigNumber(1000000),
195
214
  recipient: "0.0.12345",
196
215
  useAllAmount: false,
197
216
  memo: "Payment",
198
- } as Transaction;
217
+ });
199
218
 
200
219
  const status = createMockStatus(new BigNumber(100000));
201
220
 
@@ -228,13 +247,12 @@ describe("getDeviceTransactionConfig", () => {
228
247
  });
229
248
 
230
249
  it("should show 'Transfer All' method when useAllAmount is true", async () => {
231
- const transaction = {
232
- family: "hedera",
250
+ const transaction = getMockedTransaction({
233
251
  mode: HEDERA_TRANSACTION_MODES.Send,
234
252
  amount: new BigNumber(0),
235
253
  recipient: "0.0.12345",
236
254
  useAllAmount: true,
237
- } as Transaction;
255
+ });
238
256
 
239
257
  const status = createMockStatus(new BigNumber(100000));
240
258
 
@@ -252,14 +270,13 @@ describe("getDeviceTransactionConfig", () => {
252
270
  });
253
271
 
254
272
  it("should include gas limit for Send transactions with gasLimit", async () => {
255
- const transaction = {
256
- family: "hedera",
273
+ const transaction = getMockedTransaction({
257
274
  mode: HEDERA_TRANSACTION_MODES.Send,
258
275
  amount: new BigNumber(1000000),
259
276
  recipient: "0.0.12345",
260
277
  useAllAmount: false,
261
278
  gasLimit: new BigNumber(300000),
262
- } as Transaction;
279
+ });
263
280
 
264
281
  const status = createMockStatus(new BigNumber(100000));
265
282
 
@@ -292,13 +309,12 @@ describe("getDeviceTransactionConfig", () => {
292
309
  });
293
310
 
294
311
  it("should not include memo if not provided", async () => {
295
- const transaction = {
296
- family: "hedera",
312
+ const transaction = getMockedTransaction({
297
313
  mode: HEDERA_TRANSACTION_MODES.Send,
298
314
  amount: new BigNumber(1000000),
299
315
  recipient: "0.0.12345",
300
316
  useAllAmount: false,
301
- } as Transaction;
317
+ });
302
318
 
303
319
  const status = createMockStatus(new BigNumber(100000));
304
320
 
@@ -1,6 +1,6 @@
1
1
  import type { CommonDeviceTransactionField as DeviceTransactionField } from "@ledgerhq/coin-framework/transaction/common";
2
2
  import type { AccountLike, Account } from "@ledgerhq/types-live";
3
- import { HEDERA_TRANSACTION_MODES } from "./constants";
3
+ import { HEDERA_TRANSACTION_MODES, MAP_STAKING_MODE_TO_METHOD } from "./constants";
4
4
  import { isTokenAssociateTransaction, isStakingTransaction } from "./logic/utils";
5
5
  import type { Transaction, TransactionStatus } from "./types";
6
6
 
@@ -19,10 +19,7 @@ async function getDeviceTransactionConfig({
19
19
  fields.push({
20
20
  type: "text",
21
21
  label: "Method",
22
- value:
23
- transaction.mode === HEDERA_TRANSACTION_MODES.ClaimRewards
24
- ? "Claim Rewards"
25
- : "Update Account",
22
+ value: MAP_STAKING_MODE_TO_METHOD[transaction.mode],
26
23
  });
27
24
 
28
25
  if (!estimatedFees.isZero()) {