@ledgerhq/live-common 34.51.0-nightly.6 → 34.51.0-nightly.8

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 (162) hide show
  1. package/lib/dada-client/state-manager/api.d.ts.map +1 -1
  2. package/lib/dada-client/state-manager/api.js +10 -5
  3. package/lib/dada-client/state-manager/api.js.map +1 -1
  4. package/lib/dada-client/state-manager/types.d.ts +1 -0
  5. package/lib/dada-client/state-manager/types.d.ts.map +1 -1
  6. package/lib/device/use-cases/getAppsCatalogForDevice.d.ts +1 -1
  7. package/lib/device/use-cases/getAppsCatalogForDevice.d.ts.map +1 -1
  8. package/lib/e2e/data/deviceLabelsData.d.ts.map +1 -1
  9. package/lib/e2e/data/deviceLabelsData.js +2 -4
  10. package/lib/e2e/data/deviceLabelsData.js.map +1 -1
  11. package/lib/e2e/enum/Device.d.ts +5 -4
  12. package/lib/e2e/enum/Device.d.ts.map +1 -1
  13. package/lib/e2e/enum/Device.js +6 -4
  14. package/lib/e2e/enum/Device.js.map +1 -1
  15. package/lib/e2e/families/bitcoin.d.ts.map +1 -1
  16. package/lib/e2e/families/bitcoin.js +4 -3
  17. package/lib/e2e/families/bitcoin.js.map +1 -1
  18. package/lib/e2e/families/cardano.js +2 -2
  19. package/lib/e2e/families/cardano.js.map +1 -1
  20. package/lib/e2e/families/evm.d.ts.map +1 -1
  21. package/lib/e2e/families/evm.js +3 -2
  22. package/lib/e2e/families/evm.js.map +1 -1
  23. package/lib/e2e/families/solana.d.ts.map +1 -1
  24. package/lib/e2e/families/solana.js +2 -5
  25. package/lib/e2e/families/solana.js.map +1 -1
  26. package/lib/e2e/families/tezos.d.ts.map +1 -1
  27. package/lib/e2e/families/tezos.js +2 -1
  28. package/lib/e2e/families/tezos.js.map +1 -1
  29. package/lib/e2e/index.d.ts +7 -0
  30. package/lib/e2e/index.d.ts.map +1 -1
  31. package/lib/e2e/speculos.d.ts +1 -1
  32. package/lib/e2e/speculos.d.ts.map +1 -1
  33. package/lib/e2e/speculos.js +53 -60
  34. package/lib/e2e/speculos.js.map +1 -1
  35. package/lib/e2e/speculosAppVersion.d.ts +7 -0
  36. package/lib/e2e/speculosAppVersion.d.ts.map +1 -0
  37. package/lib/e2e/speculosAppVersion.js +104 -0
  38. package/lib/e2e/speculosAppVersion.js.map +1 -0
  39. package/lib/e2e/speculosCI.d.ts.map +1 -1
  40. package/lib/e2e/speculosCI.js +2 -1
  41. package/lib/e2e/speculosCI.js.map +1 -1
  42. package/lib/env.react.d.ts +1 -1
  43. package/lib/env.react.d.ts.map +1 -1
  44. package/lib/featureFlags/defaultFeatures.d.ts.map +1 -1
  45. package/lib/featureFlags/defaultFeatures.js +10 -0
  46. package/lib/featureFlags/defaultFeatures.js.map +1 -1
  47. package/lib/featureFlags/useFeature.d.ts +1 -1
  48. package/lib/featureFlags/useFeature.d.ts.map +1 -1
  49. package/lib/load/speculos.d.ts.map +1 -1
  50. package/lib/load/speculos.js +1 -0
  51. package/lib/load/speculos.js.map +1 -1
  52. package/lib/modularDrawer/hooks/__test__/useAssetAccountCounts.test.d.ts +2 -0
  53. package/lib/modularDrawer/hooks/__test__/useAssetAccountCounts.test.d.ts.map +1 -0
  54. package/lib/modularDrawer/hooks/__test__/useAssetAccountCounts.test.js +38 -0
  55. package/lib/modularDrawer/hooks/__test__/useAssetAccountCounts.test.js.map +1 -0
  56. package/lib/modularDrawer/hooks/__test__/useCurrenciesUnderFeatureFlag.test.d.ts +2 -0
  57. package/lib/modularDrawer/hooks/__test__/useCurrenciesUnderFeatureFlag.test.d.ts.map +1 -0
  58. package/lib/modularDrawer/hooks/__test__/useCurrenciesUnderFeatureFlag.test.js +50 -0
  59. package/lib/modularDrawer/hooks/__test__/useCurrenciesUnderFeatureFlag.test.js.map +1 -0
  60. package/lib/modularDrawer/hooks/__test__/useDetailedAccountsCore.test.d.ts.map +1 -0
  61. package/lib/modularDrawer/hooks/__test__/useDetailedAccountsCore.test.js.map +1 -0
  62. package/lib/modularDrawer/modules/__test__/createAssetConfiguration.test.d.ts +19 -0
  63. package/lib/modularDrawer/modules/__test__/createAssetConfiguration.test.d.ts.map +1 -0
  64. package/lib/modularDrawer/modules/__test__/createAssetConfiguration.test.js +209 -0
  65. package/lib/modularDrawer/modules/__test__/createAssetConfiguration.test.js.map +1 -0
  66. package/lib/modularDrawer/modules/__test__/createNetworkConfiguration.test.js +9 -27
  67. package/lib/modularDrawer/modules/__test__/createNetworkConfiguration.test.js.map +1 -1
  68. package/lib-es/dada-client/state-manager/api.d.ts.map +1 -1
  69. package/lib-es/dada-client/state-manager/api.js +10 -5
  70. package/lib-es/dada-client/state-manager/api.js.map +1 -1
  71. package/lib-es/dada-client/state-manager/types.d.ts +1 -0
  72. package/lib-es/dada-client/state-manager/types.d.ts.map +1 -1
  73. package/lib-es/device/use-cases/getAppsCatalogForDevice.d.ts +1 -1
  74. package/lib-es/device/use-cases/getAppsCatalogForDevice.d.ts.map +1 -1
  75. package/lib-es/e2e/data/deviceLabelsData.d.ts.map +1 -1
  76. package/lib-es/e2e/data/deviceLabelsData.js +2 -4
  77. package/lib-es/e2e/data/deviceLabelsData.js.map +1 -1
  78. package/lib-es/e2e/enum/Device.d.ts +5 -4
  79. package/lib-es/e2e/enum/Device.d.ts.map +1 -1
  80. package/lib-es/e2e/enum/Device.js +6 -4
  81. package/lib-es/e2e/enum/Device.js.map +1 -1
  82. package/lib-es/e2e/families/bitcoin.d.ts.map +1 -1
  83. package/lib-es/e2e/families/bitcoin.js +4 -3
  84. package/lib-es/e2e/families/bitcoin.js.map +1 -1
  85. package/lib-es/e2e/families/cardano.js +2 -2
  86. package/lib-es/e2e/families/cardano.js.map +1 -1
  87. package/lib-es/e2e/families/evm.d.ts.map +1 -1
  88. package/lib-es/e2e/families/evm.js +3 -2
  89. package/lib-es/e2e/families/evm.js.map +1 -1
  90. package/lib-es/e2e/families/solana.d.ts.map +1 -1
  91. package/lib-es/e2e/families/solana.js +3 -6
  92. package/lib-es/e2e/families/solana.js.map +1 -1
  93. package/lib-es/e2e/families/tezos.d.ts.map +1 -1
  94. package/lib-es/e2e/families/tezos.js +2 -1
  95. package/lib-es/e2e/families/tezos.js.map +1 -1
  96. package/lib-es/e2e/index.d.ts +7 -0
  97. package/lib-es/e2e/index.d.ts.map +1 -1
  98. package/lib-es/e2e/speculos.d.ts +1 -1
  99. package/lib-es/e2e/speculos.d.ts.map +1 -1
  100. package/lib-es/e2e/speculos.js +19 -25
  101. package/lib-es/e2e/speculos.js.map +1 -1
  102. package/lib-es/e2e/speculosAppVersion.d.ts +7 -0
  103. package/lib-es/e2e/speculosAppVersion.d.ts.map +1 -0
  104. package/lib-es/e2e/speculosAppVersion.js +74 -0
  105. package/lib-es/e2e/speculosAppVersion.js.map +1 -0
  106. package/lib-es/e2e/speculosCI.d.ts.map +1 -1
  107. package/lib-es/e2e/speculosCI.js +2 -1
  108. package/lib-es/e2e/speculosCI.js.map +1 -1
  109. package/lib-es/env.react.d.ts +1 -1
  110. package/lib-es/env.react.d.ts.map +1 -1
  111. package/lib-es/featureFlags/defaultFeatures.d.ts.map +1 -1
  112. package/lib-es/featureFlags/defaultFeatures.js +10 -0
  113. package/lib-es/featureFlags/defaultFeatures.js.map +1 -1
  114. package/lib-es/featureFlags/useFeature.d.ts +1 -1
  115. package/lib-es/featureFlags/useFeature.d.ts.map +1 -1
  116. package/lib-es/load/speculos.d.ts.map +1 -1
  117. package/lib-es/load/speculos.js +1 -0
  118. package/lib-es/load/speculos.js.map +1 -1
  119. package/lib-es/modularDrawer/hooks/__test__/useAssetAccountCounts.test.d.ts +2 -0
  120. package/lib-es/modularDrawer/hooks/__test__/useAssetAccountCounts.test.d.ts.map +1 -0
  121. package/lib-es/modularDrawer/hooks/__test__/useAssetAccountCounts.test.js +36 -0
  122. package/lib-es/modularDrawer/hooks/__test__/useAssetAccountCounts.test.js.map +1 -0
  123. package/lib-es/modularDrawer/hooks/__test__/useCurrenciesUnderFeatureFlag.test.d.ts +2 -0
  124. package/lib-es/modularDrawer/hooks/__test__/useCurrenciesUnderFeatureFlag.test.d.ts.map +1 -0
  125. package/lib-es/modularDrawer/hooks/__test__/useCurrenciesUnderFeatureFlag.test.js +45 -0
  126. package/lib-es/modularDrawer/hooks/__test__/useCurrenciesUnderFeatureFlag.test.js.map +1 -0
  127. package/lib-es/modularDrawer/hooks/__test__/useDetailedAccountsCore.test.d.ts.map +1 -0
  128. package/lib-es/modularDrawer/hooks/__test__/useDetailedAccountsCore.test.js.map +1 -0
  129. package/lib-es/modularDrawer/modules/__test__/createAssetConfiguration.test.d.ts +19 -0
  130. package/lib-es/modularDrawer/modules/__test__/createAssetConfiguration.test.d.ts.map +1 -0
  131. package/lib-es/modularDrawer/modules/__test__/createAssetConfiguration.test.js +202 -0
  132. package/lib-es/modularDrawer/modules/__test__/createAssetConfiguration.test.js.map +1 -0
  133. package/lib-es/modularDrawer/modules/__test__/createNetworkConfiguration.test.js +5 -23
  134. package/lib-es/modularDrawer/modules/__test__/createNetworkConfiguration.test.js.map +1 -1
  135. package/package.json +54 -54
  136. package/src/dada-client/state-manager/api.ts +10 -5
  137. package/src/dada-client/state-manager/types.ts +1 -0
  138. package/src/e2e/data/deviceLabelsData.ts +2 -4
  139. package/src/e2e/enum/Device.ts +7 -4
  140. package/src/e2e/families/bitcoin.ts +4 -9
  141. package/src/e2e/families/cardano.ts +2 -2
  142. package/src/e2e/families/evm.ts +3 -8
  143. package/src/e2e/families/solana.ts +2 -7
  144. package/src/e2e/families/tezos.ts +2 -7
  145. package/src/e2e/speculos.ts +22 -27
  146. package/src/e2e/speculosAppVersion.ts +86 -0
  147. package/src/e2e/speculosCI.ts +2 -1
  148. package/src/featureFlags/defaultFeatures.ts +10 -0
  149. package/src/load/speculos.ts +1 -0
  150. package/src/modularDrawer/hooks/__test__/useAssetAccountCounts.test.ts +40 -0
  151. package/src/modularDrawer/hooks/__test__/useCurrenciesUnderFeatureFlag.test.ts +59 -0
  152. package/src/modularDrawer/modules/__test__/createAssetConfiguration.test.tsx +250 -0
  153. package/src/modularDrawer/modules/__test__/createNetworkConfiguration.test.ts +2 -36
  154. package/lib/modularDrawer/hooks/__tests__/useDetailedAccountsCore.test.d.ts.map +0 -1
  155. package/lib/modularDrawer/hooks/__tests__/useDetailedAccountsCore.test.js.map +0 -1
  156. package/lib-es/modularDrawer/hooks/__tests__/useDetailedAccountsCore.test.d.ts.map +0 -1
  157. package/lib-es/modularDrawer/hooks/__tests__/useDetailedAccountsCore.test.js.map +0 -1
  158. /package/lib/modularDrawer/hooks/{__tests__ → __test__}/useDetailedAccountsCore.test.d.ts +0 -0
  159. /package/lib/modularDrawer/hooks/{__tests__ → __test__}/useDetailedAccountsCore.test.js +0 -0
  160. /package/lib-es/modularDrawer/hooks/{__tests__ → __test__}/useDetailedAccountsCore.test.d.ts +0 -0
  161. /package/lib-es/modularDrawer/hooks/{__tests__ → __test__}/useDetailedAccountsCore.test.js +0 -0
  162. /package/src/modularDrawer/hooks/{__tests__ → __test__}/useDetailedAccountsCore.test.ts +0 -0
