@ledgerhq/live-common 34.35.1-hotfix.0 → 34.36.0-next.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (249) hide show
  1. package/lib/apps/support.d.ts +1 -0
  2. package/lib/apps/support.d.ts.map +1 -1
  3. package/lib/apps/support.js +10 -1
  4. package/lib/apps/support.js.map +1 -1
  5. package/lib/e2e/enum/Account.d.ts +64 -58
  6. package/lib/e2e/enum/Account.d.ts.map +1 -1
  7. package/lib/e2e/enum/Account.js +80 -59
  8. package/lib/e2e/enum/Account.js.map +1 -1
  9. package/lib/e2e/enum/Device.d.ts +8 -0
  10. package/lib/e2e/enum/Device.d.ts.map +1 -0
  11. package/lib/e2e/enum/Device.js +14 -0
  12. package/lib/e2e/enum/Device.js.map +1 -0
  13. package/lib/e2e/enum/Swap.d.ts +2 -1
  14. package/lib/e2e/enum/Swap.d.ts.map +1 -1
  15. package/lib/e2e/enum/Swap.js +12 -10
  16. package/lib/e2e/enum/Swap.js.map +1 -1
  17. package/lib/e2e/families/cardano.d.ts.map +1 -1
  18. package/lib/e2e/families/cardano.js +55 -26
  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 +2 -1
  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 +5 -2
  25. package/lib/e2e/families/solana.js.map +1 -1
  26. package/lib/e2e/index.d.ts +2 -0
  27. package/lib/e2e/index.d.ts.map +1 -1
  28. package/lib/e2e/models/BuySell.d.ts +11 -0
  29. package/lib/e2e/models/BuySell.d.ts.map +1 -0
  30. package/lib/{index.js → e2e/models/BuySell.js} +1 -1
  31. package/lib/e2e/models/BuySell.js.map +1 -0
  32. package/lib/e2e/models/Transaction.d.ts +5 -5
  33. package/lib/e2e/models/Transaction.d.ts.map +1 -1
  34. package/lib/e2e/models/Transaction.js.map +1 -1
  35. package/lib/e2e/speculos.d.ts +6 -1
  36. package/lib/e2e/speculos.d.ts.map +1 -1
  37. package/lib/e2e/speculos.js +72 -40
  38. package/lib/e2e/speculos.js.map +1 -1
  39. package/lib/e2e/speculosCI.d.ts +5 -0
  40. package/lib/e2e/speculosCI.d.ts.map +1 -0
  41. package/lib/e2e/speculosCI.js +129 -0
  42. package/lib/e2e/speculosCI.js.map +1 -0
  43. package/lib/families/hedera/logic.d.ts +2 -0
  44. package/lib/families/hedera/logic.d.ts.map +1 -0
  45. package/lib/families/hedera/logic.js +19 -0
  46. package/lib/families/hedera/logic.js.map +1 -0
  47. package/lib/featureFlags/defaultFeatures.d.ts.map +1 -1
  48. package/lib/featureFlags/defaultFeatures.js +1 -0
  49. package/lib/featureFlags/defaultFeatures.js.map +1 -1
  50. package/lib/featureFlags/useFeature.d.ts +1 -1
  51. package/lib/featureFlags/useFeature.d.ts.map +1 -1
  52. package/lib/hw/actions/manager.d.ts +1 -1
  53. package/lib/hw/actions/manager.d.ts.map +1 -1
  54. package/lib/hw/connectApp.d.ts.map +1 -1
  55. package/lib/hw/connectApp.js +56 -5
  56. package/lib/hw/connectApp.js.map +1 -1
  57. package/lib/hw/connectAppEventMapper.d.ts +29 -0
  58. package/lib/hw/connectAppEventMapper.d.ts.map +1 -0
  59. package/lib/hw/connectAppEventMapper.js +300 -0
  60. package/lib/hw/connectAppEventMapper.js.map +1 -0
  61. package/lib/hw/connectManager.d.ts +3 -2
  62. package/lib/hw/connectManager.d.ts.map +1 -1
  63. package/lib/hw/connectManager.js +34 -3
  64. package/lib/hw/connectManager.js.map +1 -1
  65. package/lib/hw/connectManagerEventMapper.d.ts +16 -0
  66. package/lib/hw/connectManagerEventMapper.d.ts.map +1 -0
  67. package/lib/hw/connectManagerEventMapper.js +78 -0
  68. package/lib/hw/connectManagerEventMapper.js.map +1 -0
  69. package/lib/market/hooks/useLargeMoverChartData.d.ts +18 -0
  70. package/lib/market/hooks/useLargeMoverChartData.d.ts.map +1 -0
  71. package/lib/market/hooks/useLargeMoverChartData.js +28 -0
  72. package/lib/market/hooks/useLargeMoverChartData.js.map +1 -0
  73. package/lib/market/hooks/useLargeMoverCurrencies.d.ts +13 -0
  74. package/lib/market/hooks/useLargeMoverCurrencies.d.ts.map +1 -0
  75. package/lib/market/hooks/useLargeMoverCurrencies.js +29 -0
  76. package/lib/market/hooks/useLargeMoverCurrencies.js.map +1 -0
  77. package/lib/notifications/AnnouncementProvider/index.d.ts.map +1 -1
  78. package/lib/notifications/AnnouncementProvider/index.js +12 -10
  79. package/lib/notifications/AnnouncementProvider/index.js.map +1 -1
  80. package/lib/notifications/AnnouncementProvider/machine.d.ts +1 -4
  81. package/lib/notifications/AnnouncementProvider/machine.d.ts.map +1 -1
  82. package/lib/notifications/AnnouncementProvider/machine.js +9 -8
  83. package/lib/notifications/AnnouncementProvider/machine.js.map +1 -1
  84. package/lib/notifications/ServiceStatusProvider/index.d.ts.map +1 -1
  85. package/lib/notifications/ServiceStatusProvider/index.js +5 -4
  86. package/lib/notifications/ServiceStatusProvider/index.js.map +1 -1
  87. package/lib/notifications/ServiceStatusProvider/machine.d.ts +1 -4
  88. package/lib/notifications/ServiceStatusProvider/machine.d.ts.map +1 -1
  89. package/lib/notifications/ServiceStatusProvider/machine.js +4 -4
  90. package/lib/notifications/ServiceStatusProvider/machine.js.map +1 -1
  91. package/lib/wallet-api/ModularDrawer/types.d.ts +63 -0
  92. package/lib/wallet-api/ModularDrawer/types.d.ts.map +1 -0
  93. package/lib/wallet-api/ModularDrawer/types.js +25 -0
  94. package/lib/wallet-api/ModularDrawer/types.js.map +1 -0
  95. package/lib/wallet-api/ModularDrawer/utils.d.ts +5 -0
  96. package/lib/wallet-api/ModularDrawer/utils.d.ts.map +1 -0
  97. package/lib/wallet-api/ModularDrawer/utils.js +30 -0
  98. package/lib/wallet-api/ModularDrawer/utils.js.map +1 -0
  99. package/lib/wallet-api/react.d.ts +2 -0
  100. package/lib/wallet-api/react.d.ts.map +1 -1
  101. package/lib/wallet-api/react.js +2 -1
  102. package/lib/wallet-api/react.js.map +1 -1
  103. package/lib-es/apps/support.d.ts +1 -0
  104. package/lib-es/apps/support.d.ts.map +1 -1
  105. package/lib-es/apps/support.js +8 -0
  106. package/lib-es/apps/support.js.map +1 -1
  107. package/lib-es/e2e/enum/Account.d.ts +64 -58
  108. package/lib-es/e2e/enum/Account.d.ts.map +1 -1
  109. package/lib-es/e2e/enum/Account.js +76 -58
  110. package/lib-es/e2e/enum/Account.js.map +1 -1
  111. package/lib-es/e2e/enum/Device.d.ts +8 -0
  112. package/lib-es/e2e/enum/Device.d.ts.map +1 -0
  113. package/lib-es/e2e/enum/Device.js +10 -0
  114. package/lib-es/e2e/enum/Device.js.map +1 -0
  115. package/lib-es/e2e/enum/Swap.d.ts +2 -1
  116. package/lib-es/e2e/enum/Swap.d.ts.map +1 -1
  117. package/lib-es/e2e/enum/Swap.js +12 -10
  118. package/lib-es/e2e/enum/Swap.js.map +1 -1
  119. package/lib-es/e2e/families/cardano.d.ts.map +1 -1
  120. package/lib-es/e2e/families/cardano.js +56 -27
  121. package/lib-es/e2e/families/cardano.js.map +1 -1
  122. package/lib-es/e2e/families/evm.d.ts.map +1 -1
  123. package/lib-es/e2e/families/evm.js +2 -1
  124. package/lib-es/e2e/families/evm.js.map +1 -1
  125. package/lib-es/e2e/families/solana.d.ts.map +1 -1
  126. package/lib-es/e2e/families/solana.js +5 -2
  127. package/lib-es/e2e/families/solana.js.map +1 -1
  128. package/lib-es/e2e/index.d.ts +2 -0
  129. package/lib-es/e2e/index.d.ts.map +1 -1
  130. package/lib-es/e2e/models/BuySell.d.ts +11 -0
  131. package/lib-es/e2e/models/BuySell.d.ts.map +1 -0
  132. package/lib-es/e2e/models/BuySell.js +2 -0
  133. package/lib-es/e2e/models/BuySell.js.map +1 -0
  134. package/lib-es/e2e/models/Transaction.d.ts +5 -5
  135. package/lib-es/e2e/models/Transaction.d.ts.map +1 -1
  136. package/lib-es/e2e/models/Transaction.js.map +1 -1
  137. package/lib-es/e2e/speculos.d.ts +6 -1
  138. package/lib-es/e2e/speculos.d.ts.map +1 -1
  139. package/lib-es/e2e/speculos.js +69 -39
  140. package/lib-es/e2e/speculos.js.map +1 -1
  141. package/lib-es/e2e/speculosCI.d.ts +5 -0
  142. package/lib-es/e2e/speculosCI.d.ts.map +1 -0
  143. package/lib-es/e2e/speculosCI.js +121 -0
  144. package/lib-es/e2e/speculosCI.js.map +1 -0
  145. package/lib-es/families/hedera/logic.d.ts +2 -0
  146. package/lib-es/families/hedera/logic.d.ts.map +1 -0
  147. package/lib-es/families/hedera/logic.js +3 -0
  148. package/lib-es/families/hedera/logic.js.map +1 -0
  149. package/lib-es/featureFlags/defaultFeatures.d.ts.map +1 -1
  150. package/lib-es/featureFlags/defaultFeatures.js +1 -0
  151. package/lib-es/featureFlags/defaultFeatures.js.map +1 -1
  152. package/lib-es/featureFlags/useFeature.d.ts +1 -1
  153. package/lib-es/featureFlags/useFeature.d.ts.map +1 -1
  154. package/lib-es/hw/actions/manager.d.ts +1 -1
  155. package/lib-es/hw/actions/manager.d.ts.map +1 -1
  156. package/lib-es/hw/connectApp.d.ts.map +1 -1
  157. package/lib-es/hw/connectApp.js +57 -6
  158. package/lib-es/hw/connectApp.js.map +1 -1
  159. package/lib-es/hw/connectAppEventMapper.d.ts +29 -0
  160. package/lib-es/hw/connectAppEventMapper.d.ts.map +1 -0
  161. package/lib-es/hw/connectAppEventMapper.js +296 -0
  162. package/lib-es/hw/connectAppEventMapper.js.map +1 -0
  163. package/lib-es/hw/connectManager.d.ts +3 -2
  164. package/lib-es/hw/connectManager.d.ts.map +1 -1
  165. package/lib-es/hw/connectManager.js +34 -4
  166. package/lib-es/hw/connectManager.js.map +1 -1
  167. package/lib-es/hw/connectManagerEventMapper.d.ts +16 -0
  168. package/lib-es/hw/connectManagerEventMapper.d.ts.map +1 -0
  169. package/lib-es/hw/connectManagerEventMapper.js +74 -0
  170. package/lib-es/hw/connectManagerEventMapper.js.map +1 -0
  171. package/lib-es/market/hooks/useLargeMoverChartData.d.ts +18 -0
  172. package/lib-es/market/hooks/useLargeMoverChartData.d.ts.map +1 -0
  173. package/lib-es/market/hooks/useLargeMoverChartData.js +24 -0
  174. package/lib-es/market/hooks/useLargeMoverChartData.js.map +1 -0
  175. package/lib-es/market/hooks/useLargeMoverCurrencies.d.ts +13 -0
  176. package/lib-es/market/hooks/useLargeMoverCurrencies.d.ts.map +1 -0
  177. package/lib-es/market/hooks/useLargeMoverCurrencies.js +25 -0
  178. package/lib-es/market/hooks/useLargeMoverCurrencies.js.map +1 -0
  179. package/lib-es/notifications/AnnouncementProvider/index.d.ts.map +1 -1
  180. package/lib-es/notifications/AnnouncementProvider/index.js +12 -10
  181. package/lib-es/notifications/AnnouncementProvider/index.js.map +1 -1
  182. package/lib-es/notifications/AnnouncementProvider/machine.d.ts +1 -4
  183. package/lib-es/notifications/AnnouncementProvider/machine.d.ts.map +1 -1
  184. package/lib-es/notifications/AnnouncementProvider/machine.js +9 -8
  185. package/lib-es/notifications/AnnouncementProvider/machine.js.map +1 -1
  186. package/lib-es/notifications/ServiceStatusProvider/index.d.ts.map +1 -1
  187. package/lib-es/notifications/ServiceStatusProvider/index.js +5 -4
  188. package/lib-es/notifications/ServiceStatusProvider/index.js.map +1 -1
  189. package/lib-es/notifications/ServiceStatusProvider/machine.d.ts +1 -4
  190. package/lib-es/notifications/ServiceStatusProvider/machine.d.ts.map +1 -1
  191. package/lib-es/notifications/ServiceStatusProvider/machine.js +4 -4
  192. package/lib-es/notifications/ServiceStatusProvider/machine.js.map +1 -1
  193. package/lib-es/wallet-api/ModularDrawer/types.d.ts +63 -0
  194. package/lib-es/wallet-api/ModularDrawer/types.d.ts.map +1 -0
  195. package/lib-es/wallet-api/ModularDrawer/types.js +22 -0
  196. package/lib-es/wallet-api/ModularDrawer/types.js.map +1 -0
  197. package/lib-es/wallet-api/ModularDrawer/utils.d.ts +5 -0
  198. package/lib-es/wallet-api/ModularDrawer/utils.d.ts.map +1 -0
  199. package/lib-es/wallet-api/ModularDrawer/utils.js +25 -0
  200. package/lib-es/wallet-api/ModularDrawer/utils.js.map +1 -0
  201. package/lib-es/wallet-api/react.d.ts +2 -0
  202. package/lib-es/wallet-api/react.d.ts.map +1 -1
  203. package/lib-es/wallet-api/react.js +2 -1
  204. package/lib-es/wallet-api/react.js.map +1 -1
  205. package/package.json +54 -53
  206. package/src/apps/support.ts +11 -0
  207. package/src/e2e/enum/Account.ts +363 -362
  208. package/src/e2e/enum/Device.ts +7 -0
  209. package/src/e2e/enum/Swap.ts +10 -9
  210. package/src/e2e/families/cardano.ts +63 -28
  211. package/src/e2e/families/evm.ts +2 -1
  212. package/src/e2e/families/solana.ts +5 -2
  213. package/src/e2e/models/BuySell.ts +12 -0
  214. package/src/e2e/models/Transaction.ts +5 -5
  215. package/src/e2e/speculos.ts +75 -41
  216. package/src/e2e/speculosCI.ts +161 -0
  217. package/src/families/hedera/logic.ts +2 -0
  218. package/src/featureFlags/defaultFeatures.ts +1 -0
  219. package/src/hw/actions/manager.ts +1 -1
  220. package/src/hw/connectApp.ts +245 -178
  221. package/src/hw/connectAppEventMapper.ts +364 -0
  222. package/src/hw/connectManager.ts +116 -74
  223. package/src/hw/connectManagerEventMapper.ts +109 -0
  224. package/src/market/hooks/useLargeMoverChartData.ts +38 -0
  225. package/src/market/hooks/useLargeMoverCurrencies.ts +36 -0
  226. package/src/notifications/AnnouncementProvider/index.tsx +21 -17
  227. package/src/notifications/AnnouncementProvider/machine.ts +9 -8
  228. package/src/notifications/ServiceStatusProvider/index.tsx +11 -8
  229. package/src/notifications/ServiceStatusProvider/machine.ts +4 -4
  230. package/src/wallet-api/ModularDrawer/types.ts +45 -0
  231. package/src/wallet-api/ModularDrawer/utils.ts +37 -0
  232. package/src/wallet-api/react.ts +37 -31
  233. package/lib/index.d.ts +0 -2
  234. package/lib/index.d.ts.map +0 -1
  235. package/lib/index.js.map +0 -1
  236. package/lib/market/hooks/useLargeMoverDataProvider.d.ts +0 -17
  237. package/lib/market/hooks/useLargeMoverDataProvider.d.ts.map +0 -1
  238. package/lib/market/hooks/useLargeMoverDataProvider.js +0 -48
  239. package/lib/market/hooks/useLargeMoverDataProvider.js.map +0 -1
  240. package/lib-es/index.d.ts +0 -1
  241. package/lib-es/index.d.ts.map +0 -1
  242. package/lib-es/index.js +0 -2
  243. package/lib-es/index.js.map +0 -1
  244. package/lib-es/market/hooks/useLargeMoverDataProvider.d.ts +0 -17
  245. package/lib-es/market/hooks/useLargeMoverDataProvider.d.ts.map +0 -1
  246. package/lib-es/market/hooks/useLargeMoverDataProvider.js +0 -44
  247. package/lib-es/market/hooks/useLargeMoverDataProvider.js.map +0 -1
  248. package/src/index.ts +0 -0
  249. package/src/market/hooks/useLargeMoverDataProvider.ts +0 -70
