@ledgerhq/coin-hedera 1.15.0-nightly.20251209144712 → 1.15.1
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.
- package/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +48 -14
- package/lib/bridge/buildOptimisticOperation.d.ts.map +1 -1
- package/lib/bridge/buildOptimisticOperation.js +0 -33
- package/lib/bridge/buildOptimisticOperation.js.map +1 -1
- package/lib/bridge/getTransactionStatus.d.ts.map +1 -1
- package/lib/bridge/getTransactionStatus.js +0 -54
- package/lib/bridge/getTransactionStatus.js.map +1 -1
- package/lib/bridge/index.d.ts.map +1 -1
- package/lib/bridge/index.js +2 -4
- package/lib/bridge/index.js.map +1 -1
- package/lib/bridge/prepareTransaction.d.ts.map +1 -1
- package/lib/bridge/prepareTransaction.js +0 -16
- package/lib/bridge/prepareTransaction.js.map +1 -1
- package/lib/bridge/serialization.d.ts.map +1 -1
- package/lib/bridge/serialization.js +0 -20
- package/lib/bridge/serialization.js.map +1 -1
- package/lib/bridge/signOperation.d.ts +4 -4
- package/lib/bridge/signOperation.d.ts.map +1 -1
- package/lib/bridge/signOperation.js +0 -10
- package/lib/bridge/signOperation.js.map +1 -1
- package/lib/bridge/synchronisation.d.ts.map +1 -1
- package/lib/bridge/synchronisation.js +0 -8
- package/lib/bridge/synchronisation.js.map +1 -1
- package/lib/constants.d.ts +1 -21
- package/lib/constants.d.ts.map +1 -1
- package/lib/constants.js +1 -22
- package/lib/constants.js.map +1 -1
- package/lib/deviceTransactionConfig.d.ts.map +1 -1
- package/lib/deviceTransactionConfig.js +0 -30
- package/lib/deviceTransactionConfig.js.map +1 -1
- package/lib/errors.d.ts +0 -9
- package/lib/errors.d.ts.map +1 -1
- package/lib/errors.js +1 -4
- package/lib/errors.js.map +1 -1
- package/lib/logic/craftTransaction.d.ts +2 -2
- package/lib/logic/craftTransaction.d.ts.map +1 -1
- package/lib/logic/craftTransaction.js +8 -42
- package/lib/logic/craftTransaction.js.map +1 -1
- package/lib/logic/getBlock.d.ts.map +1 -1
- package/lib/logic/getBlock.js +0 -1
- package/lib/logic/getBlock.js.map +1 -1
- package/lib/logic/listOperations.d.ts.map +1 -1
- package/lib/logic/listOperations.js +7 -39
- package/lib/logic/listOperations.js.map +1 -1
- package/lib/logic/utils.d.ts +3 -61
- package/lib/logic/utils.d.ts.map +1 -1
- package/lib/logic/utils.js +4 -117
- package/lib/logic/utils.js.map +1 -1
- package/lib/network/api.d.ts +1 -3
- package/lib/network/api.d.ts.map +1 -1
- package/lib/network/api.js +0 -19
- package/lib/network/api.js.map +1 -1
- package/lib/test/fixtures/account.fixture.d.ts +1 -1
- package/lib/test/fixtures/account.fixture.d.ts.map +1 -1
- package/lib/test/fixtures/account.fixture.js +0 -2
- package/lib/test/fixtures/account.fixture.js.map +1 -1
- package/lib/transaction.d.ts.map +1 -1
- package/lib/transaction.js +0 -34
- package/lib/transaction.js.map +1 -1
- package/lib/types/alpaca.d.ts +0 -3
- package/lib/types/alpaca.d.ts.map +1 -1
- package/lib/types/bridge.d.ts +3 -87
- package/lib/types/bridge.d.ts.map +1 -1
- package/lib/types/logic.d.ts +1 -5
- package/lib/types/logic.d.ts.map +1 -1
- package/lib/types/mirror.d.ts +0 -19
- package/lib/types/mirror.d.ts.map +1 -1
- package/lib-es/bridge/buildOptimisticOperation.d.ts.map +1 -1
- package/lib-es/bridge/buildOptimisticOperation.js +1 -34
- package/lib-es/bridge/buildOptimisticOperation.js.map +1 -1
- package/lib-es/bridge/getTransactionStatus.d.ts.map +1 -1
- package/lib-es/bridge/getTransactionStatus.js +3 -57
- package/lib-es/bridge/getTransactionStatus.js.map +1 -1
- package/lib-es/bridge/index.d.ts.map +1 -1
- package/lib-es/bridge/index.js +2 -4
- package/lib-es/bridge/index.js.map +1 -1
- package/lib-es/bridge/prepareTransaction.d.ts.map +1 -1
- package/lib-es/bridge/prepareTransaction.js +2 -15
- package/lib-es/bridge/prepareTransaction.js.map +1 -1
- package/lib-es/bridge/serialization.d.ts.map +1 -1
- package/lib-es/bridge/serialization.js +0 -17
- package/lib-es/bridge/serialization.js.map +1 -1
- package/lib-es/bridge/signOperation.d.ts +4 -4
- package/lib-es/bridge/signOperation.d.ts.map +1 -1
- package/lib-es/bridge/signOperation.js +1 -11
- package/lib-es/bridge/signOperation.js.map +1 -1
- package/lib-es/bridge/synchronisation.d.ts.map +1 -1
- package/lib-es/bridge/synchronisation.js +0 -8
- package/lib-es/bridge/synchronisation.js.map +1 -1
- package/lib-es/constants.d.ts +1 -21
- package/lib-es/constants.d.ts.map +1 -1
- package/lib-es/constants.js +0 -21
- package/lib-es/constants.js.map +1 -1
- package/lib-es/deviceTransactionConfig.d.ts.map +1 -1
- package/lib-es/deviceTransactionConfig.js +1 -31
- package/lib-es/deviceTransactionConfig.js.map +1 -1
- package/lib-es/errors.d.ts +0 -9
- package/lib-es/errors.d.ts.map +1 -1
- package/lib-es/errors.js +0 -3
- package/lib-es/errors.js.map +1 -1
- package/lib-es/logic/craftTransaction.d.ts +2 -2
- package/lib-es/logic/craftTransaction.d.ts.map +1 -1
- package/lib-es/logic/craftTransaction.js +10 -44
- package/lib-es/logic/craftTransaction.js.map +1 -1
- package/lib-es/logic/getBlock.d.ts.map +1 -1
- package/lib-es/logic/getBlock.js +1 -2
- package/lib-es/logic/getBlock.js.map +1 -1
- package/lib-es/logic/listOperations.d.ts.map +1 -1
- package/lib-es/logic/listOperations.js +7 -39
- package/lib-es/logic/listOperations.js.map +1 -1
- package/lib-es/logic/utils.d.ts +3 -61
- package/lib-es/logic/utils.d.ts.map +1 -1
- package/lib-es/logic/utils.js +4 -107
- package/lib-es/logic/utils.js.map +1 -1
- package/lib-es/network/api.d.ts +1 -3
- package/lib-es/network/api.d.ts.map +1 -1
- package/lib-es/network/api.js +0 -19
- package/lib-es/network/api.js.map +1 -1
- package/lib-es/test/fixtures/account.fixture.d.ts +1 -1
- package/lib-es/test/fixtures/account.fixture.d.ts.map +1 -1
- package/lib-es/test/fixtures/account.fixture.js +0 -2
- package/lib-es/test/fixtures/account.fixture.js.map +1 -1
- package/lib-es/transaction.d.ts.map +1 -1
- package/lib-es/transaction.js +0 -34
- package/lib-es/transaction.js.map +1 -1
- package/lib-es/types/alpaca.d.ts +0 -3
- package/lib-es/types/alpaca.d.ts.map +1 -1
- package/lib-es/types/bridge.d.ts +3 -87
- package/lib-es/types/bridge.d.ts.map +1 -1
- package/lib-es/types/logic.d.ts +1 -5
- package/lib-es/types/logic.d.ts.map +1 -1
- package/lib-es/types/mirror.d.ts +0 -19
- package/lib-es/types/mirror.d.ts.map +1 -1
- package/package.json +11 -12
- package/src/api/index.integ.test.ts +1 -11
- package/src/bridge/buildOptimisticOperation.integration.test.ts +4 -159
- package/src/bridge/buildOptimisticOperation.ts +2 -50
- package/src/bridge/getTransactionStatus.test.ts +21 -191
- package/src/bridge/getTransactionStatus.ts +1 -75
- package/src/bridge/index.ts +2 -4
- package/src/bridge/prepareTransaction.test.ts +8 -112
- package/src/bridge/prepareTransaction.ts +2 -20
- package/src/bridge/serialization.ts +0 -17
- package/src/bridge/signOperation.ts +5 -15
- package/src/bridge/synchronisation.ts +0 -9
- package/src/bridge/utils.integration.test.ts +10 -3
- package/src/constants.ts +0 -22
- package/src/deviceTransactionConfig.ts +1 -37
- package/src/errors.ts +0 -7
- package/src/logic/craftTransaction.ts +13 -70
- package/src/logic/getBalance.test.ts +16 -15
- package/src/logic/getBlock.ts +1 -2
- package/src/logic/listOperations.test.ts +29 -86
- package/src/logic/listOperations.ts +6 -46
- package/src/logic/utils.test.ts +8 -362
- package/src/logic/utils.ts +4 -158
- package/src/network/api.test.ts +6 -58
- package/src/network/api.ts +0 -25
- package/src/network/thirdweb.test.ts +2 -2
- package/src/network/utils.test.ts +6 -4
- package/src/test/fixtures/account.fixture.ts +1 -3
- package/src/transaction.ts +0 -42
- package/src/types/alpaca.ts +0 -4
- package/src/types/bridge.ts +3 -108
- package/src/types/logic.ts +1 -6
- package/src/types/mirror.ts +0 -21
- package/lib/preload-data.d.ts +0 -7
- package/lib/preload-data.d.ts.map +0 -1
- package/lib/preload-data.js +0 -37
- package/lib/preload-data.js.map +0 -1
- package/lib/preload.d.ts +0 -8
- package/lib/preload.d.ts.map +0 -1
- package/lib/preload.js +0 -76
- package/lib/preload.js.map +0 -1
- package/lib-es/preload-data.d.ts +0 -7
- package/lib-es/preload-data.d.ts.map +0 -1
- package/lib-es/preload-data.js +0 -31
- package/lib-es/preload-data.js.map +0 -1
- package/lib-es/preload.d.ts +0 -8
- package/lib-es/preload.d.ts.map +0 -1
- package/lib-es/preload.js +0 -67
- package/lib-es/preload.js.map +0 -1
- package/src/deviceTransactionConfig.test.ts +0 -315
- package/src/preload-data.ts +0 -38
- package/src/preload.test.ts +0 -64
- package/src/preload.ts +0 -80
package/src/logic/utils.test.ts
CHANGED
|
@@ -1,33 +1,19 @@
|
|
|
1
1
|
import BigNumber from "bignumber.js";
|
|
2
2
|
import { createHash } from "crypto";
|
|
3
|
-
import { Transaction
|
|
4
|
-
import type { AssetInfo
|
|
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 {
|
|
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(
|
|
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
|
|
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
|
-
(
|
|
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(
|
|
131
|
-
expect(
|
|
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
|
});
|
package/src/logic/utils.ts
CHANGED
|
@@ -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
|
|
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 =
|
|
223
|
+
const checksum = EntityIdHelper.fromString(address).checksum ?? null;
|
|
287
224
|
|
|
288
225
|
if (checksum) {
|
|
289
226
|
const client = rpcClient.getInstance();
|
|
@@ -300,7 +237,7 @@ export const safeParseAccountId = (
|
|
|
300
237
|
};
|
|
301
238
|
|
|
302
239
|
return [null, result];
|
|
303
|
-
} catch {
|
|
240
|
+
} catch (err) {
|
|
304
241
|
return [new InvalidAddress("", { currencyName }), null];
|
|
305
242
|
}
|
|
306
243
|
};
|
|
@@ -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
|
-
};
|