@ledgerhq/live-common 34.52.0-nightly.0 → 34.52.0-nightly.2

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 (76) 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/bridge/generic-alpaca/buildSubAccounts.d.ts +5 -8
  6. package/lib/bridge/generic-alpaca/buildSubAccounts.d.ts.map +1 -1
  7. package/lib/bridge/generic-alpaca/buildSubAccounts.js +37 -9
  8. package/lib/bridge/generic-alpaca/buildSubAccounts.js.map +1 -1
  9. package/lib/bridge/generic-alpaca/getAccountShape.d.ts.map +1 -1
  10. package/lib/bridge/generic-alpaca/getAccountShape.js +18 -17
  11. package/lib/bridge/generic-alpaca/getAccountShape.js.map +1 -1
  12. package/lib/bridge/generic-alpaca/types.d.ts +4 -1
  13. package/lib/bridge/generic-alpaca/types.d.ts.map +1 -1
  14. package/lib/bridge/generic-alpaca/utils.d.ts +2 -1
  15. package/lib/bridge/generic-alpaca/utils.d.ts.map +1 -1
  16. package/lib/bridge/generic-alpaca/utils.js +35 -3
  17. package/lib/bridge/generic-alpaca/utils.js.map +1 -1
  18. package/lib/e2e/data/deviceLabelsData.d.ts.map +1 -1
  19. package/lib/e2e/data/deviceLabelsData.js +3 -4
  20. package/lib/e2e/data/deviceLabelsData.js.map +1 -1
  21. package/lib/e2e/speculos.d.ts.map +1 -1
  22. package/lib/e2e/speculos.js +12 -14
  23. package/lib/e2e/speculos.js.map +1 -1
  24. package/lib/modularDrawer/__mocks__/currencies.mock.d.ts +3 -0
  25. package/lib/modularDrawer/__mocks__/currencies.mock.d.ts.map +1 -1
  26. package/lib/modularDrawer/__mocks__/currencies.mock.js +40 -1
  27. package/lib/modularDrawer/__mocks__/currencies.mock.js.map +1 -1
  28. package/lib/modularDrawer/utils/index.d.ts +3 -2
  29. package/lib/modularDrawer/utils/index.d.ts.map +1 -1
  30. package/lib/modularDrawer/utils/index.js +6 -10
  31. package/lib/modularDrawer/utils/index.js.map +1 -1
  32. package/lib-es/bridge/generic-alpaca/alpaca/network/network-alpaca.d.ts +2 -1
  33. package/lib-es/bridge/generic-alpaca/alpaca/network/network-alpaca.d.ts.map +1 -1
  34. package/lib-es/bridge/generic-alpaca/alpaca/network/network-alpaca.js +3 -0
  35. package/lib-es/bridge/generic-alpaca/alpaca/network/network-alpaca.js.map +1 -1
  36. package/lib-es/bridge/generic-alpaca/buildSubAccounts.d.ts +5 -8
  37. package/lib-es/bridge/generic-alpaca/buildSubAccounts.d.ts.map +1 -1
  38. package/lib-es/bridge/generic-alpaca/buildSubAccounts.js +35 -7
  39. package/lib-es/bridge/generic-alpaca/buildSubAccounts.js.map +1 -1
  40. package/lib-es/bridge/generic-alpaca/getAccountShape.d.ts.map +1 -1
  41. package/lib-es/bridge/generic-alpaca/getAccountShape.js +20 -19
  42. package/lib-es/bridge/generic-alpaca/getAccountShape.js.map +1 -1
  43. package/lib-es/bridge/generic-alpaca/types.d.ts +4 -1
  44. package/lib-es/bridge/generic-alpaca/types.d.ts.map +1 -1
  45. package/lib-es/bridge/generic-alpaca/utils.d.ts +2 -1
  46. package/lib-es/bridge/generic-alpaca/utils.d.ts.map +1 -1
  47. package/lib-es/bridge/generic-alpaca/utils.js +33 -2
  48. package/lib-es/bridge/generic-alpaca/utils.js.map +1 -1
  49. package/lib-es/e2e/data/deviceLabelsData.d.ts.map +1 -1
  50. package/lib-es/e2e/data/deviceLabelsData.js +3 -4
  51. package/lib-es/e2e/data/deviceLabelsData.js.map +1 -1
  52. package/lib-es/e2e/speculos.d.ts.map +1 -1
  53. package/lib-es/e2e/speculos.js +12 -14
  54. package/lib-es/e2e/speculos.js.map +1 -1
  55. package/lib-es/modularDrawer/__mocks__/currencies.mock.d.ts +3 -0
  56. package/lib-es/modularDrawer/__mocks__/currencies.mock.d.ts.map +1 -1
  57. package/lib-es/modularDrawer/__mocks__/currencies.mock.js +39 -0
  58. package/lib-es/modularDrawer/__mocks__/currencies.mock.js.map +1 -1
  59. package/lib-es/modularDrawer/utils/index.d.ts +3 -2
  60. package/lib-es/modularDrawer/utils/index.d.ts.map +1 -1
  61. package/lib-es/modularDrawer/utils/index.js +4 -9
  62. package/lib-es/modularDrawer/utils/index.js.map +1 -1
  63. package/package.json +38 -38
  64. package/src/bridge/generic-alpaca/alpaca/network/network-alpaca.ts +4 -0
  65. package/src/bridge/generic-alpaca/buildSubAccounts.test.ts +537 -0
  66. package/src/bridge/generic-alpaca/buildSubAccounts.ts +58 -21
  67. package/src/bridge/generic-alpaca/getAccountShape.ts +26 -23
  68. package/src/bridge/generic-alpaca/tests/getAccountShape.test.ts +10 -1
  69. package/src/bridge/generic-alpaca/types.ts +5 -1
  70. package/src/bridge/generic-alpaca/utils.test.ts +31 -1
  71. package/src/bridge/generic-alpaca/utils.ts +48 -4
  72. package/src/e2e/data/deviceLabelsData.ts +3 -4
  73. package/src/e2e/speculos.ts +12 -15
  74. package/src/modularDrawer/__mocks__/currencies.mock.ts +40 -0
  75. package/src/modularDrawer/utils/index.ts +6 -10
  76. package/src/modularDrawer/utils/index.test.ts +0 -43
