@ledgerhq/live-common 34.39.0-nightly.0 → 34.39.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 (118) hide show
  1. package/lib/bridge/cache.d.ts.map +1 -1
  2. package/lib/bridge/cache.js +2 -2
  3. package/lib/bridge/cache.js.map +1 -1
  4. package/lib/bridge/cache.test.d.ts +2 -0
  5. package/lib/bridge/cache.test.d.ts.map +1 -0
  6. package/lib/bridge/cache.test.js +63 -0
  7. package/lib/bridge/cache.test.js.map +1 -0
  8. package/lib/e2e/index.d.ts +3 -0
  9. package/lib/e2e/index.d.ts.map +1 -1
  10. package/lib/env.react.d.ts +1 -1
  11. package/lib/env.react.d.ts.map +1 -1
  12. package/lib/featureFlags/defaultFeatures.d.ts.map +1 -1
  13. package/lib/featureFlags/defaultFeatures.js +11 -0
  14. package/lib/featureFlags/defaultFeatures.js.map +1 -1
  15. package/lib/featureFlags/useFeature.d.ts +1 -1
  16. package/lib/featureFlags/useFeature.d.ts.map +1 -1
  17. package/lib/hooks/useAppVersionBlockCheck.d.ts +11 -0
  18. package/lib/hooks/useAppVersionBlockCheck.d.ts.map +1 -0
  19. package/lib/hooks/useAppVersionBlockCheck.js +32 -0
  20. package/lib/hooks/useAppVersionBlockCheck.js.map +1 -0
  21. package/lib/hooks/useAppVersionBlockCheck.test.d.ts +2 -0
  22. package/lib/hooks/useAppVersionBlockCheck.test.d.ts.map +1 -0
  23. package/lib/hooks/useAppVersionBlockCheck.test.js +133 -0
  24. package/lib/hooks/useAppVersionBlockCheck.test.js.map +1 -0
  25. package/lib/hw/connectAppEventMapper.d.ts.map +1 -1
  26. package/lib/hw/connectAppEventMapper.js +3 -1
  27. package/lib/hw/connectAppEventMapper.js.map +1 -1
  28. package/lib/modularDrawer/__test__/useModularDrawerVisibility.test.d.ts +2 -0
  29. package/lib/modularDrawer/__test__/useModularDrawerVisibility.test.d.ts.map +1 -0
  30. package/lib/modularDrawer/__test__/useModularDrawerVisibility.test.js +107 -0
  31. package/lib/modularDrawer/__test__/useModularDrawerVisibility.test.js.map +1 -0
  32. package/lib/modularDrawer/enums.d.ts +8 -0
  33. package/lib/modularDrawer/enums.d.ts.map +1 -0
  34. package/lib/modularDrawer/enums.js +12 -0
  35. package/lib/modularDrawer/enums.js.map +1 -0
  36. package/lib/modularDrawer/useModularDrawerVisibility.d.ts +9 -0
  37. package/lib/modularDrawer/useModularDrawerVisibility.d.ts.map +1 -0
  38. package/lib/modularDrawer/useModularDrawerVisibility.js +18 -0
  39. package/lib/modularDrawer/useModularDrawerVisibility.js.map +1 -0
  40. package/lib/wallet-api/types.d.ts +1 -1
  41. package/lib/wallet-api/types.d.ts.map +1 -1
  42. package/lib/wallet-api/useDappLogic.d.ts.map +1 -1
  43. package/lib/wallet-api/useDappLogic.js +3 -24
  44. package/lib/wallet-api/useDappLogic.js.map +1 -1
  45. package/lib/wallet-api/utils/txTrackingHelper.d.ts +3 -0
  46. package/lib/wallet-api/utils/txTrackingHelper.d.ts.map +1 -0
  47. package/lib/wallet-api/utils/txTrackingHelper.js +16 -0
  48. package/lib/wallet-api/utils/txTrackingHelper.js.map +1 -0
  49. package/lib/wallet-api/utils/txTrackingHelper.test.d.ts +2 -0
  50. package/lib/wallet-api/utils/txTrackingHelper.test.d.ts.map +1 -0
  51. package/lib/wallet-api/utils/txTrackingHelper.test.js +70 -0
  52. package/lib/wallet-api/utils/txTrackingHelper.test.js.map +1 -0
  53. package/lib-es/bridge/cache.d.ts.map +1 -1
  54. package/lib-es/bridge/cache.js +2 -2
  55. package/lib-es/bridge/cache.js.map +1 -1
  56. package/lib-es/bridge/cache.test.d.ts +2 -0
  57. package/lib-es/bridge/cache.test.d.ts.map +1 -0
  58. package/lib-es/bridge/cache.test.js +38 -0
  59. package/lib-es/bridge/cache.test.js.map +1 -0
  60. package/lib-es/e2e/index.d.ts +3 -0
  61. package/lib-es/e2e/index.d.ts.map +1 -1
  62. package/lib-es/env.react.d.ts +1 -1
  63. package/lib-es/env.react.d.ts.map +1 -1
  64. package/lib-es/featureFlags/defaultFeatures.d.ts.map +1 -1
  65. package/lib-es/featureFlags/defaultFeatures.js +11 -0
  66. package/lib-es/featureFlags/defaultFeatures.js.map +1 -1
  67. package/lib-es/featureFlags/useFeature.d.ts +1 -1
  68. package/lib-es/featureFlags/useFeature.d.ts.map +1 -1
  69. package/lib-es/hooks/useAppVersionBlockCheck.d.ts +11 -0
  70. package/lib-es/hooks/useAppVersionBlockCheck.d.ts.map +1 -0
  71. package/lib-es/hooks/useAppVersionBlockCheck.js +25 -0
  72. package/lib-es/hooks/useAppVersionBlockCheck.js.map +1 -0
  73. package/lib-es/hooks/useAppVersionBlockCheck.test.d.ts +2 -0
  74. package/lib-es/hooks/useAppVersionBlockCheck.test.d.ts.map +1 -0
  75. package/lib-es/hooks/useAppVersionBlockCheck.test.js +131 -0
  76. package/lib-es/hooks/useAppVersionBlockCheck.test.js.map +1 -0
  77. package/lib-es/hw/connectAppEventMapper.d.ts.map +1 -1
  78. package/lib-es/hw/connectAppEventMapper.js +3 -1
  79. package/lib-es/hw/connectAppEventMapper.js.map +1 -1
  80. package/lib-es/modularDrawer/__test__/useModularDrawerVisibility.test.d.ts +2 -0
  81. package/lib-es/modularDrawer/__test__/useModularDrawerVisibility.test.d.ts.map +1 -0
  82. package/lib-es/modularDrawer/__test__/useModularDrawerVisibility.test.js +105 -0
  83. package/lib-es/modularDrawer/__test__/useModularDrawerVisibility.test.js.map +1 -0
  84. package/lib-es/modularDrawer/enums.d.ts +8 -0
  85. package/lib-es/modularDrawer/enums.d.ts.map +1 -0
  86. package/lib-es/modularDrawer/enums.js +9 -0
  87. package/lib-es/modularDrawer/enums.js.map +1 -0
  88. package/lib-es/modularDrawer/useModularDrawerVisibility.d.ts +9 -0
  89. package/lib-es/modularDrawer/useModularDrawerVisibility.d.ts.map +1 -0
  90. package/lib-es/modularDrawer/useModularDrawerVisibility.js +14 -0
  91. package/lib-es/modularDrawer/useModularDrawerVisibility.js.map +1 -0
  92. package/lib-es/wallet-api/types.d.ts +1 -1
  93. package/lib-es/wallet-api/types.d.ts.map +1 -1
  94. package/lib-es/wallet-api/useDappLogic.d.ts.map +1 -1
  95. package/lib-es/wallet-api/useDappLogic.js +3 -24
  96. package/lib-es/wallet-api/useDappLogic.js.map +1 -1
  97. package/lib-es/wallet-api/utils/txTrackingHelper.d.ts +3 -0
  98. package/lib-es/wallet-api/utils/txTrackingHelper.d.ts.map +1 -0
  99. package/lib-es/wallet-api/utils/txTrackingHelper.js +12 -0
  100. package/lib-es/wallet-api/utils/txTrackingHelper.js.map +1 -0
  101. package/lib-es/wallet-api/utils/txTrackingHelper.test.d.ts +2 -0
  102. package/lib-es/wallet-api/utils/txTrackingHelper.test.d.ts.map +1 -0
  103. package/lib-es/wallet-api/utils/txTrackingHelper.test.js +68 -0
  104. package/lib-es/wallet-api/utils/txTrackingHelper.test.js.map +1 -0
  105. package/package.json +46 -46
  106. package/src/bridge/cache.test.ts +46 -0
  107. package/src/bridge/cache.ts +5 -2
  108. package/src/featureFlags/defaultFeatures.ts +11 -0
  109. package/src/hooks/useAppVersionBlockCheck.test.ts +134 -0
  110. package/src/hooks/useAppVersionBlockCheck.ts +65 -0
  111. package/src/hw/connectAppEventMapper.ts +3 -1
  112. package/src/modularDrawer/__test__/useModularDrawerVisibility.test.ts +149 -0
  113. package/src/modularDrawer/enums.ts +7 -0
  114. package/src/modularDrawer/useModularDrawerVisibility.ts +25 -0
  115. package/src/wallet-api/types.ts +1 -1
  116. package/src/wallet-api/useDappLogic.ts +4 -27
  117. package/src/wallet-api/utils/txTrackingHelper.test.ts +80 -0
  118. package/src/wallet-api/utils/txTrackingHelper.ts +14 -0