@@ -0,0 +1,7 @@
1
+ export class Device {
2
+ constructor(public readonly name: string) {}
3
+
4
+ static readonly LNS = "nanoS";
5
+ static readonly LNX = "nanoX";
6
+ static readonly LNSP = "nanoSP";
7
+ }
@@ -4,16 +4,17 @@ export class Provider {
4
4
  public readonly uiName: string,
5
5
  public readonly kyc: boolean,
6
6
  public readonly isNative: boolean,
7
+ public readonly availableOnLns: boolean,
7
8
  ) {}
8
- static readonly CHANGELLY = new Provider("changelly", "Changelly", false, true);
9
- static readonly EXODUS = new Provider("exodus", "Exodus", false, true);
10
- static readonly ONE_INCH = new Provider("oneinch", "1inch", false, false);
11
- static readonly PARASWAP = new Provider("paraswap", "Paraswap", false, false);
12
- static readonly MOONPAY = new Provider("moonpay", "MoonPay", true, false);
13
- static readonly THORCHAIN = new Provider("thorswap", "THORChain", false, true);
14
- static readonly UNISWAP = new Provider("uniswap", "Uniswap", false, false);
15
- static readonly LIFI = new Provider("lifi", "LI.FI", false, true);
16
- static readonly CIC = new Provider("cic", "CIC", false, true);
9
+ static readonly CHANGELLY = new Provider("changelly", "Changelly", false, true, true);
10
+ static readonly EXODUS = new Provider("exodus", "Exodus", false, true, true);
11
+ static readonly ONE_INCH = new Provider("oneinch", "1inch", false, false, true);
12
+ static readonly PARASWAP = new Provider("paraswap", "Paraswap", false, false, true);
13
+ static readonly MOONPAY = new Provider("moonpay", "MoonPay", true, false, true);
14
+ static readonly THORCHAIN = new Provider("thorswap", "THORChain", false, true, false);
15
+ static readonly UNISWAP = new Provider("uniswap", "Uniswap", false, false, false);
16
+ static readonly LIFI = new Provider("lifi", "LI.FI", false, true, false);
17
+ static readonly CIC = new Provider("cic", "CIC", false, true, true);
17
18
 
