@ledgerhq/live-common 34.52.0-nightly.1 → 34.52.0-nightly.3

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 (94) hide show
  1. package/lib/bridge/generic-alpaca/alpaca/network/network-alpaca.d.ts +2 -1
  2. package/lib/bridge/generic-alpaca/alpaca/network/network-alpaca.d.ts.map +1 -1
  3. package/lib/bridge/generic-alpaca/alpaca/network/network-alpaca.js +3 -0
  4. package/lib/bridge/generic-alpaca/alpaca/network/network-alpaca.js.map +1 -1
  5. package/lib/dada-client/hooks/useAssetsData.d.ts +4 -10
  6. package/lib/dada-client/hooks/useAssetsData.d.ts.map +1 -1
  7. package/lib/dada-client/hooks/useAssetsData.js +2 -1
  8. package/lib/dada-client/hooks/useAssetsData.js.map +1 -1
  9. package/lib/dada-client/state-manager/api.d.ts.map +1 -1
  10. package/lib/dada-client/state-manager/api.js +3 -0
  11. package/lib/dada-client/state-manager/api.js.map +1 -1
  12. package/lib/dada-client/state-manager/types.d.ts +1 -0
  13. package/lib/dada-client/state-manager/types.d.ts.map +1 -1
  14. package/lib/e2e/data/deviceLabelsData.d.ts.map +1 -1
  15. package/lib/e2e/data/deviceLabelsData.js +3 -4
  16. package/lib/e2e/data/deviceLabelsData.js.map +1 -1
  17. package/lib/e2e/deviceInteraction/TouchDeviceSimulator.d.ts.map +1 -1
  18. package/lib/e2e/deviceInteraction/TouchDeviceSimulator.js +13 -5
  19. package/lib/e2e/deviceInteraction/TouchDeviceSimulator.js.map +1 -1
  20. package/lib/e2e/speculos.d.ts.map +1 -1
  21. package/lib/e2e/speculos.js +14 -15
  22. package/lib/e2e/speculos.js.map +1 -1
  23. package/lib/generated/deviceTransactionConfig.d.ts +1 -1
  24. package/lib/hooks/useDeviceTransactionConfig.d.ts +19 -0
  25. package/lib/hooks/useDeviceTransactionConfig.d.ts.map +1 -0
  26. package/lib/hooks/useDeviceTransactionConfig.js +45 -0
  27. package/lib/hooks/useDeviceTransactionConfig.js.map +1 -0
  28. package/lib/modularDrawer/__mocks__/currencies.mock.d.ts +3 -0
  29. package/lib/modularDrawer/__mocks__/currencies.mock.d.ts.map +1 -1
  30. package/lib/modularDrawer/__mocks__/currencies.mock.js +40 -1
  31. package/lib/modularDrawer/__mocks__/currencies.mock.js.map +1 -1
  32. package/lib/modularDrawer/utils/index.d.ts +3 -2
  33. package/lib/modularDrawer/utils/index.d.ts.map +1 -1
  34. package/lib/modularDrawer/utils/index.js +6 -10
  35. package/lib/modularDrawer/utils/index.js.map +1 -1
  36. package/lib/transaction/deviceTransactionConfig.d.ts +1 -1
  37. package/lib/transaction/deviceTransactionConfig.d.ts.map +1 -1
  38. package/lib/transaction/deviceTransactionConfig.js +2 -2
  39. package/lib/transaction/deviceTransactionConfig.js.map +1 -1
  40. package/lib-es/bridge/generic-alpaca/alpaca/network/network-alpaca.d.ts +2 -1
  41. package/lib-es/bridge/generic-alpaca/alpaca/network/network-alpaca.d.ts.map +1 -1
  42. package/lib-es/bridge/generic-alpaca/alpaca/network/network-alpaca.js +3 -0
  43. package/lib-es/bridge/generic-alpaca/alpaca/network/network-alpaca.js.map +1 -1
  44. package/lib-es/dada-client/hooks/useAssetsData.d.ts +4 -10
  45. package/lib-es/dada-client/hooks/useAssetsData.d.ts.map +1 -1
  46. package/lib-es/dada-client/hooks/useAssetsData.js +2 -1
  47. package/lib-es/dada-client/hooks/useAssetsData.js.map +1 -1
  48. package/lib-es/dada-client/state-manager/api.d.ts.map +1 -1
  49. package/lib-es/dada-client/state-manager/api.js +3 -0
  50. package/lib-es/dada-client/state-manager/api.js.map +1 -1
  51. package/lib-es/dada-client/state-manager/types.d.ts +1 -0
  52. package/lib-es/dada-client/state-manager/types.d.ts.map +1 -1
  53. package/lib-es/e2e/data/deviceLabelsData.d.ts.map +1 -1
  54. package/lib-es/e2e/data/deviceLabelsData.js +3 -4
  55. package/lib-es/e2e/data/deviceLabelsData.js.map +1 -1
  56. package/lib-es/e2e/deviceInteraction/TouchDeviceSimulator.d.ts.map +1 -1
  57. package/lib-es/e2e/deviceInteraction/TouchDeviceSimulator.js +13 -5
  58. package/lib-es/e2e/deviceInteraction/TouchDeviceSimulator.js.map +1 -1
  59. package/lib-es/e2e/speculos.d.ts.map +1 -1
  60. package/lib-es/e2e/speculos.js +14 -15
  61. package/lib-es/e2e/speculos.js.map +1 -1
  62. package/lib-es/generated/deviceTransactionConfig.d.ts +1 -1
  63. package/lib-es/hooks/useDeviceTransactionConfig.d.ts +19 -0
  64. package/lib-es/hooks/useDeviceTransactionConfig.d.ts.map +1 -0
  65. package/lib-es/hooks/useDeviceTransactionConfig.js +41 -0
  66. package/lib-es/hooks/useDeviceTransactionConfig.js.map +1 -0
  67. package/lib-es/modularDrawer/__mocks__/currencies.mock.d.ts +3 -0
  68. package/lib-es/modularDrawer/__mocks__/currencies.mock.d.ts.map +1 -1
  69. package/lib-es/modularDrawer/__mocks__/currencies.mock.js +39 -0
  70. package/lib-es/modularDrawer/__mocks__/currencies.mock.js.map +1 -1
  71. package/lib-es/modularDrawer/utils/index.d.ts +3 -2
  72. package/lib-es/modularDrawer/utils/index.d.ts.map +1 -1
  73. package/lib-es/modularDrawer/utils/index.js +4 -9
  74. package/lib-es/modularDrawer/utils/index.js.map +1 -1
  75. package/lib-es/transaction/deviceTransactionConfig.d.ts +1 -1
  76. package/lib-es/transaction/deviceTransactionConfig.d.ts.map +1 -1
  77. package/lib-es/transaction/deviceTransactionConfig.js +2 -2
  78. package/lib-es/transaction/deviceTransactionConfig.js.map +1 -1
  79. package/package.json +48 -48
  80. package/src/account/serialization.test.ts +1 -0
  81. package/src/bridge/generic-alpaca/alpaca/network/network-alpaca.ts +4 -0
  82. package/src/dada-client/hooks/useAssetsData.ts +4 -8
  83. package/src/dada-client/state-manager/api.ts +3 -0
  84. package/src/dada-client/state-manager/types.ts +1 -0
  85. package/src/e2e/data/deviceLabelsData.ts +3 -4
  86. package/src/e2e/deviceInteraction/TouchDeviceSimulator.ts +12 -5
  87. package/src/e2e/speculos.ts +18 -16
  88. package/src/families/bitcoin/satstack.test.ts +1 -0
  89. package/src/hooks/useDeviceTransactionConfig.test.tsx +200 -0
  90. package/src/hooks/useDeviceTransactionConfig.ts +65 -0
  91. package/src/modularDrawer/__mocks__/currencies.mock.ts +40 -0
  92. package/src/modularDrawer/utils/index.ts +6 -10
  93. package/src/transaction/deviceTransactionConfig.ts +3 -3
  94. package/src/modularDrawer/utils/index.test.ts +0 -43
