@ledgerhq/live-common 34.43.0-nightly.3 → 34.44.0-nightly.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/DataModel.test.js +6 -0
- package/lib/DataModel.test.js.map +1 -1
- package/lib/__fixtures__/solana-spl-epjfwdd5aufqssqem2qn1xzybapc8g4weggkzwytdt1v.json +53 -0
- package/lib/__tests__/accounts/groupPerDay.js +10 -0
- package/lib/__tests__/accounts/groupPerDay.js.map +1 -1
- package/lib/__tests__/test-helpers/setup.d.ts.map +1 -1
- package/lib/__tests__/test-helpers/setup.js +6 -0
- package/lib/__tests__/test-helpers/setup.js.map +1 -1
- package/lib/account/serialization.test.js +17 -1
- package/lib/account/serialization.test.js.map +1 -1
- package/lib/bridge/crypto-assets/index.d.ts.map +1 -1
- package/lib/bridge/crypto-assets/index.js +5 -5
- package/lib/bridge/crypto-assets/index.js.map +1 -1
- package/lib/bridge/generic-alpaca/getAccountShape.d.ts.map +1 -1
- package/lib/bridge/generic-alpaca/getAccountShape.js +5 -6
- package/lib/bridge/generic-alpaca/getAccountShape.js.map +1 -1
- package/lib/bridge/generic-alpaca/utils.d.ts +2 -1
- package/lib/bridge/generic-alpaca/utils.d.ts.map +1 -1
- package/lib/bridge/generic-alpaca/utils.js +5 -1
- package/lib/bridge/generic-alpaca/utils.js.map +1 -1
- package/lib/bridge/generic-alpaca/utils.test.d.ts +2 -0
- package/lib/bridge/generic-alpaca/utils.test.d.ts.map +1 -0
- package/lib/bridge/generic-alpaca/utils.test.js +20 -0
- package/lib/bridge/generic-alpaca/utils.test.js.map +1 -0
- package/lib/currencies/sortByMarketcap.test.js +5 -0
- package/lib/currencies/sortByMarketcap.test.js.map +1 -1
- package/lib/deviceSDK/hooks/__tests__/filterIgnoredFirmwareUpdates.test.d.ts +2 -0
- package/lib/deviceSDK/hooks/__tests__/filterIgnoredFirmwareUpdates.test.d.ts.map +1 -0
- package/lib/deviceSDK/hooks/__tests__/filterIgnoredFirmwareUpdates.test.js +114 -0
- package/lib/deviceSDK/hooks/__tests__/filterIgnoredFirmwareUpdates.test.js.map +1 -0
- package/lib/deviceSDK/hooks/filterIgnoredFirmwareUpdates.d.ts +11 -0
- package/lib/deviceSDK/hooks/filterIgnoredFirmwareUpdates.d.ts.map +1 -0
- package/lib/deviceSDK/hooks/filterIgnoredFirmwareUpdates.js +26 -0
- package/lib/deviceSDK/hooks/filterIgnoredFirmwareUpdates.js.map +1 -0
- package/lib/deviceSDK/hooks/getIgnoredOSUpdatesForDeviceModelAndPlatform.d.ts +12 -0
- package/lib/deviceSDK/hooks/getIgnoredOSUpdatesForDeviceModelAndPlatform.d.ts.map +1 -0
- package/lib/deviceSDK/hooks/getIgnoredOSUpdatesForDeviceModelAndPlatform.js +24 -0
- package/lib/deviceSDK/hooks/getIgnoredOSUpdatesForDeviceModelAndPlatform.js.map +1 -0
- package/lib/deviceSDK/hooks/getIgnoredOSUpdatesForDeviceModelAndPlatform.test.d.ts +2 -0
- package/lib/deviceSDK/hooks/getIgnoredOSUpdatesForDeviceModelAndPlatform.test.d.ts.map +1 -0
- package/lib/deviceSDK/hooks/getIgnoredOSUpdatesForDeviceModelAndPlatform.test.js +118 -0
- package/lib/deviceSDK/hooks/getIgnoredOSUpdatesForDeviceModelAndPlatform.test.js.map +1 -0
- package/lib/deviceSDK/hooks/useGetLatestAvailableFirmware.d.ts +3 -1
- package/lib/deviceSDK/hooks/useGetLatestAvailableFirmware.d.ts.map +1 -1
- package/lib/deviceSDK/hooks/useGetLatestAvailableFirmware.js +7 -3
- package/lib/deviceSDK/hooks/useGetLatestAvailableFirmware.js.map +1 -1
- package/lib/e2e/index.d.ts +2 -0
- package/lib/e2e/index.d.ts.map +1 -1
- package/lib/families/bitcoin/satstack.test.js +6 -0
- package/lib/families/bitcoin/satstack.test.js.map +1 -1
- package/lib/families/stellar/ui.d.ts +6 -0
- package/lib/families/stellar/ui.d.ts.map +1 -0
- package/lib/families/stellar/ui.js +18 -0
- package/lib/families/stellar/ui.js.map +1 -0
- package/lib/families/tron/data.mock.d.ts.map +1 -1
- package/lib/families/tron/data.mock.js +6 -0
- package/lib/families/tron/data.mock.js.map +1 -1
- package/lib/featureFlags/defaultFeatures.d.ts.map +1 -1
- package/lib/featureFlags/defaultFeatures.js +4 -0
- package/lib/featureFlags/defaultFeatures.js.map +1 -1
- package/lib/featureFlags/useFeature.d.ts +1 -1
- package/lib/featureFlags/useFeature.d.ts.map +1 -1
- package/lib-es/DataModel.test.js +6 -0
- package/lib-es/DataModel.test.js.map +1 -1
- package/lib-es/__fixtures__/solana-spl-epjfwdd5aufqssqem2qn1xzybapc8g4weggkzwytdt1v.json +53 -0
- package/lib-es/__tests__/accounts/groupPerDay.js +10 -0
- package/lib-es/__tests__/accounts/groupPerDay.js.map +1 -1
- package/lib-es/__tests__/test-helpers/setup.d.ts.map +1 -1
- package/lib-es/__tests__/test-helpers/setup.js +6 -0
- package/lib-es/__tests__/test-helpers/setup.js.map +1 -1
- package/lib-es/account/serialization.test.js +15 -2
- package/lib-es/account/serialization.test.js.map +1 -1
- package/lib-es/bridge/crypto-assets/index.d.ts.map +1 -1
- package/lib-es/bridge/crypto-assets/index.js +4 -4
- package/lib-es/bridge/crypto-assets/index.js.map +1 -1
- package/lib-es/bridge/generic-alpaca/getAccountShape.d.ts.map +1 -1
- package/lib-es/bridge/generic-alpaca/getAccountShape.js +6 -7
- package/lib-es/bridge/generic-alpaca/getAccountShape.js.map +1 -1
- package/lib-es/bridge/generic-alpaca/utils.d.ts +2 -1
- package/lib-es/bridge/generic-alpaca/utils.d.ts.map +1 -1
- package/lib-es/bridge/generic-alpaca/utils.js +3 -0
- package/lib-es/bridge/generic-alpaca/utils.js.map +1 -1
- package/lib-es/bridge/generic-alpaca/utils.test.d.ts +2 -0
- package/lib-es/bridge/generic-alpaca/utils.test.d.ts.map +1 -0
- package/lib-es/bridge/generic-alpaca/utils.test.js +18 -0
- package/lib-es/bridge/generic-alpaca/utils.test.js.map +1 -0
- package/lib-es/currencies/sortByMarketcap.test.js +5 -0
- package/lib-es/currencies/sortByMarketcap.test.js.map +1 -1
- package/lib-es/deviceSDK/hooks/__tests__/filterIgnoredFirmwareUpdates.test.d.ts +2 -0
- package/lib-es/deviceSDK/hooks/__tests__/filterIgnoredFirmwareUpdates.test.d.ts.map +1 -0
- package/lib-es/deviceSDK/hooks/__tests__/filterIgnoredFirmwareUpdates.test.js +112 -0
- package/lib-es/deviceSDK/hooks/__tests__/filterIgnoredFirmwareUpdates.test.js.map +1 -0
- package/lib-es/deviceSDK/hooks/filterIgnoredFirmwareUpdates.d.ts +11 -0
- package/lib-es/deviceSDK/hooks/filterIgnoredFirmwareUpdates.d.ts.map +1 -0
- package/lib-es/deviceSDK/hooks/filterIgnoredFirmwareUpdates.js +22 -0
- package/lib-es/deviceSDK/hooks/filterIgnoredFirmwareUpdates.js.map +1 -0
- package/lib-es/deviceSDK/hooks/getIgnoredOSUpdatesForDeviceModelAndPlatform.d.ts +12 -0
- package/lib-es/deviceSDK/hooks/getIgnoredOSUpdatesForDeviceModelAndPlatform.d.ts.map +1 -0
- package/lib-es/deviceSDK/hooks/getIgnoredOSUpdatesForDeviceModelAndPlatform.js +20 -0
- package/lib-es/deviceSDK/hooks/getIgnoredOSUpdatesForDeviceModelAndPlatform.js.map +1 -0
- package/lib-es/deviceSDK/hooks/getIgnoredOSUpdatesForDeviceModelAndPlatform.test.d.ts +2 -0
- package/lib-es/deviceSDK/hooks/getIgnoredOSUpdatesForDeviceModelAndPlatform.test.d.ts.map +1 -0
- package/lib-es/deviceSDK/hooks/getIgnoredOSUpdatesForDeviceModelAndPlatform.test.js +116 -0
- package/lib-es/deviceSDK/hooks/getIgnoredOSUpdatesForDeviceModelAndPlatform.test.js.map +1 -0
- package/lib-es/deviceSDK/hooks/useGetLatestAvailableFirmware.d.ts +3 -1
- package/lib-es/deviceSDK/hooks/useGetLatestAvailableFirmware.d.ts.map +1 -1
- package/lib-es/deviceSDK/hooks/useGetLatestAvailableFirmware.js +7 -3
- package/lib-es/deviceSDK/hooks/useGetLatestAvailableFirmware.js.map +1 -1
- package/lib-es/e2e/index.d.ts +2 -0
- package/lib-es/e2e/index.d.ts.map +1 -1
- package/lib-es/families/bitcoin/satstack.test.js +6 -0
- package/lib-es/families/bitcoin/satstack.test.js.map +1 -1
- package/lib-es/families/stellar/ui.d.ts +6 -0
- package/lib-es/families/stellar/ui.d.ts.map +1 -0
- package/lib-es/families/stellar/ui.js +14 -0
- package/lib-es/families/stellar/ui.js.map +1 -0
- package/lib-es/families/tron/data.mock.d.ts.map +1 -1
- package/lib-es/families/tron/data.mock.js +6 -0
- package/lib-es/families/tron/data.mock.js.map +1 -1
- package/lib-es/featureFlags/defaultFeatures.d.ts.map +1 -1
- package/lib-es/featureFlags/defaultFeatures.js +4 -0
- package/lib-es/featureFlags/defaultFeatures.js.map +1 -1
- package/lib-es/featureFlags/useFeature.d.ts +1 -1
- package/lib-es/featureFlags/useFeature.d.ts.map +1 -1
- package/package.json +42 -42
- package/src/DataModel.test.ts +8 -0
- package/src/__fixtures__/solana-spl-epjfwdd5aufqssqem2qn1xzybapc8g4weggkzwytdt1v.json +53 -0
- package/src/__tests__/accounts/groupPerDay.ts +13 -0
- package/src/__tests__/test-helpers/setup.ts +8 -0
- package/src/account/serialization.test.ts +20 -2
- package/src/bridge/crypto-assets/index.ts +6 -6
- package/src/bridge/generic-alpaca/getAccountShape.ts +6 -7
- package/src/bridge/generic-alpaca/utils.test.ts +19 -0
- package/src/bridge/generic-alpaca/utils.ts +9 -1
- package/src/currencies/sortByMarketcap.test.ts +7 -0
- package/src/deviceSDK/hooks/__tests__/filterIgnoredFirmwareUpdates.test.ts +132 -0
- package/src/deviceSDK/hooks/filterIgnoredFirmwareUpdates.ts +27 -0
- package/src/deviceSDK/hooks/getIgnoredOSUpdatesForDeviceModelAndPlatform.test.ts +192 -0
- package/src/deviceSDK/hooks/getIgnoredOSUpdatesForDeviceModelAndPlatform.ts +28 -0
- package/src/deviceSDK/hooks/useGetLatestAvailableFirmware.ts +9 -2
- package/src/families/bitcoin/satstack.test.ts +7 -0
- package/src/families/stellar/__snapshots__/bridge.integration.test.ts.snap +1930 -94
- package/src/families/stellar/ui.ts +15 -0
- package/src/families/tron/data.mock.ts +8 -0
- package/src/featureFlags/defaultFeatures.ts +4 -0
@@ -2,12 +2,6 @@ import { LiveConfig } from "@ledgerhq/live-config/LiveConfig";
|
|
2
2
|
import { CryptoAssetsStore } from "@ledgerhq/coin-framework/crypto-assets/type";
|
3
3
|
import * as legacy from "@ledgerhq/cryptoassets/tokens";
|
4
4
|
|
5
|
-
let cryptoAssetsStore: CryptoAssetsStore | undefined = undefined;
|
6
|
-
|
7
|
-
export function setCryptoAssetsStore(store: CryptoAssetsStore) {
|
8
|
-
cryptoAssetsStore = store;
|
9
|
-
}
|
10
|
-
|
11
5
|
const legacyStore: CryptoAssetsStore = {
|
12
6
|
findTokenByAddress: legacy.findTokenByAddress,
|
13
7
|
getTokenById: legacy.getTokenById,
|
@@ -16,6 +10,12 @@ const legacyStore: CryptoAssetsStore = {
|
|
16
10
|
findTokenByTicker: legacy.findTokenByTicker,
|
17
11
|
};
|
18
12
|
|
13
|
+
let cryptoAssetsStore: CryptoAssetsStore | undefined = undefined;
|
14
|
+
|
15
|
+
export function setCryptoAssetsStore(store: CryptoAssetsStore) {
|
16
|
+
cryptoAssetsStore = store;
|
17
|
+
}
|
18
|
+
|
19
19
|
export function getCryptoAssetsStore(): CryptoAssetsStore {
|
20
20
|
const featureEnabled = LiveConfig.getValueByKey("feature_cal_lazy_loading");
|
21
21
|
if (!featureEnabled) {
|
@@ -2,7 +2,7 @@ import { encodeAccountId } from "@ledgerhq/coin-framework/account/index";
|
|
2
2
|
import { GetAccountShape, mergeOps } from "@ledgerhq/coin-framework/bridge/jsHelpers";
|
3
3
|
import BigNumber from "bignumber.js";
|
4
4
|
import { getAlpacaApi } from "./alpaca";
|
5
|
-
import { adaptCoreOperationToLiveOperation } from "./utils";
|
5
|
+
import { adaptCoreOperationToLiveOperation, extractBalance } from "./utils";
|
6
6
|
|
7
7
|
export function genericGetAccountShape(network: string, kind: "local" | "remote"): GetAccountShape {
|
8
8
|
return async info => {
|
@@ -18,15 +18,14 @@ export function genericGetAccountShape(network: string, kind: "local" | "remote"
|
|
18
18
|
|
19
19
|
const blockInfo = await getAlpacaApi(network, kind).lastBlock();
|
20
20
|
|
21
|
-
const
|
22
|
-
|
23
|
-
|
24
|
-
const balance = BigNumber(balanceRes[0].value.toString());
|
21
|
+
const balances = await getAlpacaApi(network, kind).getBalance(address);
|
22
|
+
const nativeBalance = extractBalance(balances, "native");
|
23
|
+
const balance = BigNumber(nativeBalance.value.toString());
|
25
24
|
|
26
25
|
let spendableBalance: BigNumber;
|
27
|
-
if (
|
26
|
+
if (nativeBalance.locked) {
|
28
27
|
spendableBalance = BigNumber.max(
|
29
|
-
balance.minus(BigNumber(
|
28
|
+
balance.minus(BigNumber(nativeBalance.locked.toString())),
|
30
29
|
BigNumber(0),
|
31
30
|
);
|
32
31
|
} else {
|
@@ -0,0 +1,19 @@
|
|
1
|
+
import { extractBalance } from "./utils";
|
2
|
+
|
3
|
+
describe("Alpaca utils", () => {
|
4
|
+
describe("extractBalance", () => {
|
5
|
+
it("extracts an existing balance", () => {
|
6
|
+
expect(extractBalance([{ value: 4n, asset: { type: "type1" } }], "type1")).toEqual({
|
7
|
+
value: 4n,
|
8
|
+
asset: { type: "type1" },
|
9
|
+
});
|
10
|
+
});
|
11
|
+
|
12
|
+
it("generates an empty balance for a missing type", () => {
|
13
|
+
expect(extractBalance([{ value: 4n, asset: { type: "type1" } }], "type2")).toEqual({
|
14
|
+
value: 0n,
|
15
|
+
asset: { type: "type2" },
|
16
|
+
});
|
17
|
+
});
|
18
|
+
});
|
19
|
+
});
|
@@ -1,9 +1,17 @@
|
|
1
1
|
import { encodeOperationId } from "@ledgerhq/coin-framework/operation";
|
2
2
|
import { Account, Operation, OperationType, TransactionCommon } from "@ledgerhq/types-live";
|
3
|
-
import {
|
3
|
+
import {
|
4
|
+
Balance,
|
5
|
+
Operation as CoreOperation,
|
6
|
+
TransactionIntent,
|
7
|
+
} from "@ledgerhq/coin-framework/api/types";
|
4
8
|
import BigNumber from "bignumber.js";
|
5
9
|
import { fromBigNumberToBigInt } from "@ledgerhq/coin-framework/utils";
|
6
10
|
|
11
|
+
export function extractBalance(balances: Balance[], type: string): Balance {
|
12
|
+
return balances.find(balance => balance.asset.type === type) ?? { asset: { type }, value: 0n };
|
13
|
+
}
|
14
|
+
|
7
15
|
export function adaptCoreOperationToLiveOperation(accountId: string, op: CoreOperation): Operation {
|
8
16
|
return {
|
9
17
|
id: encodeOperationId(accountId, op.tx.hash, op.type),
|
@@ -2,6 +2,13 @@ import { sortCurrenciesByIds } from "./sortByMarketcap";
|
|
2
2
|
import { findCurrencyByTicker, listCryptoCurrencies, listTokens } from ".";
|
3
3
|
import { getBTCValues } from "@ledgerhq/live-countervalues/mock";
|
4
4
|
import { CURRENCIES_LIST, IDS } from "./mock";
|
5
|
+
import { setCryptoAssetsStore as setCryptoAssetsStoreForCoinFramework } from "@ledgerhq/coin-framework/crypto-assets/index";
|
6
|
+
import { CryptoAssetsStore } from "@ledgerhq/coin-framework/crypto-assets/type";
|
7
|
+
|
8
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
9
|
+
setCryptoAssetsStoreForCoinFramework({
|
10
|
+
findTokenByTicker: (_: string) => undefined,
|
11
|
+
} as CryptoAssetsStore);
|
5
12
|
|
6
13
|
test("sortCurrenciesByIds snapshot", () => {
|
7
14
|
const list = [...listCryptoCurrencies(), ...listTokens()];
|
@@ -0,0 +1,132 @@
|
|
1
|
+
import { filterIgnoredFirmwareUpdates } from "../filterIgnoredFirmwareUpdates";
|
2
|
+
import type { GetLatestAvailableFirmwareActionState } from "../../actions/getLatestAvailableFirmware";
|
3
|
+
|
4
|
+
describe("filterIgnoredFirmwareUpdates", () => {
|
5
|
+
const createMockState = (
|
6
|
+
status: GetLatestAvailableFirmwareActionState["status"],
|
7
|
+
firmwareName?: string,
|
8
|
+
): GetLatestAvailableFirmwareActionState => ({
|
9
|
+
status,
|
10
|
+
firmwareUpdateContext: firmwareName
|
11
|
+
? {
|
12
|
+
final: { name: firmwareName } as any,
|
13
|
+
osu: {} as any,
|
14
|
+
shouldFlashMCU: false,
|
15
|
+
}
|
16
|
+
: null,
|
17
|
+
deviceInfo: null,
|
18
|
+
error: null,
|
19
|
+
lockedDevice: false,
|
20
|
+
});
|
21
|
+
|
22
|
+
describe("when status is not 'available-firmware'", () => {
|
23
|
+
it("should return the original state unchanged", () => {
|
24
|
+
const state = createMockState("no-available-firmware");
|
25
|
+
const result = filterIgnoredFirmwareUpdates(state, ["2.1.0"]);
|
26
|
+
expect(result).toEqual(state);
|
27
|
+
});
|
28
|
+
|
29
|
+
it("should return the original state when status is 'error'", () => {
|
30
|
+
const state = createMockState("error");
|
31
|
+
const result = filterIgnoredFirmwareUpdates(state, ["2.1.0"]);
|
32
|
+
expect(result).toEqual(state);
|
33
|
+
});
|
34
|
+
});
|
35
|
+
|
36
|
+
describe("when ignoredOSUpdates is undefined", () => {
|
37
|
+
it("should return the original state unchanged", () => {
|
38
|
+
const state = createMockState("available-firmware", "2.1.0");
|
39
|
+
const result = filterIgnoredFirmwareUpdates(state, undefined);
|
40
|
+
expect(result).toEqual(state);
|
41
|
+
});
|
42
|
+
});
|
43
|
+
|
44
|
+
describe("when ignoredOSUpdates is empty array", () => {
|
45
|
+
it("should return the original state unchanged", () => {
|
46
|
+
const state = createMockState("available-firmware", "2.1.0");
|
47
|
+
const result = filterIgnoredFirmwareUpdates(state, []);
|
48
|
+
expect(result).toEqual(state);
|
49
|
+
});
|
50
|
+
});
|
51
|
+
|
52
|
+
describe("when firmwareUpdateContext is null", () => {
|
53
|
+
it("should return the original state unchanged", () => {
|
54
|
+
const state = createMockState("available-firmware");
|
55
|
+
const result = filterIgnoredFirmwareUpdates(state, ["2.1.0"]);
|
56
|
+
expect(result).toEqual(state);
|
57
|
+
});
|
58
|
+
});
|
59
|
+
|
60
|
+
describe("when firmwareUpdateContext.final.name is undefined", () => {
|
61
|
+
it("should return the original state unchanged", () => {
|
62
|
+
const state = createMockState("available-firmware", "2.1.0");
|
63
|
+
state.firmwareUpdateContext!.final.name = undefined as any;
|
64
|
+
const result = filterIgnoredFirmwareUpdates(state, ["2.1.0"]);
|
65
|
+
expect(result).toEqual(state);
|
66
|
+
});
|
67
|
+
});
|
68
|
+
|
69
|
+
describe("when firmware version is not in ignored list", () => {
|
70
|
+
it("should return the original state unchanged", () => {
|
71
|
+
const state = createMockState("available-firmware", "2.1.0");
|
72
|
+
const result = filterIgnoredFirmwareUpdates(state, ["2.0.0", "2.2.0"]);
|
73
|
+
expect(result).toEqual(state);
|
74
|
+
});
|
75
|
+
});
|
76
|
+
|
77
|
+
describe("when firmware version is in ignored list", () => {
|
78
|
+
it("should filter out the firmware and change status to 'no-available-firmware'", () => {
|
79
|
+
const state = createMockState("available-firmware", "2.1.0");
|
80
|
+
const result = filterIgnoredFirmwareUpdates(state, ["2.1.0", "2.2.0"]);
|
81
|
+
|
82
|
+
expect(result).toEqual({
|
83
|
+
...state,
|
84
|
+
firmwareUpdateContext: null,
|
85
|
+
status: "no-available-firmware",
|
86
|
+
});
|
87
|
+
});
|
88
|
+
|
89
|
+
it("should filter out the firmware when it's the only ignored version", () => {
|
90
|
+
const state = createMockState("available-firmware", "2.1.0");
|
91
|
+
const result = filterIgnoredFirmwareUpdates(state, ["2.1.0"]);
|
92
|
+
|
93
|
+
expect(result).toEqual({
|
94
|
+
...state,
|
95
|
+
firmwareUpdateContext: null,
|
96
|
+
status: "no-available-firmware",
|
97
|
+
});
|
98
|
+
});
|
99
|
+
});
|
100
|
+
|
101
|
+
describe("edge cases", () => {
|
102
|
+
it("should handle case-sensitive firmware version matching", () => {
|
103
|
+
const state = createMockState("available-firmware", "2.1.0");
|
104
|
+
const result = filterIgnoredFirmwareUpdates(state, ["2.1.0", "2.1.0-rc1"]);
|
105
|
+
expect(result).toEqual({
|
106
|
+
...state,
|
107
|
+
firmwareUpdateContext: null,
|
108
|
+
status: "no-available-firmware",
|
109
|
+
});
|
110
|
+
});
|
111
|
+
|
112
|
+
it("should not filter when firmware version is similar but not exact match", () => {
|
113
|
+
const state = createMockState("available-firmware", "2.1.0");
|
114
|
+
const result = filterIgnoredFirmwareUpdates(state, ["2.1.0-rc1", "2.1.1"]);
|
115
|
+
expect(result).toEqual(state);
|
116
|
+
});
|
117
|
+
|
118
|
+
it("should preserve all other state properties when filtering", () => {
|
119
|
+
const state = createMockState("available-firmware", "2.1.0");
|
120
|
+
state.lockedDevice = true;
|
121
|
+
state.error = { type: "SharedError", message: "Test", name: "TestError", retrying: false };
|
122
|
+
|
123
|
+
const result = filterIgnoredFirmwareUpdates(state, ["2.1.0"]);
|
124
|
+
|
125
|
+
expect(result).toEqual({
|
126
|
+
...state,
|
127
|
+
firmwareUpdateContext: null,
|
128
|
+
status: "no-available-firmware",
|
129
|
+
});
|
130
|
+
});
|
131
|
+
});
|
132
|
+
});
|
@@ -0,0 +1,27 @@
|
|
1
|
+
import { IgnoredOSUpdates } from "@ledgerhq/types-live";
|
2
|
+
import { GetLatestAvailableFirmwareActionState } from "../actions/getLatestAvailableFirmware";
|
3
|
+
|
4
|
+
/**
|
5
|
+
* Filters out ignored firmware updates from the action state
|
6
|
+
*
|
7
|
+
* @param newValue The current action state
|
8
|
+
* @param ignoredOSUpdates Array of firmware versions to ignore
|
9
|
+
* @returns The filtered action state
|
10
|
+
*/
|
11
|
+
export const filterIgnoredFirmwareUpdates = (
|
12
|
+
newValue: GetLatestAvailableFirmwareActionState,
|
13
|
+
ignoredOSUpdates?: IgnoredOSUpdates,
|
14
|
+
): GetLatestAvailableFirmwareActionState => {
|
15
|
+
// There is an available firmware update
|
16
|
+
if (newValue.status === "available-firmware" && newValue.firmwareUpdateContext?.final.name) {
|
17
|
+
// Filter out the ignored firmware versions
|
18
|
+
if (ignoredOSUpdates && ignoredOSUpdates.includes(newValue.firmwareUpdateContext?.final.name)) {
|
19
|
+
return {
|
20
|
+
...newValue,
|
21
|
+
firmwareUpdateContext: null,
|
22
|
+
status: "no-available-firmware",
|
23
|
+
};
|
24
|
+
}
|
25
|
+
}
|
26
|
+
return newValue;
|
27
|
+
};
|
@@ -0,0 +1,192 @@
|
|
1
|
+
import { type Feature_OnboardingIgnoredOSUpdates } from "@ledgerhq/types-live";
|
2
|
+
import { DeviceModelId } from "@ledgerhq/types-devices";
|
3
|
+
import { getIgnoredOSUpdatesForDeviceModelAndPlatform } from "./getIgnoredOSUpdatesForDeviceModelAndPlatform";
|
4
|
+
|
5
|
+
describe("getIgnoredOSUpdatesForDeviceModelAndPlatform", () => {
|
6
|
+
const mockConfig: Feature_OnboardingIgnoredOSUpdates["params"] = {
|
7
|
+
ios: {
|
8
|
+
[DeviceModelId.nanoS]: ["1.6.0", "1.6.1"],
|
9
|
+
[DeviceModelId.nanoX]: ["2.0.0"],
|
10
|
+
[DeviceModelId.nanoSP]: ["1.0.0", "1.0.1", "1.0.2"],
|
11
|
+
},
|
12
|
+
android: {
|
13
|
+
[DeviceModelId.nanoS]: ["1.5.0"],
|
14
|
+
[DeviceModelId.nanoX]: ["2.1.0", "2.1.1"],
|
15
|
+
},
|
16
|
+
macos: {
|
17
|
+
[DeviceModelId.nanoX]: ["2.2.0"],
|
18
|
+
},
|
19
|
+
windows: {
|
20
|
+
[DeviceModelId.stax]: ["3.0.0"],
|
21
|
+
},
|
22
|
+
linux: {
|
23
|
+
[DeviceModelId.europa]: ["4.0.0", "4.0.1"],
|
24
|
+
},
|
25
|
+
};
|
26
|
+
|
27
|
+
describe("when config is undefined", () => {
|
28
|
+
it("should return empty array", () => {
|
29
|
+
const result = getIgnoredOSUpdatesForDeviceModelAndPlatform(
|
30
|
+
undefined,
|
31
|
+
DeviceModelId.nanoS,
|
32
|
+
"ios",
|
33
|
+
);
|
34
|
+
expect(result).toEqual([]);
|
35
|
+
});
|
36
|
+
});
|
37
|
+
|
38
|
+
describe("when config is null", () => {
|
39
|
+
it("should return empty array", () => {
|
40
|
+
const result = getIgnoredOSUpdatesForDeviceModelAndPlatform(
|
41
|
+
null as unknown as Feature_OnboardingIgnoredOSUpdates["params"],
|
42
|
+
DeviceModelId.nanoS,
|
43
|
+
"ios",
|
44
|
+
);
|
45
|
+
expect(result).toEqual([]);
|
46
|
+
});
|
47
|
+
});
|
48
|
+
|
49
|
+
describe("when platform does not exist in config", () => {
|
50
|
+
it("should return empty array", () => {
|
51
|
+
const configWithoutPlatform: Feature_OnboardingIgnoredOSUpdates["params"] = {
|
52
|
+
ios: { [DeviceModelId.nanoS]: ["1.6.0"] },
|
53
|
+
};
|
54
|
+
|
55
|
+
const result = getIgnoredOSUpdatesForDeviceModelAndPlatform(
|
56
|
+
configWithoutPlatform,
|
57
|
+
DeviceModelId.nanoS,
|
58
|
+
"android",
|
59
|
+
);
|
60
|
+
expect(result).toEqual([]);
|
61
|
+
});
|
62
|
+
});
|
63
|
+
|
64
|
+
describe("when device model does not exist for platform", () => {
|
65
|
+
it("should return empty array", () => {
|
66
|
+
const result = getIgnoredOSUpdatesForDeviceModelAndPlatform(
|
67
|
+
mockConfig,
|
68
|
+
DeviceModelId.stax,
|
69
|
+
"ios",
|
70
|
+
);
|
71
|
+
expect(result).toEqual([]);
|
72
|
+
});
|
73
|
+
});
|
74
|
+
|
75
|
+
describe("when device model exists but has no ignored updates", () => {
|
76
|
+
it("should return empty array", () => {
|
77
|
+
const configWithEmptyArray: Feature_OnboardingIgnoredOSUpdates["params"] = {
|
78
|
+
ios: {
|
79
|
+
[DeviceModelId.nanoS]: [],
|
80
|
+
},
|
81
|
+
};
|
82
|
+
|
83
|
+
const result = getIgnoredOSUpdatesForDeviceModelAndPlatform(
|
84
|
+
configWithEmptyArray,
|
85
|
+
DeviceModelId.nanoS,
|
86
|
+
"ios",
|
87
|
+
);
|
88
|
+
expect(result).toEqual([]);
|
89
|
+
});
|
90
|
+
});
|
91
|
+
|
92
|
+
describe("when device model exists and has ignored updates", () => {
|
93
|
+
it("should return the ignored updates for iOS", () => {
|
94
|
+
const result = getIgnoredOSUpdatesForDeviceModelAndPlatform(
|
95
|
+
mockConfig,
|
96
|
+
DeviceModelId.nanoS,
|
97
|
+
"ios",
|
98
|
+
);
|
99
|
+
expect(result).toEqual(["1.6.0", "1.6.1"]);
|
100
|
+
});
|
101
|
+
|
102
|
+
it("should return the ignored updates for Android", () => {
|
103
|
+
const result = getIgnoredOSUpdatesForDeviceModelAndPlatform(
|
104
|
+
mockConfig,
|
105
|
+
DeviceModelId.nanoX,
|
106
|
+
"android",
|
107
|
+
);
|
108
|
+
expect(result).toEqual(["2.1.0", "2.1.1"]);
|
109
|
+
});
|
110
|
+
|
111
|
+
it("should return multiple ignored updates", () => {
|
112
|
+
const result = getIgnoredOSUpdatesForDeviceModelAndPlatform(
|
113
|
+
mockConfig,
|
114
|
+
DeviceModelId.nanoSP,
|
115
|
+
"ios",
|
116
|
+
);
|
117
|
+
expect(result).toEqual(["1.0.0", "1.0.1", "1.0.2"]);
|
118
|
+
});
|
119
|
+
|
120
|
+
it("should return ignored updates for macOS", () => {
|
121
|
+
const result = getIgnoredOSUpdatesForDeviceModelAndPlatform(
|
122
|
+
mockConfig,
|
123
|
+
DeviceModelId.nanoX,
|
124
|
+
"macos",
|
125
|
+
);
|
126
|
+
expect(result).toEqual(["2.2.0"]);
|
127
|
+
});
|
128
|
+
|
129
|
+
it("should return ignored updates for Windows", () => {
|
130
|
+
const result = getIgnoredOSUpdatesForDeviceModelAndPlatform(
|
131
|
+
mockConfig,
|
132
|
+
DeviceModelId.stax,
|
133
|
+
"windows",
|
134
|
+
);
|
135
|
+
expect(result).toEqual(["3.0.0"]);
|
136
|
+
});
|
137
|
+
|
138
|
+
it("should return ignored updates for Linux", () => {
|
139
|
+
const result = getIgnoredOSUpdatesForDeviceModelAndPlatform(
|
140
|
+
mockConfig,
|
141
|
+
DeviceModelId.europa,
|
142
|
+
"linux",
|
143
|
+
);
|
144
|
+
expect(result).toEqual(["4.0.0", "4.0.1"]);
|
145
|
+
});
|
146
|
+
});
|
147
|
+
|
148
|
+
describe("edge cases", () => {
|
149
|
+
it("should handle empty config object", () => {
|
150
|
+
const emptyConfig: Feature_OnboardingIgnoredOSUpdates["params"] = {};
|
151
|
+
|
152
|
+
const result = getIgnoredOSUpdatesForDeviceModelAndPlatform(
|
153
|
+
emptyConfig,
|
154
|
+
DeviceModelId.nanoS,
|
155
|
+
"ios",
|
156
|
+
);
|
157
|
+
expect(result).toEqual([]);
|
158
|
+
});
|
159
|
+
|
160
|
+
it("should handle config with empty platform objects", () => {
|
161
|
+
const configWithEmptyPlatforms: Feature_OnboardingIgnoredOSUpdates["params"] = {
|
162
|
+
ios: {},
|
163
|
+
android: {},
|
164
|
+
macos: {},
|
165
|
+
windows: {},
|
166
|
+
linux: {},
|
167
|
+
};
|
168
|
+
|
169
|
+
const result = getIgnoredOSUpdatesForDeviceModelAndPlatform(
|
170
|
+
configWithEmptyPlatforms,
|
171
|
+
DeviceModelId.nanoS,
|
172
|
+
"ios",
|
173
|
+
);
|
174
|
+
expect(result).toEqual([]);
|
175
|
+
});
|
176
|
+
|
177
|
+
it("should handle undefined device model entries", () => {
|
178
|
+
const configWithUndefined: Feature_OnboardingIgnoredOSUpdates["params"] = {
|
179
|
+
ios: {
|
180
|
+
[DeviceModelId.nanoS]: undefined as unknown as string[],
|
181
|
+
},
|
182
|
+
};
|
183
|
+
|
184
|
+
const result = getIgnoredOSUpdatesForDeviceModelAndPlatform(
|
185
|
+
configWithUndefined,
|
186
|
+
DeviceModelId.nanoS,
|
187
|
+
"ios",
|
188
|
+
);
|
189
|
+
expect(result).toEqual([]);
|
190
|
+
});
|
191
|
+
});
|
192
|
+
});
|
@@ -0,0 +1,28 @@
|
|
1
|
+
import type {
|
2
|
+
Feature_OnboardingIgnoredOSUpdates,
|
3
|
+
Platform,
|
4
|
+
IgnoredOSUpdates,
|
5
|
+
} from "@ledgerhq/types-live";
|
6
|
+
import type { DeviceModelId } from "@ledgerhq/types-devices";
|
7
|
+
|
8
|
+
/**
|
9
|
+
* Extracts the ignored OS updates for a specific device model and platform from the configuration
|
10
|
+
*
|
11
|
+
* @param ignoredOSUpdatesConfig The configuration object containing ignored OS updates per platform and device model
|
12
|
+
* @param deviceModelId The device model identifier
|
13
|
+
* @param platform The platform to get updates for
|
14
|
+
* @returns Array of firmware versions that should be ignored for the given device model and platform
|
15
|
+
*/
|
16
|
+
export const getIgnoredOSUpdatesForDeviceModelAndPlatform = (
|
17
|
+
ignoredOSUpdatesConfig: Feature_OnboardingIgnoredOSUpdates["params"] | undefined,
|
18
|
+
deviceModelId: DeviceModelId,
|
19
|
+
platform: Platform,
|
20
|
+
): IgnoredOSUpdates => {
|
21
|
+
// No ignored OS updates configuration
|
22
|
+
if (!ignoredOSUpdatesConfig) return [];
|
23
|
+
// No configuration for the specified platform
|
24
|
+
const configForPlatform = ignoredOSUpdatesConfig[platform];
|
25
|
+
if (!configForPlatform) return [];
|
26
|
+
// Return the ignored OS updates for the specified device model, empty array if not configured for that model
|
27
|
+
return configForPlatform[deviceModelId] ?? [];
|
28
|
+
};
|
@@ -5,11 +5,14 @@ import {
|
|
5
5
|
getLatestAvailableFirmwareAction as defaultGetLatestAvailableFirmwareAction,
|
6
6
|
initialState,
|
7
7
|
} from "../actions/getLatestAvailableFirmware";
|
8
|
+
import { filterIgnoredFirmwareUpdates } from "./filterIgnoredFirmwareUpdates";
|
9
|
+
import type { IgnoredOSUpdates } from "@ledgerhq/types-live";
|
8
10
|
|
9
11
|
export type UseGetLatestAvailableFirmwareArgs = {
|
10
12
|
getLatestAvailableFirmwareAction?: typeof defaultGetLatestAvailableFirmwareAction;
|
11
13
|
deviceId: string;
|
12
14
|
isHookEnabled?: boolean;
|
15
|
+
ignoredOSUpdates?: IgnoredOSUpdates;
|
13
16
|
};
|
14
17
|
|
15
18
|
/**
|
@@ -30,6 +33,7 @@ export const useGetLatestAvailableFirmware = ({
|
|
30
33
|
getLatestAvailableFirmwareAction = defaultGetLatestAvailableFirmwareAction,
|
31
34
|
deviceId,
|
32
35
|
isHookEnabled = true,
|
36
|
+
ignoredOSUpdates,
|
33
37
|
}: UseGetLatestAvailableFirmwareArgs): {
|
34
38
|
state: GetLatestAvailableFirmwareActionState;
|
35
39
|
} => {
|
@@ -47,7 +51,10 @@ export const useGetLatestAvailableFirmware = ({
|
|
47
51
|
const subscription = getLatestAvailableFirmwareAction({
|
48
52
|
deviceId,
|
49
53
|
}).subscribe({
|
50
|
-
next:
|
54
|
+
next: newValue => {
|
55
|
+
const filteredValue = filterIgnoredFirmwareUpdates(newValue, ignoredOSUpdates);
|
56
|
+
setState(filteredValue);
|
57
|
+
},
|
51
58
|
error: (error: unknown) => {
|
52
59
|
// Error from an action should be handled like an event and should not reach here
|
53
60
|
log("useGetLatestAvailableFirmware", "Unknown error", error);
|
@@ -57,7 +64,7 @@ export const useGetLatestAvailableFirmware = ({
|
|
57
64
|
return () => {
|
58
65
|
subscription.unsubscribe();
|
59
66
|
};
|
60
|
-
}, [deviceId, getLatestAvailableFirmwareAction, isHookEnabled]);
|
67
|
+
}, [deviceId, getLatestAvailableFirmwareAction, ignoredOSUpdates, isHookEnabled]);
|
61
68
|
|
62
69
|
return { state };
|
63
70
|
};
|
@@ -18,6 +18,8 @@ import { inferDescriptorFromAccount, AccountDescriptor } from "@ledgerhq/coin-bi
|
|
18
18
|
import { setEnv } from "@ledgerhq/live-env";
|
19
19
|
import { fromAccountRaw } from "../../account";
|
20
20
|
import { setSupportedCurrencies } from "../../currencies";
|
21
|
+
import { setCryptoAssetsStore as setCryptoAssetsStoreForCoinFramework } from "@ledgerhq/coin-framework/crypto-assets/index";
|
22
|
+
import { CryptoAssetsStore } from "@ledgerhq/coin-framework/crypto-assets/type";
|
21
23
|
|
22
24
|
setSupportedCurrencies(["bitcoin"]);
|
23
25
|
jest.setTimeout(10000);
|
@@ -230,6 +232,11 @@ describe("stringifySatStackConfig", () => {
|
|
230
232
|
});
|
231
233
|
});
|
232
234
|
describe("editSatStackConfig", () => {
|
235
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
236
|
+
setCryptoAssetsStoreForCoinFramework({
|
237
|
+
findTokenById: (_: string) => undefined,
|
238
|
+
findTokenByAddressInCurrency: (_: string, __: string) => undefined,
|
239
|
+
} as CryptoAssetsStore);
|
233
240
|
const config = {
|
234
241
|
node: { ...mockConfig, tls: false },
|
235
242
|
extra: {
|