@@ -3,10 +3,18 @@ import { GetAccountShape, mergeOps } from "@ledgerhq/coin-framework/bridge/jsHel
3
3
  import { encodeOperationId } from "@ledgerhq/coin-framework/operation";
4
4
  import BigNumber from "bignumber.js";
5
5
  import { getAlpacaApi } from "./alpaca";
6
- import { adaptCoreOperationToLiveOperation, extractBalance } from "./utils";
6
+ import { adaptCoreOperationToLiveOperation, cleanedOperation, extractBalance } from "./utils";
7
7
  import { inferSubOperations } from "@ledgerhq/coin-framework/serialization";
8
- import { buildSubAccounts, OperationCommon } from "./buildSubAccounts";
9
- import { Pagination } from "@ledgerhq/coin-framework/api/types";
8
+ import { buildSubAccounts, mergeSubAccounts } from "./buildSubAccounts";
9
+ import type { Operation, Pagination } from "@ledgerhq/coin-framework/api/types";
10
+ import type { OperationCommon } from "./types";
11
+
12
+ function isNftCoreOp(operation: Operation): boolean {
13
+ return (
14
+ typeof operation.details?.ledgerOpType === "string" &&
15
+ ["NFT_IN", "NFT_OUT"].includes(operation.details?.ledgerOpType)
16
+ );
17
+ }
10
18
 
