@ledgerhq/coin-tester-evm 1.12.0-nightly.20251217142347 → 1.12.0-nightly.20251219024040

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 (85) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +43 -10
  3. package/README.md +1 -1
  4. package/lib/src/anvil.d.ts +1 -1
  5. package/lib/src/anvil.d.ts.map +1 -1
  6. package/lib/src/anvil.js +3 -3
  7. package/lib/src/anvil.js.map +1 -1
  8. package/lib/src/helpers.d.ts +3 -3
  9. package/lib/src/helpers.d.ts.map +1 -1
  10. package/lib/src/helpers.js +2 -3
  11. package/lib/src/helpers.js.map +1 -1
  12. package/lib/src/scenarii/blast.d.ts.map +1 -1
  13. package/lib/src/scenarii/blast.js +5 -10
  14. package/lib/src/scenarii/blast.js.map +1 -1
  15. package/lib/src/scenarii/core.d.ts.map +1 -1
  16. package/lib/src/scenarii/core.js +5 -10
  17. package/lib/src/scenarii/core.js.map +1 -1
  18. package/lib/src/scenarii/ethereum.d.ts.map +1 -1
  19. package/lib/src/scenarii/ethereum.js +5 -10
  20. package/lib/src/scenarii/ethereum.js.map +1 -1
  21. package/lib/src/scenarii/polygon.d.ts.map +1 -1
  22. package/lib/src/scenarii/polygon.js +6 -10
  23. package/lib/src/scenarii/polygon.js.map +1 -1
  24. package/lib/src/scenarii/scroll.d.ts.map +1 -1
  25. package/lib/src/scenarii/scroll.js +5 -10
  26. package/lib/src/scenarii/scroll.js.map +1 -1
  27. package/lib/src/scenarii/sonic.d.ts.map +1 -1
  28. package/lib/src/scenarii/sonic.js +5 -17
  29. package/lib/src/scenarii/sonic.js.map +1 -1
  30. package/lib/src/signer.d.ts +7 -0
  31. package/lib/src/signer.d.ts.map +1 -0
  32. package/lib/src/signer.js +25 -0
  33. package/lib/src/signer.js.map +1 -0
  34. package/lib/tsconfig.tsbuildinfo +1 -1
  35. package/lib-es/src/anvil.d.ts +1 -1
  36. package/lib-es/src/anvil.d.ts.map +1 -1
  37. package/lib-es/src/anvil.js +3 -3
  38. package/lib-es/src/anvil.js.map +1 -1
  39. package/lib-es/src/helpers.d.ts +3 -3
  40. package/lib-es/src/helpers.d.ts.map +1 -1
  41. package/lib-es/src/helpers.js +2 -3
  42. package/lib-es/src/helpers.js.map +1 -1
  43. package/lib-es/src/scenarii/blast.d.ts.map +1 -1
  44. package/lib-es/src/scenarii/blast.js +5 -10
  45. package/lib-es/src/scenarii/blast.js.map +1 -1
  46. package/lib-es/src/scenarii/core.d.ts.map +1 -1
  47. package/lib-es/src/scenarii/core.js +5 -10
  48. package/lib-es/src/scenarii/core.js.map +1 -1
  49. package/lib-es/src/scenarii/ethereum.d.ts.map +1 -1
  50. package/lib-es/src/scenarii/ethereum.js +5 -10
  51. package/lib-es/src/scenarii/ethereum.js.map +1 -1
  52. package/lib-es/src/scenarii/polygon.d.ts.map +1 -1
  53. package/lib-es/src/scenarii/polygon.js +6 -10
  54. package/lib-es/src/scenarii/polygon.js.map +1 -1
  55. package/lib-es/src/scenarii/scroll.d.ts.map +1 -1
  56. package/lib-es/src/scenarii/scroll.js +5 -10
  57. package/lib-es/src/scenarii/scroll.js.map +1 -1
  58. package/lib-es/src/scenarii/sonic.d.ts.map +1 -1
  59. package/lib-es/src/scenarii/sonic.js +5 -17
  60. package/lib-es/src/scenarii/sonic.js.map +1 -1
  61. package/lib-es/src/signer.d.ts +7 -0
  62. package/lib-es/src/signer.d.ts.map +1 -0
  63. package/lib-es/src/signer.js +22 -0
  64. package/lib-es/src/signer.js.map +1 -0
  65. package/lib-es/tsconfig.tsbuildinfo +1 -1
  66. package/package.json +11 -10
  67. package/src/anvil.ts +3 -3
  68. package/src/helpers.ts +6 -7
  69. package/src/scenarii/blast.ts +5 -10
  70. package/src/scenarii/core.ts +6 -10
  71. package/src/scenarii/ethereum.ts +5 -10
  72. package/src/scenarii/polygon.ts +6 -10
  73. package/src/scenarii/scroll.ts +5 -10
  74. package/src/scenarii/sonic.ts +5 -17
  75. package/src/scenarii.test.ts +7 -8
  76. package/src/signer.ts +31 -0
  77. package/lib/src/constants.d.ts +0 -5
  78. package/lib/src/constants.d.ts.map +0 -1
  79. package/lib/src/constants.js +0 -5
  80. package/lib/src/constants.js.map +0 -1
  81. package/lib-es/src/constants.d.ts +0 -5
  82. package/lib-es/src/constants.d.ts.map +0 -1
  83. package/lib-es/src/constants.js +0 -2
  84. package/lib-es/src/constants.js.map +0 -1
  85. package/src/constants.ts +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ledgerhq/coin-tester-evm",