@@ -0,0 +1,65 @@
1
+ import semver from "semver";
2
+ import { LiveConfig } from "@ledgerhq/live-config/LiveConfig";
3
+
4
+ type LLMMinVersionConfig = {
5
+ minOsVersion: string;
6
+ version: string;
7
+ };
8
+
9
+ type LLMinVersionConfig = {
10
+ lld: {
11
+ windows: string;
12
+ macOS: string;
13
+ linux: string;
14
+ };
15
+ llm: {
16
+ android: LLMMinVersionConfig[];
17
+ ios: LLMMinVersionConfig[];
18
+ };
19
+ };
20
+
21
+ const checkLLmVersion = (
22
+ appVersion: string,
23
+ osVersion: string,
24
+ platform: "ios" | "android",
25
+ llmMinVersionConfig: LLMinVersionConfig["llm"],
26
+ ) => {
27
+ if (!llmMinVersionConfig[platform]) {
28
+ return false;
29
+ }
30
+
31
+ return llmMinVersionConfig[platform]
32
+ .filter(minVersionConfig =>
33
+ semver.satisfies(semver.coerce(osVersion), `>=${minVersionConfig.minOsVersion}`),
34
+ )
35
+ .reduce((acc, curr) => {
36
+ return acc || semver.satisfies(appVersion, `<${curr.version}`);
37
+ }, false);
38
+ };
39
+
40
+ export const useAppVersionBlockCheck = ({
41
+ appVersion: uncoercedAppVersion,
42
+ appKey,
43
+ platform,
44
+ osVersion,
45
+ getConfigValue = LiveConfig.getValueByKey,
46
+ }: {
47
+ appVersion: string;
48
+ osVersion?: string;
49
+ appKey: "llm" | "lld";
50
+ platform: "ios" | "android" | "macOS" | "windows" | "linux";
51
+ getConfigValue?: typeof LiveConfig.getValueByKey;
52
+ }) => {
53
+ const llMinVersionConfig = getConfigValue("config_ll_min_version");
54
+ const appVersion = semver.coerce(uncoercedAppVersion)?.version || "";
55
+ let shouldUpdate = false;
56
+
57
+ if (!llMinVersionConfig) {
58
+ return { shouldUpdate };
59
+ }
60
+
61
+ if (appKey === "llm" && (platform === "android" || platform === "ios") && osVersion) {
62
+ shouldUpdate = checkLLmVersion(appVersion, osVersion, platform, llMinVersionConfig[appKey]);
63
+ }
64
+ return { shouldUpdate };
65
+ };
@@ -203,7 +203,9 @@ export class ConnectAppEventMapper {
203
203
  type: "install",
204
204
  name: installPlan.installPlan[installPlan.currentIndex]!.versionName,
205
205
  },