18
19
  static getNameByUiName(uiName: string): string {
19
20
  const provider = Object.values(Provider).find(p => p.uiName === uiName);
@@ -1,43 +1,78 @@
1
1
  import expect from "expect";
2
2
  import { Transaction } from "../models/Transaction";
3
- import { pressBoth, pressUntilTextFound, containsSubstringInEvent, waitFor } from "../speculos";
3
+ import {
4
+ pressBoth,
5
+ pressUntilTextFound,
6
+ containsSubstringInEvent,
7
+ waitFor,
8
+ pressRightButton,
9
+ } from "../speculos";
4
10
  import { DeviceLabels } from "../enum/DeviceLabels";
11
+ import { Device } from "../enum/Device";
5
12
 
6
13
  export async function sendCardano(tx: Transaction) {
14
+ const isNanoS = process.env.SPECULOS_DEVICE === Device.LNS;
7
15
  await waitFor(DeviceLabels.NEW_ORDINARY);
8
- await pressBoth();
9
- await pressUntilTextFound(DeviceLabels.SEND_TO_ADDRESS_2);
10
- await pressBoth();
16
+ await (isNanoS ? pressRightButton() : pressBoth());
17
+ if (isNanoS) {
18
+ await waitFor(DeviceLabels.SEND_TO_ADDRESS);
19
+ await pressBoth();
20
+ } else {
21
+ await pressUntilTextFound(DeviceLabels.SEND_TO_ADDRESS_2);
22
+ await pressBoth();
23
+ }
11
24
  const events = await pressUntilTextFound(DeviceLabels.SEND);
12
- const isAmountCorrect = containsSubstringInEvent(tx.amount, events);
13
- expect(isAmountCorrect).toBeTruthy();
25
+ if (!isNanoS) {
26
+ const isAmountCorrect = containsSubstringInEvent(tx.amount, events);
27
+ expect(isAmountCorrect).toBeTruthy();
28
+ }
14
29
  await pressBoth();
15
30
  await waitFor(DeviceLabels.TRANSACTION_FEE);
16
31
  await pressBoth();
17
32
  await waitFor(DeviceLabels.CONFIRM_TRANSACTION);
18
- await pressBoth();
19
-
20
- const isAddressCorrect = containsSubstringInEvent(tx.accountToCredit.address, events);
21
- expect(isAddressCorrect).toBeTruthy();
33
+ if (isNanoS) {
34
+ await pressRightButton();
35
+ } else {
36
+ await pressBoth();
37
+ const isAddressCorrect = containsSubstringInEvent(tx.accountToCredit.address, events);
38
+ expect(isAddressCorrect).toBeTruthy();
39
+ }
22
40
  }
23
41
 
24
42
  export async function delegateCardano() {
25
- await waitFor(DeviceLabels.NEW_ORDINARY);
26
- await pressBoth();
27
- await waitFor(DeviceLabels.TRANSACTION_FEE);
28
- await pressBoth();
29
- await waitFor(DeviceLabels.REGISTER);
30
- await pressBoth();
31
- await waitFor(DeviceLabels.STAKE_KEY);
32
- await pressBoth();
33
- await waitFor(DeviceLabels.CONFIRM);
34
- await pressBoth();
35
- await waitFor(DeviceLabels.DELEGATE_STAKE);
36
- await pressBoth();
37
- await waitFor(DeviceLabels.STAKE_KEY);
38
- await pressBoth();
39
- await waitFor(DeviceLabels.CONFIRM);
40
- await pressBoth();
41
- await waitFor(DeviceLabels.CONFIRM);
42
- await pressBoth();
43
+ const commonSteps = [
44
+ { label: DeviceLabels.NEW_ORDINARY, action: "both" },
45
+ { label: DeviceLabels.TRANSACTION_FEE, action: "both" },
46
+ { label: DeviceLabels.REGISTER, action: "both" },
47
+ { label: DeviceLabels.STAKE_KEY, action: "both" },
48
+ { label: DeviceLabels.CONFIRM, action: "both" },
49
+ { label: DeviceLabels.DELEGATE_STAKE, action: "both" },
50
+ { label: DeviceLabels.STAKE_KEY, action: "both" },
51
+ { label: DeviceLabels.CONFIRM, action: "both" },
52
+ { label: DeviceLabels.CONFIRM, action: "both" },
53
+ ];
54
+
55
+ const LNSSpecificSteps = [
56
+ { label: DeviceLabels.NEW_ORDINARY, action: "right" },
57
+ { label: DeviceLabels.TRANSACTION_FEE, action: "both" },
58
+ { label: DeviceLabels.REGISTER, action: "both" },
59
+ { label: DeviceLabels.STAKE_KEY, action: "both" },
60
+ { label: DeviceLabels.CONFIRM, action: "right" },
61
+ { label: DeviceLabels.DELEGATE_STAKE, action: "both" },
62
+ { label: DeviceLabels.STAKE_KEY, action: "both" },
63
+ { label: DeviceLabels.CONFIRM, action: "right" },
64
+ { label: DeviceLabels.CONFIRM, action: "right" },
65
+ ];
66
+
67
+ const stepsToExecute =
68
+ process.env.SPECULOS_DEVICE === Device.LNS ? LNSSpecificSteps : commonSteps;
69
+
70
+ for (const step of stepsToExecute) {
71
+ await waitFor(step.label);
72
+ if (step.action === "both") {
73
+ await pressBoth();
74
+ } else if (step.action === "right") {
75
+ await pressRightButton();
76
+ }
77
+ }
43
78
  }
@@ -2,12 +2,13 @@ import expect from "expect";
2
2
  import { NFTTransaction, Transaction } from "../models/Transaction";
3
3
  import { pressBoth, pressUntilTextFound, containsSubstringInEvent, waitFor } from "../speculos";
4
4
  import { DeviceLabels } from "../enum/DeviceLabels";
5
+ import { Device } from "../enum/Device";
5
6
 
6
7
  export async function sendEVM(tx: Transaction) {
7
8
  const events = await pressUntilTextFound(DeviceLabels.ACCEPT);
8
9
  const isAmountCorrect = containsSubstringInEvent(tx.amount, events);
9
10
  expect(isAmountCorrect).toBeTruthy();
10
- if (tx.accountToCredit.ensName) {
11
+ if (tx.accountToCredit.ensName && process.env.SPECULOS_DEVICE !== Device.LNS) {
11
12
  const isENSNameCorrect = containsSubstringInEvent(tx.accountToCredit.ensName, events);
12
13
  expect(isENSNameCorrect).toBeTruthy();
13
14
  } else {
@@ -1,6 +1,7 @@
1
1
  import expect from "expect";
2
2
  import { pressBoth, pressUntilTextFound, waitFor, containsSubstringInEvent } from "../speculos";
3
3
  import { DeviceLabels } from "../enum/DeviceLabels";
4
+ import { Device } from "../enum/Device";
4
5
  import { Transaction } from "../models/Transaction";
5
6
 
6
7
  export async function delegateSolana() {
@@ -13,8 +14,10 @@ export async function sendSolana(tx: Transaction) {
13
14
  const events = await pressUntilTextFound(DeviceLabels.APPROVE);
14
15
  const isAmountCorrect = containsSubstringInEvent(tx.amount, events);
15
16
  expect(isAmountCorrect).toBeTruthy();
16
- const isAddressCorrect = containsSubstringInEvent(tx.accountToCredit.address, events);
17
- expect(isAddressCorrect).toBeTruthy();
17
+ if (process.env.SPECULOS_DEVICE !== Device.LNS) {
18
+ const isAddressCorrect = containsSubstringInEvent(tx.accountToCredit.address, events);
19
+ expect(isAddressCorrect).toBeTruthy();
20
+ }
18
21
 
19
22
  await pressBoth();
20
23
  }
@@ -0,0 +1,12 @@
1
+ import { AccountType } from "../enum/Account";
2
+
3
+ export interface Fiat {
4
+ locale: string;
5
+ currencyTicker: string;
6
+ }
7
+
8
+ export interface BuySell {
9
+ crypto: AccountType;
10
+ fiat: Fiat;
11
+ amount: string;
12
+ }
@@ -1,13 +1,13 @@
1
1
  import { Fee } from "../enum/Fee";
2
- import { Account } from "../enum/Account";
2
+ import { AccountType } from "../enum/Account";
3
3
  import { Nft } from "../enum/Nft";
4
4
 
5
5
  export type TransactionType = Transaction;
6
6
 
7
7
  export class Transaction {
8
8
  constructor(
9
- public accountToDebit: Account,
10
- public accountToCredit: Account,
9
+ public accountToDebit: AccountType,
10
+ public accountToCredit: AccountType,
11
11
  public amount: string,
12
12
  public speed?: Fee,
13
13
  public memoTag?: string,
@@ -16,8 +16,8 @@ export class Transaction {
16
16
 
17
17
  export class NFTTransaction extends Transaction {
18
18
  constructor(
19
- accountToDebit: Account,
20
- accountToCredit: Account,
19
+ accountToDebit: AccountType,
20
+ accountToCredit: AccountType,
21
21
  public nft: Nft,
22
22
  speed?: Fee,
23
23
  memoTag?: string,
@@ -7,7 +7,7 @@ import {
7
7
  findLatestAppCandidate,
8
8
  SpeculosTransport,
9
9
  } from "../load/speculos";
10
- import { SpeculosDevice } from "@ledgerhq/speculos-transport";
10
+ import { createSpeculosDeviceCI, releaseSpeculosDeviceCI } from "./speculosCI";
11
11
  import type { AppCandidate } from "@ledgerhq/coin-framework/bot/types";
12
12
  import { DeviceModelId } from "@ledgerhq/devices";
13
13
  import { CryptoCurrency } from "@ledgerhq/types-cryptoassets";
@@ -16,6 +16,7 @@ import { getEnv } from "@ledgerhq/live-env";
16
16
  import { getCryptoCurrencyById } from "../currencies";
17
17
  import { DeviceLabels } from "../e2e/enum/DeviceLabels";
18
18
  import { Account } from "./enum/Account";
19
+ import { Device as CryptoWallet } from "./enum/Device";
19
20
  import { Currency } from "./enum/Currency";
20
21
  import expect from "expect";
21
22
  import { sendBTCBasedCoin } from "./families/bitcoin";
@@ -37,6 +38,8 @@ import { NFTTransaction, Transaction } from "./models/Transaction";
37
38
  import { Delegate } from "./models/Delegate";
38
39
  import { Swap } from "./models/Swap";
39
40
 
41
+ const isSpeculosRemote = process.env.REMOTE_SPECULOS === "true";
42
+
40
43
  export type Spec = {
41
44
  currency?: CryptoCurrency;
42
45
  appQuery: {
@@ -50,6 +53,10 @@ export type Spec = {
50
53
  };
51
54
 
52
55
  export type Dependency = { name: string; appVersion?: string };
56
+ export type SpeculosDevice = {
57
+ id: string;
58
+ port: number;
59
+ };
53
60
 
54
61
  export function setExchangeDependencies(dependencies: Dependency[]) {
55
62
  const map = new Map<string, Dependency>();
@@ -61,6 +68,19 @@ export function setExchangeDependencies(dependencies: Dependency[]) {
61
68
  specs["Exchange"].dependencies = Array.from(map.values());
62
69
  }
63
70
 
71
+ export function getSpeculosModel() {
72
+ const speculosDevice = process.env.SPECULOS_DEVICE;
73
+ switch (speculosDevice) {
74
+ case CryptoWallet.LNS:
75
+ return DeviceModelId.nanoS;
76
+ case CryptoWallet.LNX:
77
+ return DeviceModelId.nanoX;
78
+ case CryptoWallet.LNSP:
79
+ default:
80
+ return DeviceModelId.nanoSP;
81
+ }
82
+ }
83
+
64
84
  type Specs = {
65
85
  [key: string]: Spec;
66
86
  };
@@ -75,7 +95,7 @@ export const specs: Specs = {
75
95
  Bitcoin: {
76
96
  currency: getCryptoCurrencyById("bitcoin"),
77
97
  appQuery: {
78
- model: DeviceModelId.nanoSP,
98
+ model: getSpeculosModel(),
79
99
  appName: "Bitcoin",
80
100
  },
81
101
  dependency: "",
@@ -83,21 +103,21 @@ export const specs: Specs = {
83
103
  Aptos: {
84
104
  currency: getCryptoCurrencyById("aptos"),
85
105
  appQuery: {
86
- model: DeviceModelId.nanoSP,
106
+ model: getSpeculosModel(),
87
107
  appName: "Aptos",
88
108
  },
89
109
  dependency: "",
90
110
  },
91
111
  Exchange: {
92
112
  appQuery: {
93
- model: DeviceModelId.nanoSP,
113
+ model: getSpeculosModel(),
94
114
  appName: "Exchange",
95
115
  },
96
116
  dependencies: [],
97
117
  },
98
118
  LedgerSync: {
99
119
  appQuery: {
100
- model: DeviceModelId.nanoX,
120
+ model: getSpeculosModel(),
101
121
  appName: "Ledger Sync",
102
122
  },
103
123
  dependency: "",
@@ -105,7 +125,7 @@ export const specs: Specs = {
105
125
  Dogecoin: {
106
126
  currency: getCryptoCurrencyById("dogecoin"),
107
127
  appQuery: {
108
- model: DeviceModelId.nanoSP,
128
+ model: getSpeculosModel(),
109
129
  appName: "Dogecoin",
110
130
  },
111
131
  dependency: "",
@@ -113,7 +133,7 @@ export const specs: Specs = {
113
133
  Ethereum: {
114
134
  currency: getCryptoCurrencyById("ethereum"),
115
135
  appQuery: {
116
- model: DeviceModelId.nanoSP,
136
+ model: getSpeculosModel(),
117
137
  appName: "Ethereum",
118
138
  },
119
139
  dependency: "",
@@ -121,7 +141,7 @@ export const specs: Specs = {
121
141
  Ethereum_Holesky: {
122
142
  currency: getCryptoCurrencyById("ethereum_holesky"),
123
143
  appQuery: {
124
- model: DeviceModelId.nanoSP,
144
+ model: getSpeculosModel(),
125
145
  appName: "Ethereum",
126
146
  },
127
147
  dependency: "",
@@ -129,7 +149,7 @@ export const specs: Specs = {
129
149
  Ethereum_Sepolia: {
130
150
  currency: getCryptoCurrencyById("ethereum_sepolia"),
131
151
  appQuery: {
132
- model: DeviceModelId.nanoSP,
152
+ model: getSpeculosModel(),
133
153
  appName: "Ethereum",
134
154
  },
135
155
  dependency: "",
@@ -137,7 +157,7 @@ export const specs: Specs = {
137
157
  Ethereum_Classic: {
138
158
  currency: getCryptoCurrencyById("ethereum_classic"),
139
159
  appQuery: {
140
- model: DeviceModelId.nanoSP,
160
+ model: getSpeculosModel(),
141
161
  appName: "Ethereum Classic",
142
162
  },
143
163
  dependency: "Ethereum",
@@ -145,7 +165,7 @@ export const specs: Specs = {
145
165
  Bitcoin_Testnet: {
146
166
  currency: getCryptoCurrencyById("bitcoin_testnet"),
147
167
  appQuery: {
148
- model: DeviceModelId.nanoSP,
168
+ model: getSpeculosModel(),
149
169
  appName: "Bitcoin Test",
150
170
  },
151
171
  dependency: "",
@@ -153,7 +173,7 @@ export const specs: Specs = {
153
173
  Solana: {
154
174
  currency: getCryptoCurrencyById("solana"),
155
175
  appQuery: {
156
- model: DeviceModelId.nanoSP,
176
+ model: getSpeculosModel(),
157
177
  appName: "Solana",
158
178
  },
159
179
  dependency: "",
@@ -161,7 +181,7 @@ export const specs: Specs = {
161
181
  Cardano: {
162
182
  currency: getCryptoCurrencyById("cardano"),
163
183
  appQuery: {
164
- model: DeviceModelId.nanoSP,
184
+ model: getSpeculosModel(),
165
185
  appName: "CardanoADA",
166
186
  },
167
187
  dependency: "",
@@ -169,7 +189,7 @@ export const specs: Specs = {
169
189
  Polkadot: {
170
190
  currency: getCryptoCurrencyById("polkadot"),
171
191
  appQuery: {
172
- model: DeviceModelId.nanoSP,
192
+ model: getSpeculosModel(),
173
193
  appName: "Polkadot",
174
194
  },
175
195
  dependency: "",
@@ -177,7 +197,7 @@ export const specs: Specs = {
177
197
  Tron: {
178
198
  currency: getCryptoCurrencyById("tron"),
179
199
  appQuery: {
180
- model: DeviceModelId.nanoSP,
200
+ model: getSpeculosModel(),
181
201
  appName: "Tron",
182
202
  },
183
203
  dependency: "",
@@ -185,7 +205,7 @@ export const specs: Specs = {
185
205
  XRP: {
186
206
  currency: getCryptoCurrencyById("ripple"),
187
207
  appQuery: {
188
- model: DeviceModelId.nanoSP,
208
+ model: getSpeculosModel(),
189
209
  appName: "XRP",
190
210
  },
191
211
  dependency: "",
@@ -193,7 +213,7 @@ export const specs: Specs = {
193
213
  Stellar: {
194
214
  currency: getCryptoCurrencyById("stellar"),
195
215
  appQuery: {
196
- model: DeviceModelId.nanoSP,
216
+ model: getSpeculosModel(),
197
217
  appName: "Stellar",
198
218
  },
199
219
  dependency: "",
@@ -201,7 +221,7 @@ export const specs: Specs = {
201
221
  Bitcoin_Cash: {
202
222
  currency: getCryptoCurrencyById("bitcoin_cash"),
203
223
  appQuery: {
204
- model: DeviceModelId.nanoSP,
224
+ model: getSpeculosModel(),
205
225
  appName: "Bitcoin Cash",
206
226
  },
207
227
  dependency: "",
@@ -209,7 +229,7 @@ export const specs: Specs = {
209
229
  Algorand: {
210
230
  currency: getCryptoCurrencyById("algorand"),
211
231
  appQuery: {
212
- model: DeviceModelId.nanoSP,
232
+ model: getSpeculosModel(),
213
233
  appName: "Algorand",
214
234
  },
215
235
  dependency: "",
@@ -217,7 +237,7 @@ export const specs: Specs = {
217
237
  Cosmos: {
218
238
  currency: getCryptoCurrencyById("cosmos"),
219
239
  appQuery: {
220
- model: DeviceModelId.nanoSP,
240
+ model: getSpeculosModel(),
221
241
  appName: "Cosmos",
222
242
  },
223
243
  dependency: "",
@@ -225,7 +245,7 @@ export const specs: Specs = {
225
245
  Tezos: {
226
246
  currency: getCryptoCurrencyById("tezos"),
227
247
  appQuery: {
228
- model: DeviceModelId.nanoSP,
248
+ model: getSpeculosModel(),
229
249
  appName: "TezosWallet",
230
250
  },
231
251
  dependency: "",
@@ -233,7 +253,7 @@ export const specs: Specs = {
233
253
  Polygon: {
234
254
  currency: getCryptoCurrencyById("polygon"),
235
255
  appQuery: {
236
- model: DeviceModelId.nanoSP,
256
+ model: getSpeculosModel(),
237
257
  appName: "Ethereum",
238
258
  },
239
259
  dependency: "",
@@ -241,7 +261,7 @@ export const specs: Specs = {
241
261
  Binance_Smart_Chain: {
242
262
  currency: getCryptoCurrencyById("bsc"),
243
263
  appQuery: {
244
- model: DeviceModelId.nanoSP,
264
+ model: getSpeculosModel(),
245
265
  appName: "Ethereum",
246
266
  },
247
267
  dependency: "",
@@ -249,7 +269,7 @@ export const specs: Specs = {
249
269
  Ton: {
250
270
  currency: getCryptoCurrencyById("ton"),
251
271
  appQuery: {
252
- model: DeviceModelId.nanoSP,
272
+ model: getSpeculosModel(),
253
273
  appName: "TON",
254
274
  },
255
275
  dependency: "",
@@ -257,7 +277,7 @@ export const specs: Specs = {
257
277
  Near: {
258
278
  currency: getCryptoCurrencyById("near"),
259
279
  appQuery: {
260
- model: DeviceModelId.nanoSP,
280
+ model: getSpeculosModel(),
261
281
  appName: "NEAR",
262
282
  },
263
283
  dependency: "",
@@ -265,7 +285,7 @@ export const specs: Specs = {
265
285
  Multivers_X: {
266
286
  currency: getCryptoCurrencyById("elrond"),
267
287
  appQuery: {
268
- model: DeviceModelId.nanoSP,
288
+ model: getSpeculosModel(),
269
289
  appName: "MultiversX",
270
290
  },
271
291
  dependency: "",
@@ -273,7 +293,7 @@ export const specs: Specs = {
273
293
  Osmosis: {
274
294
  currency: getCryptoCurrencyById("osmo"),
275
295
  appQuery: {
276
- model: DeviceModelId.nanoSP,
296
+ model: getSpeculosModel(),
277
297
  appName: "Cosmos",
278
298
  },
279
299
  dependency: "",
@@ -281,7 +301,7 @@ export const specs: Specs = {
281
301
  Injective: {
282
302
  currency: getCryptoCurrencyById("injective"),
283
303
  appQuery: {
284
- model: DeviceModelId.nanoSP,
304
+ model: getSpeculosModel(),
285
305
  appName: "Cosmos",
286
306
  },
287
307
  dependency: "",
@@ -290,7 +310,7 @@ export const specs: Specs = {
290
310
  Celo: {
291
311
  currency: getCryptoCurrencyById("celo"),
292
312
  appQuery: {
293
- model: DeviceModelId.nanoSP,
313
+ model: getSpeculosModel(),
294
314
  appName: "Celo",
295
315
  },
296
316
  dependency: "",
@@ -298,7 +318,7 @@ export const specs: Specs = {
298
318
  Litecoin: {
299
319
  currency: getCryptoCurrencyById("litecoin"),
300
320
  appQuery: {
301
- model: DeviceModelId.nanoSP,
321
+ model: getSpeculosModel(),
302
322
  appName: "Litecoin",
303
323
  },
304
324
  dependency: "",
@@ -362,9 +382,14 @@ export async function startSpeculos(
362
382
  coinapps,
363
383
  onSpeculosDeviceCreated,
364
384
  };
365
-
366
385
  try {
367
- return await createSpeculosDevice(deviceParams);
386
+ const device = isSpeculosRemote
387
+ ? await createSpeculosDeviceCI(deviceParams)
388
+ : await createSpeculosDevice(deviceParams).then(device => {
389
+ invariant(device.ports.apiPort, "[E2E] Speculos apiPort is not defined");
390
+ return { id: device.id, port: device.ports.apiPort };
391
+ });
392
+ return device;
368
393
  } catch (e: unknown) {
369
394
  console.error(e);
370
395
  log("engine", `test ${testName} failed with ${String(e)}`);
@@ -374,7 +399,9 @@ export async function startSpeculos(
374
399
  export async function stopSpeculos(deviceId: string | undefined) {
375
400
  if (deviceId) {
376
401
  log("engine", `test ${deviceId} finished`);
377
- await releaseSpeculosDevice(deviceId);
402
+ isSpeculosRemote
403
+ ? await releaseSpeculosDeviceCI(deviceId)
404
+ : await releaseSpeculosDevice(deviceId);
378
405
  }
379
406
  }
380
407
 
@@ -388,11 +415,12 @@ interface ResponseData {
388
415
 
389
416
  export async function waitFor(text: string, maxAttempts: number = 10): Promise<string[]> {
390
417
  const speculosApiPort = getEnv("SPECULOS_API_PORT");
418
+ const speculosAddress = process.env.SPECULOS_ADDRESS || "http://127.0.0.1";
391
419
  let attempts = 0;
392
420
  let textFound: boolean = false;
393
421
  while (attempts < maxAttempts && !textFound) {
394
422
  const response = await axios.get<ResponseData>(
395
- `http://127.0.0.1:${speculosApiPort}/events?stream=false&currentscreenonly=true`,
423
+ `${speculosAddress}:${speculosApiPort}/events?stream=false&currentscreenonly=true`,
396
424
  );
397
425
  const responseData = response.data;
398
426
  const texts = responseData.events.map(event => event.text);
@@ -409,7 +437,8 @@ export async function waitFor(text: string, maxAttempts: number = 10): Promise<s
409
437
 
410
438
  export async function pressBoth() {
411
439
  const speculosApiPort = getEnv("SPECULOS_API_PORT");
412
- await axios.post(`http://127.0.0.1:${speculosApiPort}/button/both`, {
440
+ const speculosAddress = process.env.SPECULOS_ADDRESS || "http://127.0.0.1";
441
+ await axios.post(`${speculosAddress}:${speculosApiPort}/button/both`, {
413
442
  action: "press-and-release",
414
443
  });
415
444
  }
@@ -427,7 +456,7 @@ export async function pressUntilTextFound(
427
456
  return await fetchAllEvents(speculosApiPort);
428
457
  }
429
458
 
430
- await pressRightButton(speculosApiPort);
459
+ await pressRightButton();
431
460
  await waitForTimeOut(200);
432
461
  }
433
462
 
@@ -437,21 +466,25 @@ export async function pressUntilTextFound(
437
466
  }
438
467
 
439
468
  async function fetchCurrentScreenTexts(speculosApiPort: number): Promise<string> {
469
+ const speculosAddress = process.env.SPECULOS_ADDRESS || "http://127.0.0.1";
440
470
  const response = await axios.get<ResponseData>(
441
- `http://127.0.0.1:${speculosApiPort}/events?stream=false&currentscreenonly=true`,
471
+ `${speculosAddress}:${speculosApiPort}/events?stream=false&currentscreenonly=true`,
442
472
  );
443
473
  return response.data.events.map(event => event.text).join("");
444
474
  }
445
475
 
446
476
  async function fetchAllEvents(speculosApiPort: number): Promise<string[]> {
477
+ const speculosAddress = process.env.SPECULOS_ADDRESS || "http://127.0.0.1";
447
478
  const response = await axios.get<ResponseData>(
448
- `http://127.0.0.1:${speculosApiPort}/events?stream=false&currentscreenonly=false`,
479
+ `${speculosAddress}:${speculosApiPort}/events?stream=false&currentscreenonly=false`,
449
480
  );
450
481
  return response.data.events.map(event => event.text);
451
482
  }
452
483
 
453
- async function pressRightButton(speculosApiPort: number): Promise<void> {
454
- await axios.post(`http://127.0.0.1:${speculosApiPort}/button/right`, {
484
+ export async function pressRightButton(): Promise<void> {
485
+ const speculosApiPort = getEnv("SPECULOS_API_PORT");
486
+ const speculosAddress = process.env.SPECULOS_ADDRESS || "http://127.0.0.1";
487
+ await axios.post(`${speculosAddress}:${speculosApiPort}/button/right`, {
455
488
  action: "press-and-release",
456
489
  });
457
490
  }
@@ -471,9 +504,10 @@ export function containsSubstringInEvent(targetString: string, events: string[])
471
504
  }
472
505
 
473
506
  export async function takeScreenshot(port?: number): Promise<Buffer | undefined> {
507
+ const speculosAddress = process.env.SPECULOS_ADDRESS || "http://127.0.0.1";
474
508
  const speculosApiPort = port ?? getEnv("SPECULOS_API_PORT");
475
509
  try {
476
- const response = await axios.get(`http://127.0.0.1:${speculosApiPort}/screenshot`, {
510
+ const response = await axios.get(`${speculosAddress}:${speculosApiPort}/screenshot`, {
477
511
  responseType: "arraybuffer",
478
512
  });
479
513
  return response.data;