3
- "version": "1.12.0-nightly.20251217142347",
3
+ "version": "1.12.0-nightly.20251219024040",
4
4
  "description": "Ledger EVM Coin Tester",
5
5
  "main": "src/scenarii.test.ts",
6
6
  "keywords": [
@@ -47,18 +47,19 @@
47
47
  "dependencies": {
48
48
  "bignumber.js": "^9.1.2",
49
49
  "bluebird": "^3.7.2",
50
+ "bip39": "^3.1.0",
50
51
  "docker-compose": "^1.1.0",
51
52
  "dotenv": "^16.4.5",
52
53
  "ethers": "6.15.0",
53
54
  "msw": "^2.2.1",
54
- "@ledgerhq/coin-evm": "^2.37.0-nightly.20251217142347",
55
- "@ledgerhq/coin-framework": "^6.11.0-nightly.20251217142347",
56
- "@ledgerhq/coin-tester": "^0.14.0-nightly.20251217142347",
57
- "@ledgerhq/cryptoassets": "^13.35.0-nightly.20251217142347",
58
- "@ledgerhq/live-common": "^34.55.0-nightly.20251217142347",
59
- "@ledgerhq/live-config": "^3.3.0-nightly.20251217142347",
60
- "@ledgerhq/types-cryptoassets": "^7.31.0-nightly.20251217142347",
61
- "@ledgerhq/types-live": "^6.91.0-nightly.20251217142347"
55
+ "@ledgerhq/coin-evm": "^2.37.0-nightly.20251219024040",
56
+ "@ledgerhq/coin-framework": "^6.11.0-nightly.20251219024040",
57
+ "@ledgerhq/coin-tester": "^0.14.0-nightly.20251219024040",
58
+ "@ledgerhq/cryptoassets": "^13.35.0-nightly.20251219024040",
59
+ "@ledgerhq/live-common": "^34.55.0-nightly.20251219024040",
60
+ "@ledgerhq/live-config": "^3.3.0-nightly.20251219024040",
61
+ "@ledgerhq/types-cryptoassets": "^7.31.0-nightly.20251219024040",
62
+ "@ledgerhq/types-live": "^6.91.0-nightly.20251219024040"
62
63
  },
63
64
  "devDependencies": {
64
65
  "@swc/core": "1.4.11",
@@ -71,7 +72,7 @@
71
72
  "ts-jest": "^29.1.2",
72
73
  "ts-node": "^10.9.2",
73
74
  "typescript": "^5.3.3",
74
- "@ledgerhq/hw-transport": "6.31.14-nightly.20251217142347"
75
+ "@ledgerhq/hw-transport": "6.31.15-nightly.20251219024040"
75
76
  },
76
77
  "scripts": {
77
78
  "clean": "rimraf lib lib-es",
package/src/anvil.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  import chalk from "chalk";
2
2
  import * as compose from "docker-compose";
3
- import { killSpeculos } from "@ledgerhq/coin-tester/lib/signers/speculos";
4
3
 
5
4
  const cwd = __dirname;
6
5
 
@@ -17,7 +16,7 @@ const ensureEnv = () => {
17
16
  }
18
17
  };
19
18
 
20
- export const spawnAnvil = async (rpc: string): Promise<void> => {
19
+ export const spawnAnvil = async (rpc: string, seed: string): Promise<void> => {
21
20
  ensureEnv();
22
21
  console.log("Starting anvil...");
23
22
  await compose.upOne("anvil", {
@@ -26,6 +25,7 @@ export const spawnAnvil = async (rpc: string): Promise<void> => {
26
25
  env: {
27
26
  ...process.env,
28
27
  RPC: rpc,
28
+ SEED: seed,
29
29
  },
30
30
  });
31
31
 
@@ -62,6 +62,6 @@ export const killAnvil = async (): Promise<void> => {
62
62
 
63
63
  ["exit", "SIGINT", "SIGQUIT", "SIGTERM", "SIGUSR1", "SIGUSR2", "uncaughtException"].map(e =>
64
64
  process.on(e, async () => {
65
- await Promise.all([killAnvil(), killSpeculos()]);
65
+ await killAnvil();
66
66
  }),
67
67
  );
package/src/helpers.ts CHANGED
@@ -1,4 +1,3 @@
1
- import type Transport from "@ledgerhq/hw-transport";
2
1
  import { ethers } from "ethers";
3
2
  import { AccountBridge, CurrencyBridge, NFTStandard } from "@ledgerhq/types-live";
4
3
  import { TokenCurrency } from "@ledgerhq/types-cryptoassets";
@@ -8,7 +7,7 @@ import { Transaction as EvmTransaction } from "@ledgerhq/coin-evm/types/transact
8
7
  import { GetAddressFn } from "@ledgerhq/coin-framework/bridge/getAddressWrapper";
9
8
  import { SignerContext } from "@ledgerhq/coin-framework/signer";
10
9
  import resolver from "@ledgerhq/coin-evm/hw-getAddress";
11
- import { Signer, createSigner } from "@ledgerhq/live-common/bridge/generic-alpaca/signer/Eth";
10
+ import { Signer } from "@ledgerhq/live-common/bridge/generic-alpaca/signer/Eth";
12
11
  import { getAlpacaCurrencyBridge } from "@ledgerhq/live-common/bridge/generic-alpaca/currencyBridge";
13
12
  import { getAlpacaAccountBridge } from "@ledgerhq/live-common/bridge/generic-alpaca/accountBridge";
14
13
 
@@ -23,15 +22,15 @@ export const ERC721Interface = new ethers.Interface(ERC721_ABI);
23
22
  export const ERC1155Interface = new ethers.Interface(ERC1155_ABI);
24
23
  export const VITALIK = "0x6bfD74C0996F269Bcece59191EFf667b3dFD73b9";
25
24
 
26
- export function getBridges(
27
- transport: Transport,
25
+ export async function getBridges(
28
26
  network: string,
29
- ): {
27
+ signer: Signer,
28
+ ): Promise<{
30
29
  currencyBridge: CurrencyBridge;
31
30
  accountBridge: AccountBridge<EvmTransaction>;
32
31
  getAddress: GetAddressFn;
33
- } {
34
- const context: SignerContext<Signer> = (_, fn) => fn(createSigner(transport));
32
+ }> {
33
+ const context: SignerContext<Signer> = (_, fn) => fn(signer);
35
34
  const getAddress = resolver(context);
36
35
 
37
36
  return {
@@ -3,15 +3,14 @@ import { ethers } from "ethers";
3
3
  import { Account } from "@ledgerhq/types-live";
4
4
  import { Scenario, ScenarioTransaction } from "@ledgerhq/coin-tester/main";
5
5
  import { encodeTokenAccountId } from "@ledgerhq/coin-framework/account/index";
6
- import { killSpeculos, spawnSpeculos } from "@ledgerhq/coin-tester/signers/speculos";
7
6
  import { resetIndexer, setBlock, indexBlocks, initMswHandlers } from "../indexer";
8
7
  import { getCoinConfig, setCoinConfig } from "@ledgerhq/coin-evm/config";
9
8
  import { Transaction as EvmTransaction } from "@ledgerhq/coin-evm/types/transaction";
10
9
  import { makeAccount } from "../fixtures";
11
- import { defaultNanoApp } from "../constants";
12
10
  import { blast, callMyDealer, getBridges, VITALIK } from "../helpers";
13
11
  import { killAnvil, spawnAnvil } from "../anvil";
14
12
  import { MIM_ON_BLAST } from "../tokenFixtures";
13
+ import { buildSigner } from "../signer";
15
14
 
16
15
  type BlastScenarioTransaction = ScenarioTransaction<EvmTransaction, Account>;
17
16
 
@@ -57,10 +56,8 @@ const makeScenarioTransactions = ({ address }: { address: string }): BlastScenar
57
56
  export const scenarioBlast: Scenario<EvmTransaction, Account> = {
58
57
  name: "Ledger Live Basic Blast Transactions",
59
58
  setup: async () => {
60
- const [{ transport, getOnSpeculosConfirmation }] = await Promise.all([
61
- spawnSpeculos(`/${defaultNanoApp.firmware}/Ethereum/app_${defaultNanoApp.version}.elf`),
62
- spawnAnvil("https://rpc.blast.io"),
63
- ]);
59
+ const signer = await buildSigner();
60
+ await spawnAnvil("https://rpc.blast.io", signer.exportMnemonic());
64
61
 
65
62
  const provider = new ethers.JsonRpcProvider("http://127.0.0.1:8545");
66
63
 
@@ -86,8 +83,7 @@ export const scenarioBlast: Scenario<EvmTransaction, Account> = {
86
83
  }));
87
84
  initMswHandlers(getCoinConfig(blast).info);
88
85
 
89
- const onSignerConfirmation = getOnSpeculosConfirmation();
90
- const { currencyBridge, accountBridge, getAddress } = getBridges(transport, "blast");
86
+ const { currencyBridge, accountBridge, getAddress } = await getBridges("blast", signer);
91
87
  const { address } = await getAddress("", {
92
88
  path: "44'/60'/0'/0/0",
93
89
  currency: blast,
@@ -107,7 +103,6 @@ export const scenarioBlast: Scenario<EvmTransaction, Account> = {
107
103
  currencyBridge,
108
104
  accountBridge,
109
105
  account: scenarioAccount,
110
- onSignerConfirmation,
111
106
  retryLimit: 0,
112
107
  };
113
108
  },
@@ -130,7 +125,7 @@ export const scenarioBlast: Scenario<EvmTransaction, Account> = {
130
125
  expect(account.operations.length).toBe(3);
131
126
  },
132
127
  teardown: async () => {
133
- await Promise.all([killSpeculos(), killAnvil()]);
128
+ await killAnvil();
134
129
  resetIndexer();
135
130
  },
136
131
  };
@@ -3,7 +3,6 @@ import { getCoinConfig, setCoinConfig } from "@ledgerhq/coin-evm/config";
3
3
  import { Transaction as EvmTransaction } from "@ledgerhq/coin-evm/types/transaction";
4
4
  import { encodeTokenAccountId } from "@ledgerhq/coin-framework/account/index";
5
5
  import { Scenario, ScenarioTransaction } from "@ledgerhq/coin-tester/main";
6
- import { killSpeculos, spawnSpeculos } from "@ledgerhq/coin-tester/signers/speculos";
7
6
  import { LiveConfig } from "@ledgerhq/live-config/LiveConfig";
8
7
  import { Account } from "@ledgerhq/types-live";
9
8
  import { BigNumber } from "bignumber.js";
@@ -11,8 +10,8 @@ import { ethers } from "ethers";
11
10
  import { killAnvil, spawnAnvil } from "../anvil";
12
11
  import { VITALIK, core, getBridges } from "../helpers";
13
12
  import { indexBlocks, initMswHandlers, resetIndexer, setBlock } from "../indexer";
14
- import { defaultNanoApp } from "../constants";
15
13
  import { STCORE_ON_CORE } from "../tokenFixtures";
14
+ import { buildSigner } from "../signer";
16
15
 
17
16
  type CoreScenarioTransaction = ScenarioTransaction<EvmTransaction, Account>;
18
17
 
@@ -59,10 +58,9 @@ const makeScenarioTransactions = ({ address }: { address: string }): CoreScenari
59
58
  export const scenarioCore: Scenario<EvmTransaction, Account> = {
60
59
  name: "Ledger Live Basic CORE Transactions",
61
60
  setup: async () => {
62
- const [{ transport, getOnSpeculosConfirmation }] = await Promise.all([
63
- spawnSpeculos(`/${defaultNanoApp.firmware}/Ethereum/app_${defaultNanoApp.version}.elf`),
64
- spawnAnvil("https://rpc.ankr.com/core"),
65
- ]);
61
+ const signer = await buildSigner();
62
+ await spawnAnvil("https://rpc.ankr.com/core", signer.exportMnemonic());
63
+
66
64
  const provider = new ethers.JsonRpcProvider("http://127.0.0.1:8545");
67
65
 
68
66
  setCoinConfig(() => ({
@@ -101,8 +99,7 @@ export const scenarioCore: Scenario<EvmTransaction, Account> = {
101
99
 
102
100
  initMswHandlers(getCoinConfig(core).info);
103
101
 
104
- const onSignerConfirmation = getOnSpeculosConfirmation();
105
- const { currencyBridge, accountBridge, getAddress } = getBridges(transport, "core");
102
+ const { currencyBridge, accountBridge, getAddress } = await getBridges("core", signer);
106
103
  const { address } = await getAddress("", {
107
104
  path: "44'/60'/0'/0/0",
108
105
  currency: core,
@@ -128,7 +125,6 @@ export const scenarioCore: Scenario<EvmTransaction, Account> = {
128
125
  currencyBridge,
129
126
  accountBridge,
130
127
  account: scenarioAccount,
131
- onSignerConfirmation,
132
128
  };
133
129
  },
134
130
  beforeAll: account => {
@@ -152,6 +148,6 @@ export const scenarioCore: Scenario<EvmTransaction, Account> = {
152
148
  },
153
149
  teardown: async () => {
154
150
  resetIndexer();
155
- await Promise.all([killSpeculos(), killAnvil()]);
151
+ await killAnvil();
156
152
  },
157
153
  };
@@ -1,6 +1,5 @@
1
1
  import { encodeTokenAccountId } from "@ledgerhq/coin-framework/account/index";
2
2
  import { Scenario, ScenarioTransaction } from "@ledgerhq/coin-tester/main";
3
- import { killSpeculos, spawnSpeculos } from "@ledgerhq/coin-tester/signers/speculos";
4
3
  import { Account } from "@ledgerhq/types-live";
5
4
  import { BigNumber } from "bignumber.js";
6
5
  import { ethers } from "ethers";
@@ -10,9 +9,9 @@ import { Transaction as EvmTransaction } from "@ledgerhq/coin-evm/types/transact
10
9
  import { killAnvil, spawnAnvil } from "../anvil";
11
10
  import { callMyDealer, ethereum, VITALIK, getBridges } from "../helpers";
12
11
  import { indexBlocks, initMswHandlers, resetIndexer, setBlock } from "../indexer";
13
- import { defaultNanoApp } from "../constants";
14
12
  import { LiveConfig } from "@ledgerhq/live-config/LiveConfig";
15
13
  import { USDC_ON_ETHEREUM } from "../tokenFixtures";
14
+ import { buildSigner } from "../signer";
16
15
 
17
16
  type EthereumScenarioTransaction = ScenarioTransaction<EvmTransaction, Account>;
18
17
 
@@ -62,10 +61,8 @@ const makeScenarioTransactions = ({
62
61
  export const scenarioEthereum: Scenario<EvmTransaction, Account> = {
63
62
  name: "Ledger Live Basic ETH Transactions",
64
63
  setup: async () => {
65
- const [{ transport, getOnSpeculosConfirmation }] = await Promise.all([
66
- spawnSpeculos(`/${defaultNanoApp.firmware}/Ethereum/app_${defaultNanoApp.version}.elf`),
67
- spawnAnvil("https://ethereum-rpc.publicnode.com"),
68
- ]);
64
+ const signer = await buildSigner();
65
+ await spawnAnvil("https://ethereum-rpc.publicnode.com", signer.exportMnemonic());
69
66
 
70
67
  setCoinConfig(() => ({
71
68
  info: {
@@ -113,8 +110,7 @@ export const scenarioEthereum: Scenario<EvmTransaction, Account> = {
113
110
 
114
111
  initMswHandlers(getCoinConfig(ethereum).info);
115
112
 
116
- const onSignerConfirmation = getOnSpeculosConfirmation();
117
- const { currencyBridge, accountBridge, getAddress } = getBridges(transport, "ethereum");
113
+ const { currencyBridge, accountBridge, getAddress } = await getBridges("ethereum", signer);
118
114
  const { address } = await getAddress("", {
119
115
  path: "44'/60'/0'/0/0",
120
116
  currency: ethereum,
@@ -141,7 +137,6 @@ export const scenarioEthereum: Scenario<EvmTransaction, Account> = {
141
137
  currencyBridge,
142
138
  accountBridge,
143
139
  account: scenarioAccount,
144
- onSignerConfirmation,
145
140
  };
146
141
  },
147
142
  beforeAll: account => {
@@ -166,6 +161,6 @@ export const scenarioEthereum: Scenario<EvmTransaction, Account> = {
166
161
  },
167
162
  teardown: async () => {
168
163
  resetIndexer();
169
- await Promise.all([killSpeculos(), killAnvil()]);
164
+ await killAnvil();
170
165
  },
171
166
  };
@@ -3,16 +3,15 @@ import { ethers } from "ethers";
3
3
  import { Account } from "@ledgerhq/types-live";
4
4
  import { Scenario, ScenarioTransaction } from "@ledgerhq/coin-tester/main";
5
5
  import { encodeTokenAccountId } from "@ledgerhq/coin-framework/account/index";
6
- import { killSpeculos, spawnSpeculos } from "@ledgerhq/coin-tester/signers/speculos";
7
6
  import { resetIndexer, initMswHandlers, setBlock, indexBlocks } from "../indexer";
8
7
  import { Transaction as EvmTransaction } from "@ledgerhq/coin-evm/types/transaction";
9
8
  import { getCoinConfig, setCoinConfig } from "@ledgerhq/coin-evm/config";
10
9
  import { makeAccount } from "../fixtures";
11
10
  import { callMyDealer, getBridges, polygon, VITALIK } from "../helpers";
12
- import { defaultNanoApp } from "../constants";
13
11
  import { killAnvil, spawnAnvil } from "../anvil";
14
12
  import { LiveConfig } from "@ledgerhq/live-config/LiveConfig";
15
13
  import { USDC_ON_POLYGON } from "../tokenFixtures";
14
+ import { buildSigner } from "../signer";
16
15
 
17
16
  type PolygonScenarioTransaction = ScenarioTransaction<EvmTransaction, Account>;
18
17
 
@@ -59,10 +58,8 @@ const makeScenarioTransactions = ({ address }: { address: string }) => {
59
58
  export const scenarioPolygon: Scenario<EvmTransaction, Account> = {
60
59
  name: "Ledger Live Basic Polygon Transactions",
61
60
  setup: async () => {
62
- const [{ transport, getOnSpeculosConfirmation }] = await Promise.all([
63
- spawnSpeculos(`/${defaultNanoApp.firmware}/Ethereum/app_${defaultNanoApp.version}.elf`),
64
- spawnAnvil("https://polygon-bor-rpc.publicnode.com"),
65
- ]);
61
+ const signer = await buildSigner();
62
+ await spawnAnvil("https://polygon-bor-rpc.publicnode.com", signer.exportMnemonic());
66
63
 
67
64
  const provider = new ethers.JsonRpcProvider("http://127.0.0.1:8545");
68
65
 
@@ -115,8 +112,7 @@ export const scenarioPolygon: Scenario<EvmTransaction, Account> = {
115
112
  });
116
113
  initMswHandlers(getCoinConfig(polygon).info);
117
114
 
118
- const onSignerConfirmation = getOnSpeculosConfirmation();
119
- const { currencyBridge, accountBridge, getAddress } = getBridges(transport, "polygon");
115
+ const { currencyBridge, accountBridge, getAddress } = await getBridges("polygon", signer);
120
116
  const { address } = await getAddress("", {
121
117
  path: "44'/60'/0'/0/0",
122
118
  currency: polygon,
@@ -135,7 +131,7 @@ export const scenarioPolygon: Scenario<EvmTransaction, Account> = {
135
131
  dose: ethers.parseUnits("100", USDC_ON_POLYGON.units[0].magnitude),
136
132
  });
137
133
 
138
- return { currencyBridge, accountBridge, account: scenarioAccount, onSignerConfirmation };
134
+ return { currencyBridge, accountBridge, account: scenarioAccount };
139
135
  },
140
136
  getTransactions: address => makeScenarioTransactions({ address }),
141
137
  beforeSync: async () => {
@@ -159,6 +155,6 @@ export const scenarioPolygon: Scenario<EvmTransaction, Account> = {
159
155
  },
160
156
  teardown: async () => {
161
157
  resetIndexer();
162
- await Promise.all([killSpeculos(), killAnvil()]);
158
+ await killAnvil();
163
159
  },
164
160
  };
@@ -3,15 +3,14 @@ import { ethers } from "ethers";
3
3
  import { Account } from "@ledgerhq/types-live";
4
4
  import { Scenario, ScenarioTransaction } from "@ledgerhq/coin-tester/main";
5
5
  import { encodeTokenAccountId } from "@ledgerhq/coin-framework/account/index";
6
- import { killSpeculos, spawnSpeculos } from "@ledgerhq/coin-tester/signers/speculos";
7
6
  import { resetIndexer, setBlock, indexBlocks, initMswHandlers } from "../indexer";
8
7
  import { getCoinConfig, setCoinConfig } from "@ledgerhq/coin-evm/config";
9
8
  import { Transaction as EvmTransaction } from "@ledgerhq/coin-evm/types/transaction";
10
9
  import { makeAccount } from "../fixtures";
11
10
  import { callMyDealer, getBridges, scroll, VITALIK } from "../helpers";
12
- import { defaultNanoApp } from "../constants";
13
11
  import { killAnvil, spawnAnvil } from "../anvil";
14
12
  import { USDC_ON_SCROLL } from "../tokenFixtures";
13
+ import { buildSigner } from "../signer";
15
14
 
16
15
  type ScrollScenarioTransaction = ScenarioTransaction<EvmTransaction, Account>;
17
16
 
@@ -61,10 +60,8 @@ const makeScenarioTransactions = ({
61
60
  export const scenarioScroll: Scenario<EvmTransaction, Account> = {
62
61
  name: "Ledger Live Basic Scroll Transactions",
63
62
  setup: async () => {
64
- const [{ transport, getOnSpeculosConfirmation }] = await Promise.all([
65
- spawnSpeculos(`/${defaultNanoApp.firmware}/Ethereum/app_${defaultNanoApp.version}.elf`),
66
- spawnAnvil("https://rpc.scroll.io"),
67
- ]);
63
+ const signer = await buildSigner();
64
+ await spawnAnvil("https://rpc.scroll.io", signer.exportMnemonic());
68
65
 
69
66
  const provider = new ethers.JsonRpcProvider("http://127.0.0.1:8545");
70
67
 
@@ -90,8 +87,7 @@ export const scenarioScroll: Scenario<EvmTransaction, Account> = {
90
87
  }));
91
88
  initMswHandlers(getCoinConfig(scroll).info);
92
89
 
93
- const onSignerConfirmation = getOnSpeculosConfirmation();
94
- const { currencyBridge, accountBridge, getAddress } = getBridges(transport, "scroll");
90
+ const { currencyBridge, accountBridge, getAddress } = await getBridges("scroll", signer);
95
91
  const { address } = await getAddress("", {
96
92
  path: "44'/60'/0'/0/0",
97
93
  currency: scroll,
@@ -111,7 +107,6 @@ export const scenarioScroll: Scenario<EvmTransaction, Account> = {
111
107
  currencyBridge,
112
108
  accountBridge,
113
109
  account: scenarioAccount,
114
- onSignerConfirmation,
115
110
  retryLimit: 0,
116
111
  };
117
112
  },
@@ -134,7 +129,7 @@ export const scenarioScroll: Scenario<EvmTransaction, Account> = {
134
129
  expect(account.operations.length).toBe(3);
135
130
  },
136
131
  teardown: async () => {
137
- await Promise.all([killSpeculos(), killAnvil()]);
132
+ await killAnvil();
138
133
  resetIndexer();
139
134
  },
140
135
  };
@@ -3,16 +3,15 @@ import { ethers } from "ethers";
3
3
  import { Account } from "@ledgerhq/types-live";
4
4
  import { encodeTokenAccountId } from "@ledgerhq/coin-framework/account/index";
5
5
  import { Scenario, ScenarioTransaction } from "@ledgerhq/coin-tester/main";
6
- import { killSpeculos, spawnSpeculos } from "@ledgerhq/coin-tester/signers/speculos";
7
6
  import { resetIndexer, indexBlocks, initMswHandlers, setBlock } from "../indexer";
8
7
  import { Transaction as EvmTransaction } from "@ledgerhq/coin-evm/types/transaction";
9
8
  import { getCoinConfig, setCoinConfig } from "@ledgerhq/coin-evm/config";
10
9
  import { makeAccount } from "../fixtures";
11
10
  import { VITALIK, callMyDealer, getBridges, sonic } from "../helpers";
12
- import { defaultNanoApp } from "../constants";
13
11
  import { killAnvil, spawnAnvil } from "../anvil";
14
12
  import { LiveConfig } from "@ledgerhq/live-config/LiveConfig";
15
13
  import { BRIDGED_USDC_ON_SONIC } from "../tokenFixtures";
14
+ import { buildSigner } from "../signer";
16
15
 
17
16
  type SonicScenarioTransaction = ScenarioTransaction<EvmTransaction, Account>;
18
17
 
@@ -60,17 +59,8 @@ const makeScenarioTransactions = ({ address }: { address: string }): SonicScenar
60
59
  export const scenarioSonic: Scenario<EvmTransaction, Account> = {
61
60
  name: "Ledger Live Basic S Transactions",
62
61
  setup: async () => {
63
- const [{ transport, getOnSpeculosConfirmation }] = await Promise.all([
64
- spawnSpeculos(`/${defaultNanoApp.firmware}/Sonic/app_${defaultNanoApp.version}.elf`, {
65
- libraries: [
66
- {
67
- name: "Ethereum",
68
- endpoint: "/2.4.2/Ethereum/app_1.17.0.elf",
69
- },
70
- ],
71
- }),
72
- spawnAnvil("https://sonic-rpc.publicnode.com"),
73
- ]);
62
+ const signer = await buildSigner();
63
+ await spawnAnvil("https://sonic-rpc.publicnode.com", signer.exportMnemonic());
74
64
 
75
65
  setCoinConfig(() => ({
76
66
  info: {
@@ -110,8 +100,7 @@ export const scenarioSonic: Scenario<EvmTransaction, Account> = {
110
100
 
111
101
  initMswHandlers(getCoinConfig(sonic).info);
112
102
 
113
- const onSignerConfirmation = getOnSpeculosConfirmation();
114
- const { currencyBridge, accountBridge, getAddress } = getBridges(transport, "sonic");
103
+ const { currencyBridge, accountBridge, getAddress } = await getBridges("sonic", signer);
115
104
  const { address } = await getAddress("", {
116
105
  path: "44'/60'/0'/0/0",
117
106
  currency: sonic,
@@ -138,7 +127,6 @@ export const scenarioSonic: Scenario<EvmTransaction, Account> = {
138
127
  currencyBridge,
139
128
  accountBridge,
140
129
  account: scenarioAccount,
141
- onSignerConfirmation,
142
130
  };
143
131
  },
144
132
  beforeAll: account => {
@@ -160,6 +148,6 @@ export const scenarioSonic: Scenario<EvmTransaction, Account> = {
160
148
  },
161
149
  teardown: async () => {
162
150
  resetIndexer();
163
- await Promise.all([killSpeculos(), killAnvil()]);
151
+ await killAnvil();
164
152
  },
165
153
  };
@@ -1,4 +1,3 @@
1
- import { killSpeculos } from "@ledgerhq/coin-tester/signers/speculos";
2
1
  import { executeScenario } from "@ledgerhq/coin-tester/main";
3
2
  import { killAnvil } from "./anvil";
4
3
  import { scenarioEthereum } from "./scenarii/ethereum";
@@ -22,7 +21,7 @@ describe("EVM Deterministic Tester", () => {
22
21
  await executeScenario(scenarioEthereum);
23
22
  } catch (e) {
24
23
  if (e != "done") {
25
- await Promise.all([killSpeculos(), killAnvil()]);
24
+ await killAnvil();
26
25
  throw e;
27
26
  }
28
27
  }
@@ -33,7 +32,7 @@ describe("EVM Deterministic Tester", () => {
33
32
  await executeScenario(scenarioSonic);
34
33
  } catch (e) {
35
34
  if (e != "done") {
36
- await Promise.all([killSpeculos(), killAnvil()]);
35
+ await killAnvil();
37
36
  throw e;
38
37
  }
39
38
  }
@@ -44,7 +43,7 @@ describe("EVM Deterministic Tester", () => {
44
43
  await executeScenario(scenarioPolygon);
45
44
  } catch (e) {
46
45
  if (e != "done") {
47
- await Promise.all([killSpeculos(), killAnvil()]);
46
+ await killAnvil();
48
47
  throw e;
49
48
  }
50
49
  }
@@ -55,7 +54,7 @@ describe("EVM Deterministic Tester", () => {
55
54
  await executeScenario(scenarioCore);
56
55
  } catch (e) {
57
56
  if (e != "done") {
58
- await Promise.all([killSpeculos(), killAnvil()]);
57
+ await killAnvil();
59
58
  throw e;
60
59
  }
61
60
  }
@@ -66,7 +65,7 @@ describe("EVM Deterministic Tester", () => {
66
65
  await executeScenario(scenarioScroll);
67
66
  } catch (e) {
68
67
  if (e != "done") {
69
- await Promise.all([killSpeculos(), killAnvil()]);
68
+ await killAnvil();
70
69
  throw e;
71
70
  }
72
71
  }
@@ -77,7 +76,7 @@ describe("EVM Deterministic Tester", () => {
77
76
  await executeScenario(scenarioBlast);
78
77
  } catch (e) {
79
78
  if (e != "done") {
80
- await Promise.all([killSpeculos(), killAnvil()]);
79
+ await killAnvil();
81
80
  throw e;
82
81
  }
83
82
  }
@@ -86,6 +85,6 @@ describe("EVM Deterministic Tester", () => {
86
85
 
87
86
  ["exit", "SIGINT", "SIGQUIT", "SIGTERM", "SIGUSR1", "SIGUSR2", "uncaughtException"].map(e =>
88
87
  process.on(e, async () => {
89
- await Promise.all([killSpeculos(), killAnvil()]);
88
+ await killAnvil();
90
89
  }),
91
90
  );
package/src/signer.ts ADDED
@@ -0,0 +1,31 @@
1
+ import { EvmAddress } from "@ledgerhq/coin-evm/types/signer";
2
+ import { Signer } from "@ledgerhq/live-common/bridge/generic-alpaca/signer/Eth";
3
+ import { HDNodeWallet, Transaction } from "ethers";
4
+ import { generateMnemonic, mnemonicToSeed } from "bip39";
5
+
6
+ type EvmSigner = Signer & { exportMnemonic: () => string };
7
+
8
+ function getAddress(wallet: HDNodeWallet): Promise<EvmAddress> {
9
+ return Promise.resolve({ publicKey: wallet.publicKey, address: wallet.address });
10
+ }
11
+
12
+ function signTransaction(wallet: HDNodeWallet, transaction: string): Promise<string> {
13
+ const signature = wallet.signingKey.sign(Transaction.from(transaction).unsignedHash);
14
+ return Promise.resolve(signature.serialized);
15
+ }
16
+
17
+ export async function buildSigner(): Promise<EvmSigner> {
18
+ const mnemonic = generateMnemonic();
19
+ const seed = await mnemonicToSeed(mnemonic);
20
+ const seedHex = seed.toString("hex");
21
+ const root = HDNodeWallet.fromSeed(`0x${seedHex}`);
22
+
23
+ const wallet = (path: string) => root.derivePath(path);
24
+
25
+ return {
26
+ exportMnemonic: () => mnemonic,
27
+ getAddress: (path: string) => getAddress(wallet(path)),
28
+ signTransaction: (path: string, transaction: string) =>
29
+ signTransaction(wallet(path), transaction),
30
+ };
31
+ }
@@ -1,5 +0,0 @@
1
- export declare const defaultNanoApp: {
2
- firmware: "2.4.2";
3
- version: "1.17.0";
4
- };
5
- //# sourceMappingURL=constants.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc;;;CAA6D,CAAC"}
@@ -1,5 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.defaultNanoApp = void 0;
4
- exports.defaultNanoApp = { firmware: "2.4.2", version: "1.17.0" };
5
- //# sourceMappingURL=constants.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,cAAc,GAAG,EAAE,QAAQ,EAAE,OAAgB,EAAE,OAAO,EAAE,QAAiB,EAAE,CAAC"}
@@ -1,5 +0,0 @@
1
- export declare const defaultNanoApp: {
2
- firmware: "2.4.2";
3
- version: "1.17.0";
4
- };
5
- //# sourceMappingURL=constants.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc;;;CAA6D,CAAC"}
@@ -1,2 +0,0 @@
1
- export const defaultNanoApp = { firmware: "2.4.2", version: "1.17.0" };
2
- //# sourceMappingURL=constants.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,cAAc,GAAG,EAAE,QAAQ,EAAE,OAAgB,EAAE,OAAO,EAAE,QAAiB,EAAE,CAAC"}
package/src/constants.ts DELETED
@@ -1 +0,0 @@
1
- export const defaultNanoApp = { firmware: "2.4.2" as const, version: "1.17.0" as const };