@@ -114,7 +114,7 @@ export const DEVICE_LABELS_CONFIG: DeviceLabelsConfig = {
114
114
  [AppInfos.ETHEREUM.name]: DeviceLabels.VERIFY_ETHEREUM,
115
115
  [AppInfos.POLKADOT.name]: DeviceLabels.PLEASE_REVIEW,
116
116
  [AppInfos.POLYGON.name]: DeviceLabels.VERIFY_POLYGON,
117
- [AppInfos.SOLANA.name]: DeviceLabels.VERIFY_SOLANA_ADDRESS,
117
+ [AppInfos.SOLANA.name]: DeviceLabels.PUBKEY,
118
118
  default: DeviceLabels.ADDRESS,
119
119
  },
120
120
  receiveConfirm: {
@@ -124,14 +124,13 @@ export const DEVICE_LABELS_CONFIG: DeviceLabelsConfig = {
124
124
  [AppInfos.ETHEREUM.name]: DeviceLabels.CONFIRM,
125
125
  [AppInfos.POLKADOT.name]: DeviceLabels.CAPS_APPROVE,
126
126
  [AppInfos.POLYGON.name]: DeviceLabels.CONFIRM,
127
- [AppInfos.SOLANA.name]: DeviceLabels.CONFIRM,
128
127
  default: DeviceLabels.APPROVE,
129
128
  },
130
129
  delegateVerify: {
131
130
  [AppInfos.COSMOS.name]: DeviceLabels.PLEASE_REVIEW,
132
131
  [AppInfos.MULTIVERS_X.name]: DeviceLabels.RECEIVER,
133
132
  [AppInfos.NEAR.name]: DeviceLabels.VIEW_HEADER,
134
- [AppInfos.SOLANA.name]: DeviceLabels.REVIEW_TRANSACTION,
133
+ [AppInfos.SOLANA.name]: DeviceLabels.DELEGATE_FROM,
135
134
  default: DeviceLabels.REVIEW_OPERATION,
136
135
  },
137
136
  delegateConfirm: {
@@ -141,7 +140,6 @@ export const DEVICE_LABELS_CONFIG: DeviceLabelsConfig = {
141
140
  [AppInfos.INJECTIVE.name]: DeviceLabels.CAPS_APPROVE,
142
141
  [AppInfos.MULTIVERS_X.name]: DeviceLabels.SIGN,
143
142
  [AppInfos.NEAR.name]: DeviceLabels.CONTINUE_TO_ACTION,
144
- [AppInfos.SOLANA.name]: DeviceLabels.SIGN_TRANSACTION,
145
143
  [AppInfos.OSMOSIS.name]: DeviceLabels.CAPS_APPROVE,
146
144
  default: DeviceLabels.APPROVE,
147
145
  },
@@ -160,6 +158,7 @@ export const DEVICE_LABELS_CONFIG: DeviceLabelsConfig = {
160
158
  [AppInfos.BITCOIN.name]: DeviceLabels.SIGN_TRANSACTION,
161
159
  [AppInfos.KASPA.name]: DeviceLabels.APPROVE,
162
160
  [AppInfos.DOGECOIN.name]: DeviceLabels.ACCEPT,
161
+ [AppInfos.BITCOIN_CASH.name]: DeviceLabels.ACCEPT,
163
162
  default: DeviceLabels.CAPS_APPROVE,
164
163
  },
165
164
  },
@@ -12,14 +12,21 @@ function getSpeculosInfo(): {
12
12
  }
13
13
  export async function pressAndRelease(deviceLabel: string, x?: number, y?: number) {
14
14
  const { speculosApiPort, speculosAddress } = getSpeculosInfo();
15
- const { x: coordX, y: coordY } = await getDeviceLabelCoordinates(deviceLabel, speculosApiPort);
16
- x = x === undefined ? coordX : x;
17
- y = y === undefined ? coordY : y;
15
+ let xCoord: number;
16
+ let yCoord: number;
17
+ if (x && y) {
18
+ xCoord = x;
19
+ yCoord = y;
20
+ } else {
21
+ const coords = await getDeviceLabelCoordinates(deviceLabel, speculosApiPort);
22
+ xCoord = coords.x;
23
+ yCoord = coords.y;
24
+ }
18
25
  await retryAxiosRequest(() =>
19
26
  axios.post(`${speculosAddress}:${speculosApiPort}/finger`, {
20
27
  action: "press-and-release",
21
- x: x,
22
- y: y,
28
+ x: xCoord,
29
+ y: yCoord,
23
30
  }),
24
31
  );
25
32
  }
@@ -654,7 +654,12 @@ export async function activateLedgerSync() {
654
654
  export async function activateExpertMode() {
655
655
  if (isTouchDevice()) {
656
656
  await goToSettings();
657
- await pressAndRelease(DeviceLabels.SETTINGS_TOGGLE_1);
657
+ const SettingsToggle1Coordinates = { x: 344, y: 136 };
658
+ await pressAndRelease(
659
+ DeviceLabels.SETTINGS_TOGGLE_1,
660
+ SettingsToggle1Coordinates.x,
661
+ SettingsToggle1Coordinates.y,
662
+ );
658
663
  } else {
659
664
  await pressUntilTextFound(DeviceLabels.EXPERT_MODE);
660
665
  await pressBoth();
@@ -723,26 +728,23 @@ export function getDeviceLabels(appInfo: AppInfos): DeviceLabelsReturn {
723
728
  export async function expectValidAddressDevice(account: Account, addressDisplayed: string) {
724
729
  if (account.currency === Currency.SUI_USDC) {
725
730
  providePublicKey();
731
+ }
732
+ const { receiveVerifyLabel, receiveConfirmLabel } = getDeviceLabels(account.currency.speculosApp);
733
+ await waitFor(receiveVerifyLabel);
734
+ if (isTouchDevice()) {
735
+ const events = await pressUntilTextFound(receiveConfirmLabel);
736
+ const isAddressCorrect = containsSubstringInEvent(addressDisplayed, events);
737
+ expect(isAddressCorrect).toBeTruthy();
738
+ await pressAndRelease(DeviceLabels.CONFIRM);
726
739
  } else {
727
740
  const { receiveVerifyLabel, receiveConfirmLabel } = getDeviceLabels(
728
741
  account.currency.speculosApp,
729
742
  );
730
743
  await waitFor(receiveVerifyLabel);
731
- if (isTouchDevice()) {
732
- const events = await pressUntilTextFound(receiveConfirmLabel);
733
- const isAddressCorrect = containsSubstringInEvent(addressDisplayed, events);
734
- expect(isAddressCorrect).toBeTruthy();
735
- await pressAndRelease(DeviceLabels.CONFIRM);
736
- } else {
737
- const { receiveVerifyLabel, receiveConfirmLabel } = getDeviceLabels(
738
- account.currency.speculosApp,
739
- );
740
- await waitFor(receiveVerifyLabel);
741
- const events = await pressUntilTextFound(receiveConfirmLabel);
742
- const isAddressCorrect = containsSubstringInEvent(addressDisplayed, events);
743
- expect(isAddressCorrect).toBeTruthy();
744
- await pressBoth();
745
- }
744
+ const events = await pressUntilTextFound(receiveConfirmLabel);
745
+ const isAddressCorrect = containsSubstringInEvent(addressDisplayed, events);
746
+ expect(isAddressCorrect).toBeTruthy();
747
+ await pressBoth();
746
748
  }
747
749
  }
748
750
 
@@ -236,6 +236,7 @@ describe("editSatStackConfig", () => {
236
236
  setCryptoAssetsStoreForCoinFramework({
237
237
  findTokenById: (_: string) => undefined,
238
238
  findTokenByAddressInCurrency: (_: string, __: string) => undefined,
239
+ getTokensSyncHash: (_: string) => Promise.resolve("0"),
239
240
  } as CryptoAssetsStore);
240
241
  const config = {
241
242
  node: { ...mockConfig, tls: false },
@@ -0,0 +1,200 @@
1
+ /**
2
+ * @jest-environment jsdom
3
+ */
4
+
5
+ import { TextDecoder, TextEncoder } from "util";
6
+
7
+ // Polyfill for TextDecoder/TextEncoder required by Cardano dependencies
8
+ global.TextDecoder = TextDecoder as any;
9
+ global.TextEncoder = TextEncoder as any;
10
+
11
+ // Mock the deviceTransactionConfig module before importing anything else
12
+ jest.mock("../transaction/deviceTransactionConfig", () => ({
13
+ getDeviceTransactionConfig: jest.fn(),
14
+ }));
15
+
16
+ import { renderHook, waitFor } from "@testing-library/react";
17
+ import { useDeviceTransactionConfig } from "./useDeviceTransactionConfig";
18
+ import { getDeviceTransactionConfig } from "../transaction/deviceTransactionConfig";
19
+ import { Account } from "@ledgerhq/types-live";
20
+ import { Transaction, TransactionStatus } from "../generated/types";
21
+ import BigNumber from "bignumber.js";
22
+ import { getCryptoCurrencyById } from "../currencies/index";
23
+
24
+ const mockGetDeviceTransactionConfig = getDeviceTransactionConfig as jest.MockedFunction<
25
+ typeof getDeviceTransactionConfig
26
+ >;
27
+
28
+ const btc = getCryptoCurrencyById("bitcoin");
29
+
30
+ describe("useDeviceTransactionConfig", () => {
31
+ const mockAccount: Account = {
32
+ type: "Account",
33
+ id: "test-account-id",
34
+ seedIdentifier: "seed-id",
35
+ derivationMode: "" as const,
36
+ index: 0,
37
+ freshAddress: "test-address",
38
+ freshAddressPath: "44'/0'/0'/0/0",
39
+ used: true,
40
+ balance: new BigNumber(1000000),
41
+ spendableBalance: new BigNumber(1000000),
42
+ creationDate: new Date(),
43
+ blockHeight: 100,
44
+ currency: btc,
45
+ operationsCount: 0,
46
+ operations: [],
47
+ pendingOperations: [],
48
+ lastSyncDate: new Date(),
49
+ balanceHistoryCache: {
50
+ HOUR: { latestDate: null, balances: [] },
51
+ DAY: { latestDate: null, balances: [] },
52
+ WEEK: { latestDate: null, balances: [] },
53
+ },
54
+ swapHistory: [],
55
+ };
56
+
57
+ const mockTransaction: Transaction = {
58
+ family: "bitcoin" as any,
59
+ amount: new BigNumber(100),
60
+ recipient: "test-recipient",
61
+ useAllAmount: false,
62
+ } as Transaction;
63
+
64
+ const mockStatus: TransactionStatus = {
65
+ errors: {},
66
+ warnings: {},
67
+ estimatedFees: new BigNumber(10),
68
+ amount: new BigNumber(100),
69
+ totalSpent: new BigNumber(110),
70
+ } as TransactionStatus;
71
+
72
+ beforeEach(() => {
73
+ jest.clearAllMocks();
74
+ });
75
+
76
+ it("should load device transaction config fields successfully", async () => {
77
+ const mockFields = [
78
+ { type: "amount", label: "Amount" },
79
+ { type: "fees", label: "Fees" },
80
+ ];
81
+
82
+ mockGetDeviceTransactionConfig.mockResolvedValue(mockFields as any);
83
+
84
+ const { result } = renderHook(() =>
85
+ useDeviceTransactionConfig({
86
+ account: mockAccount,
87
+ parentAccount: null,
88
+ transaction: mockTransaction,
89
+ status: mockStatus,
90
+ }),
91
+ );
92
+
93
+ // Initially loading
94
+ expect(result.current.loading).toBe(true);
95
+ expect(result.current.fields).toEqual([]);
96
+
97
+ // Wait for async operation
98
+ await waitFor(() => {
99
+ expect(result.current.loading).toBe(false);
100
+ });
101
+
102
+ expect(result.current.fields).toEqual(mockFields);
103
+ expect(mockGetDeviceTransactionConfig).toHaveBeenCalledWith({
104
+ account: mockAccount,
105
+ parentAccount: null,
106
+ transaction: mockTransaction,
107
+ status: mockStatus,
108
+ });
109
+ });
110
+
111
+ it("should handle errors gracefully", async () => {
112
+ const consoleErrorSpy = jest.spyOn(console, "error").mockImplementation();
113
+ mockGetDeviceTransactionConfig.mockRejectedValue(new Error("Test error"));
114
+
115
+ const { result } = renderHook(() =>
116
+ useDeviceTransactionConfig({
117
+ account: mockAccount,
118
+ parentAccount: null,
119
+ transaction: mockTransaction,
120
+ status: mockStatus,
121
+ }),
122
+ );
123
+
124
+ expect(result.current.loading).toBe(true);
125
+
126
+ await waitFor(() => {
127
+ expect(result.current.loading).toBe(false);
128
+ });
129
+
130
+ expect(result.current.fields).toEqual([]);
131
+ expect(consoleErrorSpy).toHaveBeenCalledWith(
132
+ "Failed to load device transaction config:",
133
+ expect.any(Error),
134
+ );
135
+
136
+ consoleErrorSpy.mockRestore();
137
+ });
138
+
139
+ it("should reload fields when dependencies change", async () => {
140
+ const mockFields1 = [{ type: "amount", label: "Amount 1" }];
141
+ const mockFields2 = [{ type: "amount", label: "Amount 2" }];
142
+
143
+ mockGetDeviceTransactionConfig
144
+ .mockResolvedValueOnce(mockFields1 as any)
145
+ .mockResolvedValueOnce(mockFields2 as any);
146
+
147
+ const { result, rerender } = renderHook(
148
+ ({ transaction }) =>
149
+ useDeviceTransactionConfig({
150
+ account: mockAccount,
151
+ parentAccount: null,
152
+ transaction,
153
+ status: mockStatus,
154
+ }),
155
+ {
156
+ initialProps: { transaction: mockTransaction },
157
+ },
158
+ );
159
+
160
+ await waitFor(() => {
161
+ expect(result.current.loading).toBe(false);
162
+ });
163
+
164
+ expect(result.current.fields).toEqual(mockFields1);
165
+
166
+ // Change transaction
167
+ const newTransaction = {
168
+ ...mockTransaction,
169
+ amount: new BigNumber(200),
170
+ };
171
+
172
+ rerender({ transaction: newTransaction });
173
+
174
+ await waitFor(() => {
175
+ expect(result.current.loading).toBe(false);
176
+ });
177
+
178
+ expect(result.current.fields).toEqual(mockFields2);
179
+ expect(mockGetDeviceTransactionConfig).toHaveBeenCalledTimes(2);
180
+ });
181
+
182
+ it("should cleanup on unmount", async () => {
183
+ const mockFields = [{ type: "amount", label: "Amount" }];
184
+ mockGetDeviceTransactionConfig.mockResolvedValue(mockFields as any);
185
+
186
+ const { unmount } = renderHook(() =>
187
+ useDeviceTransactionConfig({
188
+ account: mockAccount,
189
+ parentAccount: null,
190
+ transaction: mockTransaction,
191
+ status: mockStatus,
192
+ }),
193
+ );
194
+
195
+ unmount();
196
+
197
+ // Should not throw any errors
198
+ expect(mockGetDeviceTransactionConfig).toHaveBeenCalled();
199
+ });
200
+ });
@@ -0,0 +1,65 @@
1
+ import { useState, useEffect } from "react";
2
+ import { Account, AccountLike } from "@ledgerhq/types-live";
3
+ import { Transaction, TransactionStatus } from "../generated/types";
4
+ import {
5
+ getDeviceTransactionConfig,
6
+ DeviceTransactionField,
7
+ } from "../transaction/deviceTransactionConfig";
8
+
9
+ type UseDeviceTransactionConfigParams = {
10
+ account: AccountLike;
11
+ parentAccount: Account | null | undefined;
12
+ transaction: Transaction;
13
+ status: TransactionStatus;
14
+ };
15
+
16
+ /**
17
+ * Hook to fetch device transaction configuration fields asynchronously.
18
+ * This anticipates the future async nature of crypto assets store operations.
19
+ */
20
+ export function useDeviceTransactionConfig({
21
+ account,
22
+ parentAccount,
23
+ transaction,
24
+ status,
25
+ }: UseDeviceTransactionConfigParams): {
26
+ fields: DeviceTransactionField[];
27
+ loading: boolean;
28
+ } {
29
+ const [fields, setFields] = useState<DeviceTransactionField[]>([]);
30
+ const [loading, setLoading] = useState(true);
31
+
32
+ useEffect(() => {
33
+ let mounted = true;
34
+
35
+ async function loadFields() {
36
+ try {
37
+ setLoading(true);
38
+ const result = await getDeviceTransactionConfig({
39
+ account,
40
+ parentAccount,
41
+ transaction,
42
+ status,
43
+ });
44
+ if (mounted) {
45
+ setFields(result);
46
+ setLoading(false);
47
+ }
48
+ } catch (error) {
49
+ console.error("Failed to load device transaction config:", error);
50
+ if (mounted) {
51
+ setFields([]);
52
+ setLoading(false);
53
+ }
54
+ }
55
+ }
56
+
57
+ loadFields();
58
+
59
+ return () => {
60
+ mounted = false;
61
+ };
62
+ }, [account, parentAccount, transaction, status]);
63
+
64
+ return { fields, loading };
65
+ }
@@ -7,6 +7,7 @@ export const mockArbitrumCryptoCurrency = getCryptoCurrencyById("arbitrum");
7
7
  export const mockBaseCryptoCurrency = getCryptoCurrencyById("base");
8
8
  export const mockScrollCryptoCurrency = getCryptoCurrencyById("scroll");
9
9
  export const mockInjectiveCryptoCurrency = getCryptoCurrencyById("injective");
10
+ export const mockBscCryptoCurrency = getCryptoCurrencyById("bsc");
10
11
 
11
12
  export const arbitrumToken: TokenCurrency = {
12
13
  type: "TokenCurrency",
@@ -41,6 +42,45 @@ export const usdcToken: TokenCurrency = {
41
42
  ],
42
43
  };
43
44
 
45
+ export const maticEth: TokenCurrency = {
46
+ type: "TokenCurrency" as const,
47
+ id: "ethereum/erc20/matic",
48
+ ledgerSignature: "",
49
+ contractAddress: "0x7D1AfA7B718fb893dB30A3aBc0Cfc608AaCfeBB0",
50
+ parentCurrency: mockEthCryptoCurrency,
51
+ tokenType: "erc20" as const,
52
+ name: "Matic",
53
+ ticker: "MATIC",
54
+ delisted: false,
55
+ disableCountervalue: false,
56
+ units: [
57
+ {
58
+ name: "Matic",
59
+ code: "MATIC",
60
+ magnitude: 18,
61
+ },
62
+ ],
63
+ };
64
+
65
+ export const maticBsc: TokenCurrency = {
66
+ type: "TokenCurrency" as const,
67
+ id: "bsc/bep20/matic_token",
68
+ ledgerSignature: "",
69
+ contractAddress: "0xCC42724C6683B7E57334c4E856f4c9965ED682bD",
70
+ parentCurrency: mockBscCryptoCurrency,
71
+ tokenType: "bep20" as const,
72
+ name: "Matic Token",
73
+ ticker: "MATIC",
74
+ delisted: false,
75
+ disableCountervalue: false,
76
+ units: [
77
+ {
78
+ name: "Matic Token",
79
+ code: "MATIC",
80
+ magnitude: 18,
81
+ },
82
+ ],
83
+ };
44
84
  export const findCryptoCurrencyById = (id: string) =>
45
85
  [mockBtcCryptoCurrency, mockEthCryptoCurrency, mockArbitrumCryptoCurrency].find(a => a.id === id);
46
86
  export const getTokenOrCryptoCurrencyById = (id: string) =>
@@ -2,17 +2,13 @@ import { CryptoOrTokenCurrency } from "@ledgerhq/types-cryptoassets";
2
2
  export { groupCurrenciesByProvider } from "./groupCurrenciesByProvider";
3
3
  export { sortAccountsByFiatValue } from "./sortAccountsByFiatValue";
4
4
 
5
- function isCorrespondingCurrency(
5
+ const getBaseId = (currency: CryptoOrTokenCurrency) =>
6
+ currency.type === "CryptoCurrency" ? currency.id : currency.parentCurrency.id;
7
+
8
+ function belongsToSameNetwork(
6
9
  elem: CryptoOrTokenCurrency,
7
10
  network: CryptoOrTokenCurrency,
8
11
  ): boolean {
9
- if (elem.type === "TokenCurrency") {
10
- return elem.parentCurrency?.id === network.id || elem.id === network.id;
11
- }
12
- if (elem.type === "CryptoCurrency") {
13
- return elem.id === network.id;
14
- }
15
- return false;
12
+ return getBaseId(elem) === getBaseId(network);
16
13
  }
17
-
18
- export { isCorrespondingCurrency };
14
+ export { getBaseId, belongsToSameNetwork };
@@ -6,14 +6,14 @@ import { getMainAccount } from "../account";
6
6
  import type { Account, AccountLike } from "@ledgerhq/types-live";
7
7
 
8
8
  export type DeviceTransactionField = CommonDeviceTransactionField | ExtraDeviceTransactionField;
9
- export function getDeviceTransactionConfig(arg: {
9
+ export async function getDeviceTransactionConfig(arg: {
10
10
  account: AccountLike;
11
11
  parentAccount: Account | null | undefined;
12
12
  transaction: Transaction;
13
13
  status: TransactionStatus;
14
- }): Array<DeviceTransactionField> {
14
+ }): Promise<Array<DeviceTransactionField>> {
15
15
  const mainAccount = getMainAccount(arg.account, arg.parentAccount);
16
16
  const f = perFamily[mainAccount.currency.family];
17
17
  if (!f) return [];
18
- return f(arg);
18
+ return await f(arg);
19
19
  }
@@ -1,43 +0,0 @@
1
- import { isCorrespondingCurrency } from "./index";
2
-
3
- import { createFixtureCryptoCurrency } from "../../mock/fixtures/cryptoCurrencies";
4
- import { cryptocurrenciesById } from "@ledgerhq/cryptoassets";
5
- import type { CryptoOrTokenCurrency } from "@ledgerhq/types-cryptoassets";
6
-
7
- describe("isCorrespondingCurrency", () => {
8
- const evmCurrency = createFixtureCryptoCurrency("evm");
9
- const usdcToken: CryptoOrTokenCurrency = {
10
- type: "TokenCurrency",
11
- id: "ethereum/erc20/usdc",
12
- contractAddress: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
13
- parentCurrency: evmCurrency,
14
- tokenType: "erc20",
15
- name: "USD Coin",
16
- ticker: "USDC",
17
- units: [{ name: "USD Coin", code: "USDC", magnitude: 6 }],
18
- };
19
- const evmCrypto: CryptoOrTokenCurrency = evmCurrency;
20
-
21
- it("returns true for a token whose parentCurrency.id matches the reference crypto", () => {
22
- expect(isCorrespondingCurrency(usdcToken, evmCurrency)).toBe(true);
23
- });
24
-
25
- it("returns true for a token whose id matches the reference crypto", () => {
26
- expect(isCorrespondingCurrency(usdcToken, usdcToken)).toBe(true);
27
- });
28
-
29
- it("returns true for a crypto whose id matches the reference crypto", () => {
30
- expect(isCorrespondingCurrency(evmCrypto, evmCurrency)).toBe(true);
31
- });
32
-
33
- it("returns false for a token whose parentCurrency is different", () => {
34
- const bitcoinCurrency = cryptocurrenciesById["bitcoin"];
35
- const tokenWithOtherParent = { ...usdcToken, parentCurrency: bitcoinCurrency };
36
- expect(isCorrespondingCurrency(tokenWithOtherParent, evmCurrency)).toBe(false);
37
- });
38
-
39
- it("returns false for a crypto whose id is different", () => {
40
- const bitcoinCurrency = cryptocurrenciesById["bitcoin"];
41
- expect(isCorrespondingCurrency(bitcoinCurrency, evmCurrency)).toBe(false);
42
- });
43
- });