@@ -41,18 +41,20 @@ export const assetsDataApi = createApi({
41
41
  ...(pageParam?.cursor && { cursor: pageParam.cursor }),
42
42
  ...(queryArg?.useCase && { transaction: queryArg.useCase }),
43
43
  ...(queryArg?.currencyIds &&
44
- queryArg?.currencyIds.length > 0 &&
45
- !queryArg?.useCase && { currencyIds: queryArg.currencyIds }),
44
+ queryArg?.currencyIds.length > 0 && { currencyIds: queryArg.currencyIds }),
46
45
  ...(queryArg?.search && { search: queryArg.search }),
47
46
  product: queryArg.product,
48
47
  minVersion: queryArg.version,
49
- additionalData: [AssetsAdditionalData.Apy, AssetsAdditionalData.MarketTrend],
48
+ additionalData: queryArg.additionalData || [
49
+ AssetsAdditionalData.Apy,
50
+ AssetsAdditionalData.MarketTrend,
51
+ ],
50
52
  };
51
53
 
52
54
  const baseUrl = queryArg.isStaging ? getEnv("DADA_API_STAGING") : getEnv("DADA_API_PROD");
53
55
 
54
56
  return {
55
- url: `${baseUrl}assets`,
57
+ url: `${baseUrl}/assets`,
56
58
  params,
57
59
  };