206
- installQueue: installPlan.installPlan.map(app => app.versionName),
206
+ installQueue: installPlan.installPlan
207
+ .map(app => app.versionName)
208
+ .slice(installPlan.currentIndex),
207
209
  });
208
210
  this.installPlan = installPlan;
209
211
  }
@@ -0,0 +1,149 @@
1
+ /**
2
+ * @jest-environment jsdom
3
+ */
4
+ import { renderHook } from "@testing-library/react";
5
+ import { useModularDrawerVisibility } from "../useModularDrawerVisibility";
6
+ import { ModularDrawerLocation } from "../enums";
7
+ import {
8
+ makeMockedFeatureFlagsProviderWrapper,
9
+ makeMockedContextValue,
10
+ } from "../../featureFlags/mock";
11
+
12
+ describe("useModularDrawerVisibility", () => {
13
+ describe("lldModularDrawer", () => {
14
+ it("should return false if the feature flag is not enabled", () => {
15
+ const mockedFeatures = {
16
+ lldModularDrawer: {
17
+ enabled: false,
18
+ params: { [ModularDrawerLocation.ADD_ACCOUNT]: true },
19
+ },
20
+ };
21
+
22
+ const { result } = renderHook(
23
+ () =>
24
+ useModularDrawerVisibility({
25
+ modularDrawerFeatureFlagKey: "lldModularDrawer",
26
+ }),
27
+ {
28
+ wrapper: makeMockedFeatureFlagsProviderWrapper(makeMockedContextValue(mockedFeatures)),
29
+ },
30
+ );
31
+
32
+ expect(result.current.isModularDrawerVisible(ModularDrawerLocation.ADD_ACCOUNT)).toBe(false);
33
+ });
34
+
35
+ it("should return false if the location param is not set", () => {
36
+ const mockedFeatures = {
37
+ lldModularDrawer: { enabled: true, params: {} },
38
+ };
39
+
40
+ const { result } = renderHook(
41
+ () =>
42
+ useModularDrawerVisibility({
43
+ modularDrawerFeatureFlagKey: "lldModularDrawer",
44
+ }),
45
+ {
46
+ wrapper: makeMockedFeatureFlagsProviderWrapper(makeMockedContextValue(mockedFeatures)),
47
+ },
48
+ );
49
+
50
+ expect(result.current.isModularDrawerVisible(ModularDrawerLocation.ADD_ACCOUNT)).toBe(false);
51
+ });
52
+
53
+ it("should return the correct visibility for each location", () => {
54
+ const mockedFeatures = {
55
+ lldModularDrawer: {
56
+ enabled: true,
57
+ params: {
58
+ [ModularDrawerLocation.ADD_ACCOUNT]: true,
59
+ [ModularDrawerLocation.EARN_FLOW]: false,
60
+ },
61
+ },
62
+ };
63
+
64
+ const { result } = renderHook(
65
+ () =>
66
+ useModularDrawerVisibility({
67
+ modularDrawerFeatureFlagKey: "lldModularDrawer",
68
+ }),
69
+ {
70
+ wrapper: makeMockedFeatureFlagsProviderWrapper(makeMockedContextValue(mockedFeatures)),
71
+ },
72
+ );
73
+
74
+ expect(result.current.isModularDrawerVisible(ModularDrawerLocation.ADD_ACCOUNT)).toBe(true);
75
+ expect(result.current.isModularDrawerVisible(ModularDrawerLocation.EARN_FLOW)).toBe(false);
76
+ expect(result.current.isModularDrawerVisible(ModularDrawerLocation.LIVE_APP)).toBe(false);
77
+ });
78
+ });
79
+
80
+ describe("llmModularDrawer", () => {
81
+ it("should return false if the feature flag is not enabled", () => {
82
+ const mockedFeatures = {
83
+ llmModularDrawer: {
84
+ enabled: false,
85
+ params: { [ModularDrawerLocation.ADD_ACCOUNT]: true },
86
+ },
87
+ };
88
+
89
+ const { result } = renderHook(
90
+ () =>
91
+ useModularDrawerVisibility({
92
+ modularDrawerFeatureFlagKey: "llmModularDrawer",
93
+ }),
94
+ {
95
+ wrapper: makeMockedFeatureFlagsProviderWrapper(makeMockedContextValue(mockedFeatures)),
96
+ },
97
+ );
98
+
99
+ expect(result.current.isModularDrawerVisible(ModularDrawerLocation.ADD_ACCOUNT)).toBe(false);
100
+ });
101
+
102
+ it("should return false if the location param is not set", () => {
103
+ const mockedFeatures = {
104
+ llmModularDrawer: { enabled: true, params: {} },
105
+ };
106
+
107
+ const { result } = renderHook(
108
+ () =>
109
+ useModularDrawerVisibility({
110
+ modularDrawerFeatureFlagKey: "llmModularDrawer",
111
+ }),
112
+ {
113
+ wrapper: makeMockedFeatureFlagsProviderWrapper(makeMockedContextValue(mockedFeatures)),
114
+ },
115
+ );
116
+
117
+ expect(result.current.isModularDrawerVisible(ModularDrawerLocation.ADD_ACCOUNT)).toBe(false);
118
+ });
119
+
120
+ it("should return the correct visibility for each location", () => {
121
+ const mockedFeatures = {
122
+ llmModularDrawer: {
123
+ enabled: true,
124
+ params: {
125
+ [ModularDrawerLocation.ADD_ACCOUNT]: false,
126
+ [ModularDrawerLocation.EARN_FLOW]: true,
127
+ [ModularDrawerLocation.RECEIVE_FLOW]: true,
128
+ },
129
+ },
130
+ };
131
+
132
+ const { result } = renderHook(
133
+ () =>
134
+ useModularDrawerVisibility({
135
+ modularDrawerFeatureFlagKey: "llmModularDrawer",
136
+ }),
137
+ {
138
+ wrapper: makeMockedFeatureFlagsProviderWrapper(makeMockedContextValue(mockedFeatures)),
139
+ },
140
+ );
141
+
142
+ expect(result.current.isModularDrawerVisible(ModularDrawerLocation.ADD_ACCOUNT)).toBe(false);
143
+ expect(result.current.isModularDrawerVisible(ModularDrawerLocation.EARN_FLOW)).toBe(true);
144
+ expect(result.current.isModularDrawerVisible(ModularDrawerLocation.RECEIVE_FLOW)).toBe(true);
145
+ expect(result.current.isModularDrawerVisible(ModularDrawerLocation.LIVE_APP)).toBe(false);
146
+ expect(result.current.isModularDrawerVisible(ModularDrawerLocation.SEND_FLOW)).toBe(false);
147
+ });
148
+ });
149
+ });
@@ -0,0 +1,7 @@
1
+ export enum ModularDrawerLocation {
2
+ ADD_ACCOUNT = "add_account",
3
+ EARN_FLOW = "earn_flow",
4
+ LIVE_APP = "live_app",
5
+ RECEIVE_FLOW = "receive_flow",
6
+ SEND_FLOW = "send_flow",
7
+ }
@@ -0,0 +1,25 @@
1
+ import { useCallback } from "react";
2
+ import { useFeature } from "../featureFlags";
3
+ import { ModularDrawerLocation } from "./enums";
4
+
5
+ type ModularDrawerFeatureFlagKey = "lldModularDrawer" | "llmModularDrawer";
6
+
7
+ export function useModularDrawerVisibility({
8
+ modularDrawerFeatureFlagKey,
9
+ }: {
10
+ modularDrawerFeatureFlagKey: ModularDrawerFeatureFlagKey;
11
+ }) {
12
+ const featureModularDrawer = useFeature(modularDrawerFeatureFlagKey);
13
+
14
+ const isModularDrawerVisible = useCallback(
15
+ (location: ModularDrawerLocation) => {
16
+ if (!featureModularDrawer?.enabled) return false;
17
+ return featureModularDrawer.params?.[location] ?? false;
18
+ },
19
+ [featureModularDrawer],
20
+ );
21
+
22
+ return {
23
+ isModularDrawerVisible,
24
+ };
25
+ }
@@ -79,7 +79,7 @@ export type RecentlyUsedIdDb = {
79
79
  export type CurrentAccountHistIDb = Record<string, string>;
80
80
 
81
81
  export type DAppTrackingData = {
82
- type: "approve" | "transfer";
82
+ type: string;
83
83
  currency: string;
84
84
  network: CryptoCurrency["id"];
85
85
  };
@@ -15,8 +15,8 @@ import BigNumber from "bignumber.js";
15
15
  import { safeEncodeEIP55 } from "@ledgerhq/coin-evm/logic";
16
16
  import { SmartWebsocket } from "./SmartWebsocket";
17
17
  import { stripHexPrefix } from "./helpers";
18
- import { DeviceTransactionField, getDeviceTransactionConfig } from "../transaction";
19
- import type { Transaction } from "../generated/types";
18
+ import { getTxType } from "./utils/txTrackingHelper";
19
+ import { Transaction as EvmTransaction } from "@ledgerhq/coin-evm/types/transaction";
20
20
 
21
21
  type MessageId = number | string | null;
22
22
 
@@ -205,16 +205,6 @@ function isParentAccountPresent(
205
205
  return true;
206
206
  }
207
207
 
208
- function getTransactionType(fields: Array<DeviceTransactionField>): string {
209
- for (let i = 0; i < fields.length; i++) {
210
- const field = fields[i];
211
- if (field.type === "text" && field.label === "Type") {
212
- return field.value;
213
- }
214
- }
215
- return "";
216
- }
217
-
218
208
  export function useDappLogic({
219
209
  manifest,
220
210
  accounts,
@@ -490,20 +480,7 @@ export function useDappLogic({
490
480
  account: currentAccount,
491
481
  });
492
482
 
493
- const fields = getDeviceTransactionConfig({
494
- account: currentAccount,
495
- parentAccount: currentParentAccount,
496
- transaction: signFlowInfos.liveTx as Transaction,
497
- status: {
498
- errors: {},
499
- warnings: {},
500
- estimatedFees: new BigNumber(0),
501
- amount: new BigNumber(0),
502
- totalSpent: new BigNumber(0),
503
- },
504
- });
505
-
506
- const transactionType = getTransactionType(fields);
483
+ const transactionType = getTxType(signFlowInfos.liveTx as EvmTransaction);
507
484
 
508
485
  const token = findTokenByAddress(tx.recipient);
509
486
 
@@ -518,7 +495,7 @@ export function useDappLogic({
518
495
  : currentAccount.currency.id;
519
496
 
520
497
  trackingData = {
521
- type: transactionType === "Approve" ? "approve" : "transfer",
498
+ type: transactionType,
522
499
  currency: token ? token.name : accountCurrencyName,
523
500
  network: token ? token.parentCurrency.id : accountNetwork,
524
501
  };
@@ -0,0 +1,80 @@
1
+ import { getTxType } from "./txTrackingHelper";
2
+ import { ERC20_CLEAR_SIGNED_SELECTORS, DAPP_SELECTORS } from "@ledgerhq/hw-app-eth";
3
+ import { Transaction as EvmTransaction } from "@ledgerhq/coin-evm/types/transaction";
4
+
5
+ const createMockTransaction = (selector: string): EvmTransaction =>
6
+ ({
7
+ data: Buffer.from(selector.slice(2) + "0".repeat(128), "hex"),
8
+ recipient: "0x1234567890123456789012345678901234567890",
9
+ amount: "0",
10
+ gasPrice: "0",
11
+ gasLimit: "21000",
12
+ nonce: 0,
13
+ }) as unknown as EvmTransaction;
14
+
15
+ describe("getTxType", () => {
16
+ describe("ERC20 transactions", () => {
17
+ it("should return 'transfer' for ERC20 transfer selector", () => {
18
+ const tx = createMockTransaction(ERC20_CLEAR_SIGNED_SELECTORS.TRANSFER);
19
+ const result = getTxType(tx);
20
+ expect(result).toBe("transfer");
21
+ });
22
+
23
+ it("should return 'approve' for ERC20 approve selector", () => {
24
+ const tx = createMockTransaction(ERC20_CLEAR_SIGNED_SELECTORS.APPROVE);
25
+ const result = getTxType(tx);
26
+ expect(result).toBe("approve");
27
+ });
28
+ });
29
+
30
+ describe("DAPP transactions", () => {
31
+ it("should return the DAPP selector value for known DAPP transactions", () => {
32
+ const dappSelectors = Object.keys(DAPP_SELECTORS);
33
+ if (dappSelectors.length > 0) {
34
+ const firstSelector = dappSelectors[0];
35
+ const expectedValue = DAPP_SELECTORS[firstSelector];
36
+
37
+ const tx = createMockTransaction(firstSelector);
38
+ const result = getTxType(tx);
39
+ expect(result).toBe(expectedValue);
40
+ }
41
+ });
42
+ });
43
+
44
+ describe("Unknown transactions", () => {
45
+ it("should return 'transfer' for unknown selectors", () => {
46
+ const tx = createMockTransaction("0x12345678");
47
+ const result = getTxType(tx);
48
+ expect(result).toBe("transfer");
49
+ });
50
+
51
+ it("should return 'transfer' for transactions without data", () => {
52
+ const tx = {
53
+ data: undefined,
54
+ } as EvmTransaction;
55
+ const result = getTxType(tx);
56
+ expect(result).toBe("transfer");
57
+ });
58
+
59
+ it("should return 'transfer' for transactions with empty data", () => {
60
+ const tx = {
61
+ data: Buffer.alloc(0),
62
+ } as EvmTransaction;
63
+ const result = getTxType(tx);
64
+ expect(result).toBe("transfer");
65
+ });
66
+ });
67
+
68
+ describe("Selector extract", () => {
69
+ it("should correctly extract 4-byte selector from transaction data", () => {
70
+ const transferSelector = ERC20_CLEAR_SIGNED_SELECTORS.TRANSFER;
71
+ const tx = createMockTransaction(transferSelector);
72
+
73
+ const expectedSelector = transferSelector;
74
+ const txSelector = `0x${tx.data?.toString("hex").substring(0, 8)}`;
75
+
76
+ expect(txSelector).toBe(expectedSelector);
77
+ expect(getTxType(tx)).toBe("transfer");
78
+ });
79
+ });
80
+ });
@@ -0,0 +1,14 @@
1
+ import { Transaction as EvmTransaction } from "@ledgerhq/coin-evm/types/transaction";
2
+ import { DAPP_SELECTORS } from "@ledgerhq/hw-app-eth";
3
+
4
+ const fallback = "transfer";
5
+
6
+ export const getTxType = (tx: EvmTransaction): string => {
7
+ if (!tx || !tx.data) return fallback;
8
+
9
+ const txSelector = `0x${tx.data.toString("hex").substring(0, 8)}`;
10
+ const type = DAPP_SELECTORS[txSelector];
11
+
12
+ if (!type) return fallback;
13
+ return type;
14
+ };