11
19
  export function genericGetAccountShape(network: string, kind: string): GetAccountShape {
12
20
  return async (info, syncConfig) => {
@@ -56,39 +64,34 @@ export function genericGetAccountShape(network: string, kind: string): GetAccoun
56
64
  }
57
65
 
58
66
  const [newCoreOps] = await alpacaApi.listOperations(address, paginationParams);
59
- const newOps = newCoreOps.map(op =>
60
- adaptCoreOperationToLiveOperation(accountId, op),
61
- ) as OperationCommon[];
62
- const mergedOps = mergeOps(oldOps, newOps) as OperationCommon[];
67
+ const newOps = newCoreOps
68
+ .filter(op => !isNftCoreOp(op))
69
+ .map(op => adaptCoreOperationToLiveOperation(accountId, op)) as OperationCommon[];
63
70
 
64
- const assetOperations: OperationCommon[] = [];
65
- mergedOps.forEach(operation => {
66
- if (
71
+ const newAssetOperations = newOps.filter(
72
+ operation =>
67
73
  operation?.extra?.assetReference &&
68
74
  operation?.extra?.assetOwner &&
69
- !["OPT_IN", "OPT_OUT"].includes(operation.type)
70
- ) {
71
- assetOperations.push(operation);
72
- }
73
- });
74
-
75
- const subAccounts = await buildSubAccounts({
76
- currency,
75
+ !["OPT_IN", "OPT_OUT"].includes(operation.type),
76
+ );
77
+ const newSubAccounts = await buildSubAccounts({
77
78
  accountId,
78
79
  allTokenAssetsBalances,
79
80
  syncConfig,
80
- operations: assetOperations,
81
+ operations: newAssetOperations,
81
82
  getTokenFromAsset: alpacaApi.getTokenFromAsset,
82
83
  });
84
+ const subAccounts = mergeSubAccounts(initialAccount?.subAccounts ?? [], newSubAccounts);
83
85
 
84
- const operations = mergedOps.map(op => {
85
- const subOperations = inferSubOperations(op.hash, subAccounts);
86
+ const newOpsWithSubs = newOps.map(op => {
87
+ const subOperations = inferSubOperations(op.hash, newSubAccounts);
86
88
 
87
- return {
89
+ return cleanedOperation({
88
90
  ...op,
89
91
  subOperations,
90
- };
92
+ });
91
93
  });
94
+ const operations = mergeOps(oldOps, newOpsWithSubs) as OperationCommon[];
92
95
 
93
96
  const res = {
94
97
  id: accountId,
@@ -29,9 +29,11 @@ jest.mock("../alpaca", () => ({
29
29
 
30
30
  const adaptCoreOperationToLiveOperationMock = jest.fn();
31
31
  const extractBalanceMock = jest.fn();
32
+ const cleanedOperationMock = jest.fn();
32
33
  jest.mock("../utils", () => ({
33
34
  adaptCoreOperationToLiveOperation: (...a: any[]) => adaptCoreOperationToLiveOperationMock(...a),
34
35
  extractBalance: (...a: any[]) => extractBalanceMock(...a),
36
+ cleanedOperation: (...a: any[]) => cleanedOperationMock(...a),
35
37
  }));
36
38
 
37
39
  const inferSubOperationsMock = jest.fn();
@@ -40,8 +42,10 @@ jest.mock("@ledgerhq/coin-framework/serialization", () => ({
40
42
  }));
41
43
 
42
44
  const buildSubAccountsMock = jest.fn();
45
+ const mergeSubAccountsMock = jest.fn();
43
46
  jest.mock("../buildSubAccounts", () => ({
44
47
  buildSubAccounts: (...a: any[]) => buildSubAccountsMock(...a),
48
+ mergeSubAccounts: (...a: any[]) => mergeSubAccountsMock(...a),
45
49
  }));
46
50
 
47
51
  // Test matrix for Stellar & XRP
@@ -51,7 +55,7 @@ const chains = [
51
55
  { currency: { id: "tezos", name: "Tezos" }, network: "mainnet" },
52
56
  ];
53
57
 
54
- describe("genericGetAccountShape (stellar & xrp)", () => {
58
+ describe("genericGetAccountShape", () => {
55
59
  beforeEach(() => {
56
60
  jest.clearAllMocks();
57
61
  });
@@ -88,6 +92,11 @@ describe("genericGetAccountShape (stellar & xrp)", () => {
88
92
  }));
89
93
 
90
94
  mergeOpsMock.mockImplementation((oldOps, newOps) => [...newOps, ...oldOps]);
95
+ cleanedOperationMock.mockImplementation(operation => operation);
96
+ mergeSubAccountsMock.mockImplementation((oldSubAccounts, newSubAccounts) => [
97
+ ...newSubAccounts,
98
+ ...oldSubAccounts,
99
+ ]);
91
100
 
92
101
  buildSubAccountsMock.mockReturnValue([
93
102
  { id: `${currency.id}_subAcc1`, type: "TokenAccount" },
@@ -1,4 +1,4 @@
1
- import { TransactionCommon } from "@ledgerhq/types-live";
1
+ import type { Operation, TransactionCommon } from "@ledgerhq/types-live";
2
2
  import BigNumber from "bignumber.js";
3
3
  import type { Unit } from "@ledgerhq/types-cryptoassets";
4
4
 
@@ -32,3 +32,7 @@ export type GenericTransaction = TransactionCommon & {
32
32
  assetOwner?: string;
33
33
  networkInfo?: NetworkInfo | null;
34
34
  };
35
+
36
+ export interface OperationCommon extends Operation {
37
+ extra: Record<string, any>;
38
+ }
@@ -1,5 +1,6 @@
1
1
  import {
2
2
  adaptCoreOperationToLiveOperation,
3
+ cleanedOperation,
3
4
  extractBalance,
4
5
  findCryptoCurrencyByNetwork,
5
6
  transactionToIntent,
@@ -7,9 +8,38 @@ import {
7
8
  import BigNumber from "bignumber.js";
8
9
  import { Operation as CoreOperation } from "@ledgerhq/coin-framework/api/types";
9
10
  import { Account } from "@ledgerhq/types-live";
10
- import { GenericTransaction } from "./types";
11
+ import { GenericTransaction, OperationCommon } from "./types";
11
12
 
12
13
  describe("Alpaca utils", () => {
14
+ describe("cleanedOperation", () => {
15
+ it("creates a cleaned version of an operation without mutating it", () => {
16
+ const dirty = {
17
+ id: "id",
18
+ hash: "hash",
19
+ senders: ["sender"],
20
+ recipients: ["recipient"],
21
+ extra: { assetAmount: 5, assetReference: "USDC", paginationToken: "pagination" },
22
+ } as unknown as OperationCommon;
23
+
24
+ const clean = cleanedOperation(dirty);
25
+
26
+ expect(clean).toEqual({
27
+ id: "id",
28
+ hash: "hash",
29
+ senders: ["sender"],
30
+ recipients: ["recipient"],
31
+ extra: { paginationToken: "pagination" },
32
+ });
33
+ expect(dirty).toEqual({
34
+ id: "id",
35
+ hash: "hash",
36
+ senders: ["sender"],
37
+ recipients: ["recipient"],
38
+ extra: { assetAmount: 5, assetReference: "USDC", paginationToken: "pagination" },
39
+ });
40
+ });
41
+ });
42
+
13
43
  describe("transactionToIntent", () => {
14
44
  describe("type", () => {
15
45
  it("fallbacks to 'Payment' without a transaction mode", () => {
@@ -9,7 +9,7 @@ import {
9
9
  } from "@ledgerhq/coin-framework/api/types";
10
10
  import { findCryptoCurrencyById } from "@ledgerhq/cryptoassets/currencies";
11
11
  import { CryptoCurrency } from "@ledgerhq/types-cryptoassets";
12
- import { GenericTransaction } from "./types";
12
+ import { GenericTransaction, OperationCommon } from "./types";
13
13
 
14
14
  export function findCryptoCurrencyByNetwork(network: string): CryptoCurrency | undefined {
15
15
  const networksRemap = {
@@ -27,6 +27,30 @@ export function extractBalance(balances: Balance[], type: string): Balance {
27
27
  );
28
28
  }
29
29
 
30
+ function isStringArray(value: unknown): value is string[] {
31
+ return Array.isArray(value) && value.every(item => typeof item === "string");
32
+ }
33
+
34
+ export function cleanedOperation(operation: OperationCommon): OperationCommon {
35
+ if (!operation.extra) return operation;
36
+
37
+ const extraToClean = new Set([
38
+ "assetReference",
39
+ "assetAmount",
40
+ "assetOwner",
41
+ "assetSenders",
42
+ "assetRecipients",
43
+ "parentSenders",
44
+ "parentRecipients",
45
+ "ledgerOpType",
46
+ ]);
47
+ const cleanedExtra = Object.fromEntries(
48
+ Object.entries(operation.extra).filter(([key]) => !extraToClean.has(key)),
49
+ );
50
+
51
+ return { ...operation, extra: cleanedExtra };
52
+ }
53
+
30
54
  export function adaptCoreOperationToLiveOperation(accountId: string, op: CoreOperation): Operation {
31
55
  const opType = op.type as OperationType;
32
56
 
@@ -34,6 +58,10 @@ export function adaptCoreOperationToLiveOperation(accountId: string, op: CoreOpe
34
58
  assetReference?: string;
35
59
  assetOwner?: string;
36
60
  assetAmount?: string | undefined;
61
+ assetSenders?: string[];
62
+ assetRecipients?: string[];
63
+ parentSenders?: string[];
64
+ parentRecipients?: string[];
37
65
  ledgerOpType?: string | undefined;
38
66
  memo?: string | undefined;
39
67
  } = {};
@@ -46,6 +74,22 @@ export function adaptCoreOperationToLiveOperation(accountId: string, op: CoreOpe
46
74
  extra.assetAmount = op.details.assetAmount as string;
47
75
  }
48
76
 
77
+ if (isStringArray(op.details?.assetSenders)) {
78
+ extra.assetSenders = op.details?.assetSenders;
79
+ }
80
+
81
+ if (isStringArray(op.details?.assetRecipients)) {
82
+ extra.assetRecipients = op.details?.assetRecipients;
83
+ }
84
+
85
+ if (isStringArray(op.details?.parentSenders)) {
86
+ extra.parentSenders = op.details?.parentSenders;
87
+ }
88
+
89
+ if (isStringArray(op.details?.parentRecipients)) {
90
+ extra.parentRecipients = op.details?.parentRecipients;
91
+ }
92
+
49
93
  if (op.asset?.type !== "native") {
50
94
  extra.assetReference =
51
95
  "assetReference" in (op.asset ?? {}) ? (op.asset as any).assetReference : "";
@@ -67,11 +111,11 @@ export function adaptCoreOperationToLiveOperation(accountId: string, op: CoreOpe
67
111
  fee: bnFees,
68
112
  blockHash: op.tx.block.hash,
69
113
  blockHeight: op.tx.block.height,
70
- senders: op.senders,
71
- recipients: op.recipients,
114
+ senders: extra.parentSenders ?? op.senders,
115
+ recipients: extra.parentRecipients ?? op.recipients,
72
116
  date: op.tx.date,
73
117
  transactionSequenceNumber: op.details?.sequence as number,
74
- hasFailed: (op.details as unknown as { status?: string })?.status === "failed",
118
+ hasFailed: op.details?.status === "failed",
75
119
  extra,
76
120
  };
77
121
 
@@ -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
  },
@@ -723,26 +723,23 @@ export function getDeviceLabels(appInfo: AppInfos): DeviceLabelsReturn {
723
723
  export async function expectValidAddressDevice(account: Account, addressDisplayed: string) {
724
724
  if (account.currency === Currency.SUI_USDC) {
725
725
  providePublicKey();
726
+ }
727
+ const { receiveVerifyLabel, receiveConfirmLabel } = getDeviceLabels(account.currency.speculosApp);
728
+ await waitFor(receiveVerifyLabel);
729
+ if (isTouchDevice()) {
730
+ const events = await pressUntilTextFound(receiveConfirmLabel);
731
+ const isAddressCorrect = containsSubstringInEvent(addressDisplayed, events);
732
+ expect(isAddressCorrect).toBeTruthy();
733
+ await pressAndRelease(DeviceLabels.CONFIRM);
726
734
  } else {
727
735
  const { receiveVerifyLabel, receiveConfirmLabel } = getDeviceLabels(
728
736
  account.currency.speculosApp,
729
737
  );
730
738
  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
- }
739
+ const events = await pressUntilTextFound(receiveConfirmLabel);
740
+ const isAddressCorrect = containsSubstringInEvent(addressDisplayed, events);
741
+ expect(isAddressCorrect).toBeTruthy();
742
+ await pressBoth();
746
743
  }
747
744
  }
748
745
 
@@ -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 };
@@ -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
- });