58
60
  },
@@ -81,7 +83,10 @@ export const assetsDataApi = createApi({
81
83
  queryArg?.currencyIds.length > 0 && { currencyIds: queryArg.currencyIds }),
82
84
  product: queryArg.product,
83
85
  minVersion: queryArg.version,
84
- additionalData: [AssetsAdditionalData.Apy, AssetsAdditionalData.MarketTrend],
86
+ additionalData: queryArg.additionalData || [
87
+ AssetsAdditionalData.Apy,
88
+ AssetsAdditionalData.MarketTrend,
89
+ ],
85
90
  };
86
91
 
87
92
  const baseUrl = queryArg.isStaging ? getEnv("DADA_API_STAGING") : getEnv("DADA_API_PROD");
@@ -16,6 +16,7 @@ export interface GetAssetsDataParams {
16
16
  product: "llm" | "lld";
17
17
  version: string;
18
18
  isStaging?: boolean;
19
+ additionalData?: AssetsAdditionalData[];
19
20
  }
20
21
 
21
22
  export interface PageParam {
@@ -65,7 +65,7 @@ export const DEVICE_LABELS_CONFIG: DeviceLabelsConfig = {
65
65
  [AppInfos.ETHEREUM.name]: DeviceLabels.VERIFY_ETHEREUM,
66
66
  [AppInfos.POLKADOT.name]: DeviceLabels.PLEASE_REVIEW,
67
67
  [AppInfos.POLYGON.name]: DeviceLabels.VERIFY_POLYGON,
68
- [AppInfos.SOLANA.name]: DeviceLabels.VERIFY_SOLANA_ADDRESS,
68
+ [AppInfos.SOLANA.name]: DeviceLabels.PUBKEY,
69
69
  default: DeviceLabels.ADDRESS,
70
70
  },
71
71
  receiveConfirm: {
@@ -75,14 +75,13 @@ export const DEVICE_LABELS_CONFIG: DeviceLabelsConfig = {
75
75
  [AppInfos.ETHEREUM.name]: DeviceLabels.CONFIRM,
76
76
  [AppInfos.POLKADOT.name]: DeviceLabels.CAPS_APPROVE,
77
77
  [AppInfos.POLYGON.name]: DeviceLabels.CONFIRM,
78
- [AppInfos.SOLANA.name]: DeviceLabels.CONFIRM,
79
78
  default: DeviceLabels.APPROVE,
80
79
  },
81
80
  delegateVerify: {
82
81
  [AppInfos.COSMOS.name]: DeviceLabels.PLEASE_REVIEW,
83
82
  [AppInfos.MULTIVERS_X.name]: DeviceLabels.RECEIVER,
84
83
  [AppInfos.NEAR.name]: DeviceLabels.VIEW_HEADER,
85
- [AppInfos.SOLANA.name]: DeviceLabels.REVIEW_TRANSACTION,
84
+ [AppInfos.SOLANA.name]: DeviceLabels.DELEGATE_FROM,
86
85
  default: DeviceLabels.REVIEW_OPERATION,
87
86
  },
88
87
  delegateConfirm: {
@@ -92,7 +91,6 @@ export const DEVICE_LABELS_CONFIG: DeviceLabelsConfig = {
92
91
  [AppInfos.INJECTIVE.name]: DeviceLabels.CAPS_APPROVE,
93
92
  [AppInfos.MULTIVERS_X.name]: DeviceLabels.SIGN,
94
93
  [AppInfos.NEAR.name]: DeviceLabels.CONTINUE_TO_ACTION,
95
- [AppInfos.SOLANA.name]: DeviceLabels.SIGN_TRANSACTION,
96
94
  [AppInfos.OSMOSIS.name]: DeviceLabels.CAPS_APPROVE,
97
95
  default: DeviceLabels.APPROVE,
98
96
  },
@@ -1,7 +1,10 @@
1
1
  export class Device {
2
- constructor(public readonly name: string) {}
2
+ constructor(
3
+ public readonly name: string,
4
+ public readonly targetId: number,
5
+ ) {}
3
6
 
4
- static readonly LNS = "nanoS";
5
- static readonly LNX = "nanoX";
6
- static readonly LNSP = "nanoSP";
7
+ static readonly LNS = new Device("nanoS", 823132164);
8
+ static readonly LNX = new Device("nanoX", 855638020);
9
+ static readonly LNSP = new Device("nanoSP", 856686596);
7
10
  }
@@ -1,12 +1,7 @@
1
1
  import expect from "expect";
2
2
  import { Transaction } from "../models/Transaction";
3
- import {
4
- pressBoth,
5
- pressUntilTextFound,
6
- waitFor,
7
- containsSubstringInEvent,
8
- getSpeculosModel,
9
- } from "../speculos";
3
+ import { pressBoth, pressUntilTextFound, waitFor, containsSubstringInEvent } from "../speculos";
4
+ import { getSpeculosModel } from "../speculosAppVersion";
10
5
  import { DeviceLabels } from "../enum/DeviceLabels";
11
6
  import { Device } from "../enum/Device";
12
7
  import invariant from "invariant";
@@ -27,7 +22,7 @@ export async function sendBTC(tx: Transaction) {
27
22
  const speculosDevice = getSpeculosModel();
28
23
  try {
29
24
  const events =
30
- speculosDevice === Device.LNS
25
+ speculosDevice === Device.LNS.name
31
26
  ? await pressUntilTextFound(DeviceLabels.CONTINUE)
32
27
  : await pressUntilTextFound(DeviceLabels.SIGN_TRANSACTION);
33
28
  const isAmountCorrect = containsSubstringInEvent(tx.amount, events);
@@ -35,7 +30,7 @@ export async function sendBTC(tx: Transaction) {
35
30
  const isAddressCorrect = containsSubstringInEvent(tx.accountToCredit.address, events);
36
31
  expect(isAddressCorrect).toBeTruthy();
37
32
  await pressBoth();
38
- if (speculosDevice === Device.LNS) {
33
+ if (speculosDevice === Device.LNS.name) {
39
34
  await pressUntilTextFound(DeviceLabels.SIGN);
40
35
  await pressBoth();
41
36
  await waitFor(DeviceLabels.BITCOIN_IS_READY);
@@ -11,7 +11,7 @@ import { DeviceLabels } from "../enum/DeviceLabels";
11
11
  import { Device } from "../enum/Device";
12
12
 
13
13
  export async function sendCardano(tx: Transaction) {
14
- const isNanoS = process.env.SPECULOS_DEVICE === Device.LNS;
14
+ const isNanoS = process.env.SPECULOS_DEVICE === Device.LNS.name;
15
15
  await waitFor(DeviceLabels.NEW_ORDINARY);
16
16
  await (isNanoS ? pressRightButton() : pressBoth());
17
17
  if (isNanoS) {
@@ -66,7 +66,7 @@ export async function delegateCardano() {
66
66
  [DeviceLabels.CONFIRM, "right"],
67
67
  ] as const;
68
68
 
69
- const steps = process.env.SPECULOS_DEVICE === Device.LNS ? LNSSpecificSteps : commonSteps;
69
+ const steps = process.env.SPECULOS_DEVICE === Device.LNS.name ? LNSSpecificSteps : commonSteps;
70
70
 
71
71
  for (const [label, action] of steps) {
72
72
  try {
@@ -1,12 +1,7 @@
1
1
  import expect from "expect";
2
2
  import { NFTTransaction, Transaction } from "../models/Transaction";
3
- import {
4
- pressBoth,
5
- pressUntilTextFound,
6
- containsSubstringInEvent,
7
- waitFor,
8
- getSpeculosModel,
9
- } from "../speculos";
3
+ import { pressBoth, pressUntilTextFound, containsSubstringInEvent, waitFor } from "../speculos";
4
+ import { getSpeculosModel } from "../speculosAppVersion";
10
5
  import { DeviceLabels } from "../enum/DeviceLabels";
11
6
  import { Device } from "../enum/Device";
12
7
  import { DeviceModelId } from "@ledgerhq/types-devices";
@@ -18,7 +13,7 @@ export async function sendEVM(tx: Transaction) {
18
13
  : await pressUntilTextFound(DeviceLabels.ACCEPT);
19
14
  const isAmountCorrect = containsSubstringInEvent(tx.amount, events);
20
15
  expect(isAmountCorrect).toBeTruthy();
21
- if (tx.accountToCredit.ensName && process.env.SPECULOS_DEVICE !== Device.LNS) {
16
+ if (tx.accountToCredit.ensName && process.env.SPECULOS_DEVICE !== Device.LNS.name) {
22
17
  const isENSNameCorrect = containsSubstringInEvent(tx.accountToCredit.ensName, events);
23
18
  expect(isENSNameCorrect).toBeTruthy();
24
19
  } else {
@@ -4,13 +4,11 @@ import {
4
4
  pressUntilTextFound,
5
5
  containsSubstringInEvent,
6
6
  getDelegateEvents,
7
- getSpeculosModel,
8
7
  } from "../speculos";
9
8
  import { DeviceLabels } from "../enum/DeviceLabels";
10
9
  import { Device } from "../enum/Device";
11
10
  import { Transaction } from "../models/Transaction";
12
11
  import { Delegate } from "../models/Delegate";
13
- import { DeviceModelId } from "@ledgerhq/types-devices";
14
12
 
15
13
  export async function delegateSolana(delegatingAccount: Delegate) {
16
14
  await getDelegateEvents(delegatingAccount);
@@ -18,13 +16,10 @@ export async function delegateSolana(delegatingAccount: Delegate) {
18
16
  }
19
17
 
20
18
  export async function sendSolana(tx: Transaction) {
21
- const events =
22
- getSpeculosModel() !== DeviceModelId.nanoS
23
- ? await pressUntilTextFound(DeviceLabels.SIGN_TRANSACTION)
24
- : await pressUntilTextFound(DeviceLabels.APPROVE);
19
+ const events = await pressUntilTextFound(DeviceLabels.APPROVE);
25
20
  const isAmountCorrect = containsSubstringInEvent(tx.amount, events);
26
21
  expect(isAmountCorrect).toBeTruthy();
27
- if (process.env.SPECULOS_DEVICE !== Device.LNS) {
22
+ if (process.env.SPECULOS_DEVICE !== Device.LNS.name) {
28
23
  const isAddressCorrect = containsSubstringInEvent(
29
24
  tx.accountToCredit.parentAccount?.address ?? tx.accountToCredit.address,
30
25
  events,
@@ -1,10 +1,5 @@
1
- import {
2
- getDelegateEvents,
3
- getDeviceLabels,
4
- getSpeculosModel,
5
- pressBoth,
6
- pressUntilTextFound,
7
- } from "../speculos";
1
+ import { getDelegateEvents, getDeviceLabels, pressBoth, pressUntilTextFound } from "../speculos";
2
+ import { getSpeculosModel } from "../speculosAppVersion";
8
3
  import { Delegate } from "../models/Delegate";
9
4
  import { DeviceModelId } from "@ledgerhq/types-devices";
10
5
  import { DeviceLabels } from "../enum/DeviceLabels";
@@ -16,7 +16,6 @@ import { getEnv } from "@ledgerhq/live-env";
16
16
  import { getCryptoCurrencyById } from "../currencies";
17
17
  import { DeviceLabels } from "./enum/DeviceLabels";
18
18
  import { Account } from "./enum/Account";
19
- import { Device as CryptoWallet } from "./enum/Device";
20
19
  import { Currency } from "./enum/Currency";
21
20
  import expect from "expect";
22
21
  import { sendBTC, sendBTCBasedCoin } from "./families/bitcoin";
@@ -43,6 +42,7 @@ import { delegateOsmosis } from "./families/osmosis";
43
42
  import { AppInfos } from "./enum/AppInfos";
44
43
  import { DEVICE_LABELS_CONFIG } from "./data/deviceLabelsData";
45
44
  import { sendSui } from "./families/sui";
45
+ import { getAppVersionFromCatalog, getSpeculosModel } from "./speculosAppVersion";
46
46
 
47
47
  const isSpeculosRemote = process.env.REMOTE_SPECULOS === "true";
48
48
 
@@ -51,6 +51,7 @@ export type Spec = {
51
51
  appQuery: {
52
52
  model: DeviceModelId;
53
53
  appName: string;
54
+ appVersion?: string;
54
55
  };
55
56
  /** @deprecated */
56
57
  dependency?: string;
@@ -74,19 +75,6 @@ export function setExchangeDependencies(dependencies: Dependency[]) {
74
75
  specs["Exchange"].dependencies = Array.from(map.values());
75
76
  }
76
77
 
77
- export function getSpeculosModel() {
78
- const speculosDevice = process.env.SPECULOS_DEVICE;
79
- switch (speculosDevice) {
80
- case CryptoWallet.LNS:
81
- return DeviceModelId.nanoS;
82
- case CryptoWallet.LNX:
83
- return DeviceModelId.nanoX;
84
- case CryptoWallet.LNSP:
85
- default:
86
- return DeviceModelId.nanoSP;
87
- }
88
- }
89
-
90
78
  type Specs = {
91
79
  [key: string]: Spec;
92
80
  };
@@ -312,7 +300,6 @@ export const specs: Specs = {
312
300
  },
313
301
  dependency: "",
314
302
  },
315
-
316
303
  Celo: {
317
304
  currency: getCryptoCurrencyById("celo"),
318
305
  appQuery: {
@@ -367,13 +354,21 @@ export async function startSpeculos(
367
354
  invariant(seed, "SEED is not set");
368
355
  const coinapps = COINAPPS;
369
356
  invariant(coinapps, "COINAPPS is not set");
370
- let appCandidates;
357
+ const appCandidates = await listAppCandidates(coinapps);
371
358
 
372
- if (!appCandidates) {
373
- appCandidates = await listAppCandidates(coinapps);
374
- }
359
+ const nanoAppCatalogPath = getEnv("E2E_NANO_APP_VERSION_PATH");
375
360
 
376
361
  const { appQuery, dependency, onSpeculosDeviceCreated } = spec;
362
+ try {
363
+ const displayName = spec.currency?.managerAppName || appQuery.appName;
364
+ const catalogVersion = await getAppVersionFromCatalog(displayName, nanoAppCatalogPath);
365
+ if (catalogVersion) {
366
+ appQuery.appVersion = catalogVersion;
367
+ }
368
+ } catch (e) {
369
+ console.warn("[speculos] Unable to fetch app version from catalog", e);
370
+ }
371
+
377
372
  const appCandidate = findLatestAppCandidate(appCandidates, appQuery);
378
373
  const { model } = appQuery;
379
374
  const { dependencies } = spec;
@@ -806,10 +801,7 @@ export async function getDelegateEvents(delegatingAccount: Delegate): Promise<st
806
801
 
807
802
  export async function verifyAmountsAndAcceptSwap(swap: Swap, amount: string) {
808
803
  await waitFor(DeviceLabels.REVIEW_TRANSACTION);
809
- const events =
810
- getSpeculosModel() === DeviceModelId.nanoS
811
- ? await pressUntilTextFound(DeviceLabels.ACCEPT_AND_SEND)
812
- : await pressUntilTextFound(DeviceLabels.SIGN_TRANSACTION);
804
+ const events = await pressUntilTextFound(DeviceLabels.ACCEPT_AND_SEND);
813
805
  verifySwapData(swap, events, amount);
814
806
  await pressBoth();
815
807
  }
@@ -829,11 +821,14 @@ export async function verifyAmountsAndRejectSwap(swap: Swap, amount: string) {
829
821
  }
830
822
 
831
823
  function verifySwapData(swap: Swap, events: string[], amount: string) {
832
- const swapPair = `swap ${swap.getAccountToDebit.currency.ticker} to ${swap.getAccountToCredit.currency.ticker}`;
824
+ // Uncoment when new exchange nanoApp is in prod
825
+
826
+ // const swapPair = `swap ${swap.getAccountToDebit.currency.ticker} to ${swap.getAccountToCredit.currency.ticker}`;
827
+
828
+ // if (getSpeculosModel() !== DeviceModelId.nanoS) {
829
+ // expectDeviceScreenContains(swapPair, events, "Swap pair not found on the device screen");
830
+ // }
833
831
 
834
- if (getSpeculosModel() !== DeviceModelId.nanoS) {
835
- expectDeviceScreenContains(swapPair, events, "Swap pair not found on the device screen");
836
- }
837
832
  expectDeviceScreenContains(amount, events, `Amount ${amount} not found on the device screen`);
838
833
  }
839
834
 
@@ -0,0 +1,86 @@
1
+ import { HttpManagerApiRepository, ApplicationV2Entity } from "@ledgerhq/device-core";
2
+ import { version } from "@ledgerhq/device-core/package.json";
3
+ import { getEnv } from "@ledgerhq/live-env";
4
+ import { DeviceModelId } from "@ledgerhq/devices";
5
+ import { Device as CryptoWallet } from "./enum/Device";
6
+ import * as fs from "fs";
7
+ import * as path from "path";
8
+
9
+ export function getSpeculosModel(): DeviceModelId {
10
+ const speculosDevice = process.env.SPECULOS_DEVICE;
11
+ switch (speculosDevice) {
12
+ case CryptoWallet.LNS.name:
13
+ return DeviceModelId.nanoS;
14
+ case CryptoWallet.LNX.name:
15
+ return DeviceModelId.nanoX;
16
+ case CryptoWallet.LNSP.name:
17
+ default:
18
+ return DeviceModelId.nanoSP;
19
+ }
20
+ }
21
+
22
+ function getDeviceTargetId(device: DeviceModelId): number {
23
+ const modelToTargetIdMap = {
24
+ [DeviceModelId.nanoS]: CryptoWallet.LNS.targetId,
25
+ [DeviceModelId.nanoX]: CryptoWallet.LNX.targetId,
26
+ [DeviceModelId.nanoSP]: CryptoWallet.LNSP.targetId,
27
+ };
28
+ return modelToTargetIdMap[device];
29
+ }
30
+
31
+ export async function getNanoAppCatalog(
32
+ device: DeviceModelId,
33
+ deviceFirmware: string,
34
+ ): Promise<ApplicationV2Entity[]> {
35
+ const repository = new HttpManagerApiRepository(getEnv("MANAGER_API_BASE"), version);
36
+ const targetId = getDeviceTargetId(device);
37
+ return await repository.catalogForDevice({
38
+ provider: 1,
39
+ targetId: targetId,
40
+ firmwareVersion: deviceFirmware,
41
+ });
42
+ }
43
+
44
+ function getDeviceFirmwareVersion(): string {
45
+ const firmwareVersion = process.env.SPECULOS_FIRMWARE_VERSION;
46
+ if (!firmwareVersion) {
47
+ throw new Error("SPECULOS_FIRMWARE_VERSION environment variable is not set");
48
+ }
49
+ return firmwareVersion;
50
+ }
51
+
52
+ export async function createNanoAppJsonFile(nanoAppFilePath: string): Promise<void> {
53
+ try {
54
+ const device = getSpeculosModel();
55
+ const firmware = getDeviceFirmwareVersion();
56
+ const appCatalog = await getNanoAppCatalog(device, firmware);
57
+ const jsonFilePath = path.join(process.cwd(), nanoAppFilePath);
58
+ const dirPath = path.dirname(jsonFilePath);
59
+ if (!fs.existsSync(dirPath)) {
60
+ fs.mkdirSync(dirPath, { recursive: true });
61
+ }
62
+ fs.writeFileSync(jsonFilePath, JSON.stringify(appCatalog, null, 2), "utf8");
63
+ } catch (error) {
64
+ console.error("Unable to create app version file:", error);
65
+ }
66
+ }
67
+
68
+ export async function getAppVersionFromCatalog(
69
+ currency: string,
70
+ nanoAppFilePath: string,
71
+ ): Promise<string | undefined> {
72
+ try {
73
+ await createNanoAppJsonFile(nanoAppFilePath);
74
+ const rootDir = process.cwd();
75
+ const jsonFilePath = path.join(rootDir, nanoAppFilePath);
76
+ type CatalogApp = { versionDisplayName: string; version: string };
77
+ const raw = fs.readFileSync(jsonFilePath, "utf8");
78
+ const catalog: CatalogApp[] = JSON.parse(raw);
79
+
80
+ const app = catalog.find(entry => entry.versionDisplayName === currency);
81
+
82
+ return app?.version ?? "";
83
+ } catch (error) {
84
+ console.error(`Unable to get app version for ${currency} from catalog:`, error);
85
+ }
86
+ }
@@ -7,7 +7,7 @@ import {
7
7
  import { SpeculosDevice } from "./speculos";
8
8
  import https from "https";
9
9
 
10
- const { SEED, GITHUB_TOKEN, AWS_ROLE, CLUSTER } = process.env;
10
+ const { SEED, GITHUB_TOKEN, AWS_ROLE, CLUSTER, SPECULOS_IMAGE_TAG } = process.env;
11
11
  const GIT_API_URL = "https://api.github.com/repos/LedgerHQ/actions/actions/";
12
12
  const START_WORKFLOW_ID = "workflows/161487603/dispatches";
13
13
  const STOP_WORKFLOW_ID = "workflows/161487604/dispatches";
@@ -147,6 +147,7 @@ function createStartPayload(deviceParams: DeviceParams, runId: string) {
147
147
  return {
148
148
  ref: GITHUB_REF,
149
149
  inputs: {
150
+ speculos_version: SPECULOS_IMAGE_TAG?.split(":")[1] || "master",
150
151
  coin_app: appName,
151
152
  coin_app_version: appVersion,
152
153
  device: reverseModelMap[model],
@@ -129,6 +129,10 @@ export const DEFAULT_FEATURES: Features = {
129
129
  receiveStakingFlowConfigDesktop: initFeature(),
130
130
  brazePushNotifications: initFeature(),
131
131
  stakeAccountBanner: initFeature(),
132
+ mixpanelAnalytics: initFeature({
133
+ enabled: false,
134
+ params: { record_sessions_percent: 100 },
135
+ }),
132
136
 
133
137
  ptxSwapDetailedView: initFeature({
134
138
  enabled: false,
@@ -688,6 +692,12 @@ export const DEFAULT_FEATURES: Features = {
688
692
  supportDeviceApex: DEFAULT_FEATURE,
689
693
  llmSyncOnboardingIncr1: DEFAULT_FEATURE,
690
694
  noah: DEFAULT_FEATURE,
695
+ lldSessionReplay: {
696
+ ...DEFAULT_FEATURE,
697
+ params: {
698
+ sampling: 100,
699
+ },
700
+ },
691
701
  };
692
702
 
693
703
  // Firebase SDK treat JSON values as strings
@@ -128,6 +128,7 @@ export const findLatestAppCandidate = (
128
128
  appCandidates: AppCandidate[],
129
129
  search: AppSearch,
130
130
  ): AppCandidate | null => {
131
+ search.firmware = process.env.SPECULOS_FIRMWARE_VERSION;
131
132
  let apps = appCandidates.filter(c => appCandidatesMatches(c, search));
132
133
  if (apps.length === 0) {
133
134
  return null;
@@ -0,0 +1,40 @@
1
+ import { genAccount } from "@ledgerhq/coin-framework/lib/mocks/account";
2
+ import { useAssetAccountCounts } from "../useAssetAccountCounts";
3
+ import { createFixtureCryptoCurrency } from "../../../mock/fixtures/cryptoCurrencies";
4
+
5
+ const ethereumCurrency = createFixtureCryptoCurrency("ethereum");
6
+ const ethereumAccountHigh = genAccount("ethereum-account-high", {
7
+ currency: ethereumCurrency,
8
+ });
9
+
10
+ describe("useAssetAccountCounts", () => {
11
+ it("should return the count for one account", () => {
12
+ const assetAccountCounts = useAssetAccountCounts({
13
+ assets: [ethereumCurrency],
14
+ nestedAccounts: [ethereumAccountHigh],
15
+ accountIds: new Map([[ethereumAccountHigh.id, true]]),
16
+ formatLabel: (count: number) => `${count}`,
17
+ });
18
+
19
+ expect(assetAccountCounts[0].count).toBe(1);
20
+ expect(assetAccountCounts[0].label).toBe("1");
21
+ });
22
+
23
+ it("should return the count for two accounts on ethereum", () => {
24
+ const ethereumAccountLow = genAccount("ethereum-account-low", {
25
+ currency: ethereumCurrency,
26
+ });
27
+ const assetAccountCounts = useAssetAccountCounts({
28
+ assets: [ethereumCurrency],
29
+ nestedAccounts: [ethereumAccountHigh, ethereumAccountLow],
30
+ accountIds: new Map([
31
+ [ethereumAccountHigh.id, true],
32
+ [ethereumAccountLow.id, true],
33
+ ]),
34
+ formatLabel: (count: number) => `${count}`,
35
+ });
36
+
37
+ expect(assetAccountCounts[0].count).toBe(2);
38
+ expect(assetAccountCounts[0].label).toBe("2");
39
+ });
40
+ });
@@ -0,0 +1,59 @@
1
+ /**
2
+ * @jest-environment jsdom
3
+ */
4
+ import { renderHook } from "@testing-library/react";
5
+ import { useCurrenciesUnderFeatureFlag } from "../useCurrenciesUnderFeatureFlag";
6
+ import { useFeature } from "../../../featureFlags";
7
+ import useEnv from "../../../hooks/useEnv";
8
+
9
+ jest.mock("../../../featureFlags", () => ({ useFeature: jest.fn() }));
10
+ jest.mock("../../../hooks/useEnv", () => jest.fn());
11
+
12
+ const mockUseFeature = jest.mocked(useFeature);
13
+ const mockedEnvironment = jest.mocked(useEnv);
14
+
15
+ describe("useCurrenciesUnderFeatureFlag", () => {
16
+ beforeEach(() => {
17
+ jest.clearAllMocks();
18
+ });
19
+
20
+ it("should return empty deactivatedCurrencyIds when all features are enabled", () => {
21
+ mockedEnvironment.mockReturnValue(false);
22
+ mockUseFeature.mockReturnValue({ enabled: true });
23
+
24
+ const { result } = renderHook(() => useCurrenciesUnderFeatureFlag());
25
+
26
+ expect(result.current.deactivatedCurrencyIds.size).toEqual(0);
27
+ expect(result.current.featureFlaggedCurrencies).toBeDefined();
28
+ });
29
+
30
+ it("should include disabled currencies in deactivatedCurrencyIds", () => {
31
+ mockedEnvironment.mockReturnValue(false);
32
+ mockUseFeature.mockReturnValue({ enabled: false });
33
+
34
+ const { result } = renderHook(() => useCurrenciesUnderFeatureFlag());
35
+
36
+ expect(result.current.deactivatedCurrencyIds.size).toBeGreaterThan(0);
37
+ });
38
+
39
+ it("should return empty deactivatedCurrencyIds when MOCK is true", () => {
40
+ mockedEnvironment.mockReturnValue(true);
41
+ mockUseFeature.mockReturnValue({ enabled: false });
42
+
43
+ const { result } = renderHook(() => useCurrenciesUnderFeatureFlag());
44
+
45
+ expect(result.current.deactivatedCurrencyIds.size).toBe(0);
46
+ });
47
+
48
+ it("should contain currency mappings", () => {
49
+ mockedEnvironment.mockReturnValue(false);
50
+ mockUseFeature.mockReturnValue({ enabled: true });
51
+
52
+ const { result } = renderHook(() => useCurrenciesUnderFeatureFlag());
53
+
54
+ const currencies = result.current.featureFlaggedCurrencies;
55
+ expect(currencies).toHaveProperty("aptos");
56
+ expect(currencies).toHaveProperty("stacks");
57
+ expect(currencies).toHaveProperty("optimism");
58
+ });
59
+ });