Skip to content

Commit d69250a

Browse files
authored
Merge pull request #1944 from mintlayer/feature/ledger_signer
Feature/ledger signer
2 parents a7bd4fe + 9800cfb commit d69250a

80 files changed

Lines changed: 8479 additions & 3178 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/build.yml

Lines changed: 144 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ on:
88
branches:
99
- "**" # target all branches
1010
schedule:
11-
- cron: '15 0 * * *' # every day at 00:15 UTC
11+
- cron: "15 0 * * *" # every day at 00:15 UTC
1212

1313
env:
1414
CARGO_TERM_COLOR: always
@@ -27,7 +27,7 @@ jobs:
2727
- name: Setup Python
2828
uses: actions/setup-python@v6
2929
with:
30-
python-version-file: './build-tools/.python-version'
30+
python-version-file: "./build-tools/.python-version"
3131

3232
- name: Install Rust
3333
# Use bash to be able to escape the newline via '\'.
@@ -37,17 +37,17 @@ jobs:
3737
--default-toolchain $(python ./build-tools/cargo-info-extractor/extract.py --rust-version)
3838
3939
- name: Build
40-
run: cargo build --release --locked --features trezor
40+
run: cargo build --release --locked --features trezor,ledger
4141

4242
- name: Run tests
43-
run: cargo test --release --workspace --features trezor
43+
run: cargo test --release --workspace --features trezor,ledger
4444

4545
- name: Run doc tests
46-
run: cargo test --release --doc --features trezor
46+
run: cargo test --release --doc --features trezor,ledger
4747

4848
# This test is ignored, so it needs to run separately.
4949
- name: Run mixed_sighash_types test
50-
run: cargo test --release mixed_sighash_types --features trezor
50+
run: cargo test --release mixed_sighash_types --features trezor,ledger
5151

5252
# This test is ignored, so it needs to run separately.
5353
- name: Run test_4opc_sequences test
@@ -76,30 +76,30 @@ jobs:
7676
run: sudo apt-get update
7777

7878
- name: Install build dependencies
79-
run: sudo apt-get install -yqq --no-install-recommends build-essential podman pkg-config libssl-dev
79+
run: sudo apt-get install -yqq --no-install-recommends build-essential podman pkg-config libssl-dev libdbus-1-dev libusb-1.0-0-dev
8080

8181
- name: Setup Python
8282
uses: actions/setup-python@v6
8383
with:
84-
python-version-file: './build-tools/.python-version'
84+
python-version-file: "./build-tools/.python-version"
8585

8686
- name: Install Rust
8787
run: |
8888
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y \
8989
--default-toolchain $(python ./build-tools/cargo-info-extractor/extract.py --rust-version)
9090
9191
- name: Build
92-
run: cargo build --release --locked --features trezor
92+
run: cargo build --release --locked --features trezor,ledger
9393

9494
- name: Run tests
95-
run: cargo test --release --workspace --features trezor
95+
run: cargo test --release --workspace --features trezor,ledger
9696

9797
- name: Run doc tests
98-
run: cargo test --release --doc --features trezor
98+
run: cargo test --release --doc --features trezor,ledger
9999

100100
# This test is ignored, so it needs to run separately.
101101
- name: Run mixed_sighash_types test
102-
run: cargo test --release mixed_sighash_types --features trezor
102+
run: cargo test --release mixed_sighash_types --features trezor,ledger
103103

104104
# This test is ignored, so it needs to run separately.
105105
- name: Run test_4opc_sequences test
@@ -125,25 +125,25 @@ jobs:
125125
- name: Setup Python
126126
uses: actions/setup-python@v6
127127
with:
128-
python-version-file: './build-tools/.python-version'
128+
python-version-file: "./build-tools/.python-version"
129129

130130
- name: Install Rust
131131
run: |
132132
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y \
133133
--default-toolchain $(python ./build-tools/cargo-info-extractor/extract.py --rust-version)
134134
135135
- name: Build
136-
run: cargo build --release --locked --features trezor
136+
run: cargo build --release --locked --features trezor,ledger
137137

138138
- name: Run tests
139-
run: cargo test --release --workspace --features trezor
139+
run: cargo test --release --workspace --features trezor,ledger
140140

141141
- name: Run doc tests
142-
run: cargo test --release --doc --features trezor
142+
run: cargo test --release --doc --features trezor,ledger
143143

144144
# This test is ignored, so it needs to run separately.
145145
- name: Run mixed_sighash_types test
146-
run: cargo test --release mixed_sighash_types --features trezor
146+
run: cargo test --release mixed_sighash_types --features trezor,ledger
147147

148148
# This test is ignored, so it needs to run separately.
149149
- name: Run test_4opc_sequences test
@@ -162,9 +162,9 @@ jobs:
162162
run_tests_on_trezor_preparation:
163163
runs-on: ubuntu-latest
164164
steps:
165-
# Note: we need to mimic the directory structure of the run_tests_on_trezor job, otherwise nextest
166-
# will fail to execute archived tests. So we checkout the source code to "./mintlayer-core".
167-
# (Also note that because of this the resulting path of the source dir will be "/.../mintlayer-core/mintlayer-core/mintlayer-core")
165+
# Note: we need to mimic the directory structure of the run_tests_on_trezor job, otherwise nextest
166+
# will fail to execute archived tests. So we checkout the source code to "./mintlayer-core".
167+
# (Also note that because of this the resulting path of the source dir will be "/.../mintlayer-core/mintlayer-core/mintlayer-core")
168168
- name: Checkout the core repository
169169
uses: actions/checkout@v5
170170
with:
@@ -175,12 +175,12 @@ jobs:
175175
run: sudo apt-get update
176176

177177
- name: Install build dependencies
178-
run: sudo apt-get install -yqq --no-install-recommends build-essential pkg-config libssl-dev
178+
run: sudo apt-get install -yqq --no-install-recommends build-essential pkg-config libssl-dev libdbus-1-dev libusb-1.0-0-dev
179179

180180
- name: Setup Python
181181
uses: actions/setup-python@v6
182182
with:
183-
python-version-file: './mintlayer-core/build-tools/.python-version'
183+
python-version-file: "./mintlayer-core/build-tools/.python-version"
184184

185185
- name: Extract required info from Cargo.toml
186186
id: extract_cargo_info
@@ -240,7 +240,7 @@ jobs:
240240
- name: Setup Python
241241
uses: actions/setup-python@v6
242242
with:
243-
python-version-file: './mintlayer-core/build-tools/.python-version'
243+
python-version-file: "./mintlayer-core/build-tools/.python-version"
244244

245245
- name: Extract required info from Cargo.toml
246246
id: extract_cargo_info
@@ -281,13 +281,127 @@ jobs:
281281
# Note: since we haven't installed Cargo in this job, we have to execute "cargo-nextest nextest"
282282
# instead of "cargo nextest".
283283
- name: Run tests in the emulator
284-
run:
285-
nix-shell --run "
286-
poetry run core/emu.py
287-
--headless --quiet --temporary-profile
288-
--mnemonic \"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about\"
289-
--command env --chdir ../mintlayer-core
290-
cargo-nextest nextest run --archive-file tests.tar.zst -j1 trezor_signer
284+
run: nix-shell --run "
285+
poetry run core/emu.py
286+
--headless --quiet --temporary-profile
287+
--mnemonic \"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about\"
288+
--command env --chdir ../mintlayer-core
289+
cargo-nextest nextest run --archive-file tests.tar.zst -j1 trezor_signer
291290
"
292291
working-directory: ./mintlayer-trezor-firmware
293292
timeout-minutes: 10
293+
294+
# Build Ledger-specific tests and archive them
295+
run_tests_on_ledger_preparation:
296+
runs-on: ubuntu-latest
297+
steps:
298+
- name: Checkout the core repository
299+
uses: actions/checkout@v5
300+
with:
301+
submodules: recursive
302+
path: ./mintlayer-core
303+
304+
- name: Update the list of available system packages
305+
run: sudo apt-get update
306+
307+
- name: Install build dependencies
308+
run: sudo apt-get install -yqq --no-install-recommends build-essential pkg-config libdbus-1-dev libusb-1.0-0-dev
309+
310+
- name: Setup Python
311+
uses: actions/setup-python@v6
312+
with:
313+
python-version-file: "./mintlayer-core/build-tools/.python-version"
314+
315+
- name: Extract required info from Cargo.toml
316+
id: extract_cargo_info
317+
run: echo "RUST_VERSION=$(python ./build-tools/cargo-info-extractor/extract.py --rust-version)" >> $GITHUB_OUTPUT
318+
working-directory: ./mintlayer-core
319+
320+
- name: Install Rust
321+
run: |
322+
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y \
323+
--default-toolchain ${{ steps.extract_cargo_info.outputs.RUST_VERSION }}
324+
325+
- name: Install cargo-nextest
326+
uses: taiki-e/install-action@nextest
327+
328+
- name: Build and archive the tests
329+
run: cargo nextest archive --release --locked -p wallet --features enable-ledger-device-tests --archive-file ledger-tests.tar.zst
330+
working-directory: ./mintlayer-core
331+
332+
- name: Upload archived tests
333+
uses: actions/upload-artifact@v4
334+
with:
335+
name: archived-ledger-tests
336+
path: ./mintlayer-core/ledger-tests.tar.zst
337+
retention-days: 1
338+
339+
# Run Ledger-specific tests on an emulator
340+
run_tests_on_ledger:
341+
needs: run_tests_on_ledger_preparation
342+
runs-on: ubuntu-latest
343+
strategy:
344+
matrix:
345+
model: [apex_p, flex, stax, nanox, nanosplus]
346+
env:
347+
LEDGER_TESTS_AUTO_CONFIRM: true
348+
steps:
349+
- name: Checkout the core repository
350+
uses: actions/checkout@v5
351+
with:
352+
submodules: recursive
353+
path: ./mintlayer-core
354+
355+
- name: Checkout mintlayer-ledger-app repository
356+
uses: actions/checkout@v5
357+
with:
358+
repository: mintlayer/mintlayer-ledger-app
359+
ref: feature/mintlayer-app
360+
path: ./mintlayer-ledger-app
361+
362+
- name: Download archived tests
363+
uses: actions/download-artifact@v4
364+
with:
365+
name: archived-ledger-tests
366+
path: ./mintlayer-core
367+
368+
- name: Install cargo-nextest
369+
uses: taiki-e/install-action@nextest
370+
371+
- name: Build Ledger app in container
372+
run: |
373+
sudo docker run --rm \
374+
-v "$(realpath ./mintlayer-ledger-app):/app" \
375+
ghcr.io/ledgerhq/ledger-app-builder/ledger-app-dev-tools:latest \
376+
sh -c 'cargo ledger build ${{ matrix.model }}'
377+
378+
- name: Run Ledger emulator and execute tests
379+
run: |
380+
set -e
381+
382+
sudo docker run -d --rm --name ledger-emulator \
383+
-v "$(realpath ./mintlayer-ledger-app):/app" \
384+
--publish 5000:5000 --publish 9999:9999 \
385+
ghcr.io/ledgerhq/ledger-app-builder/ledger-app-dev-tools:latest \
386+
sh -c 'speculos --apdu-port 9999 --api-port 5000 --display headless \
387+
-s "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about" \
388+
target/${{ matrix.model }}/release/mintlayer-app'
389+
390+
echo "--- Waiting for emulator to initialize ---"
391+
sleep 15
392+
393+
# Set up a trap to ensure the container is stopped even if tests fail or the job is cancelled
394+
trap "echo '--- Dumping Ledger emulator logs ---'; \
395+
sudo docker logs ledger-emulator; \
396+
echo '--- Stopping Ledger emulator ---'; \
397+
sudo docker stop ledger-emulator" \
398+
EXIT
399+
400+
echo "--- Running Ledger device tests on the host ---"
401+
cd ./mintlayer-core
402+
403+
# Export the device model from the matrix so the Rust test can pick it up
404+
export LEDGER_TESTS_DEVICE_MODEL=${{ matrix.model }}
405+
406+
cargo-nextest nextest run --archive-file ledger-tests.tar.zst -j1 ledger_signer
407+
timeout-minutes: 15

.github/workflows/code_checks.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ on:
88
branches:
99
- "**" # target all branches
1010
schedule:
11-
- cron: '15 0 * * *' # every day at 00:15 UTC
11+
- cron: "15 0 * * *" # every day at 00:15 UTC
1212

1313
env:
1414
CARGO_TERM_COLOR: always
@@ -28,12 +28,12 @@ jobs:
2828
run: sudo apt-get update
2929

3030
- name: Install build dependencies
31-
run: sudo apt-get install -yqq --no-install-recommends build-essential
31+
run: sudo apt-get install -yqq --no-install-recommends build-essential libdbus-1-dev libusb-1.0-0-dev
3232

3333
- name: Setup Python
3434
uses: actions/setup-python@v6
3535
with:
36-
python-version-file: './build-tools/.python-version'
36+
python-version-file: "./build-tools/.python-version"
3737

3838
- name: Install Rust
3939
run: |
@@ -69,7 +69,7 @@ jobs:
6969
- name: Setup Python
7070
uses: actions/setup-python@v6
7171
with:
72-
python-version-file: './build-tools/.python-version'
72+
python-version-file: "./build-tools/.python-version"
7373

7474
- name: Install Rust
7575
# Use bash to be able to escape the newline via '\'.
@@ -102,7 +102,7 @@ jobs:
102102
- name: Setup Python
103103
uses: actions/setup-python@v6
104104
with:
105-
python-version-file: './build-tools/.python-version'
105+
python-version-file: "./build-tools/.python-version"
106106

107107
- name: Install Rust
108108
run: |

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,19 @@ The format is loosely based on [Keep a Changelog](https://keepachangelog.com/en/
1616

1717
- Wallet RPC:
1818
- new methods added: `node_get_tokens_info`, `order_list_own`, `order_list_all_active`.
19+
- new value `ledger` in the `hardware_wallet` option for `wallet_create`, `wallet_recover` and `wallet_open` methods.
1920

2021
- Wallet CLI:
2122
- the commands `order-create`, `order-fill`, `order-freeze`, `order-conclude` were added,
2223
mirroring their existing RPC counterparts;
2324
- other new commands added: `order-list-own`, `order-list-all-active`;
25+
- `wallet-create`/`wallet-recover`/`wallet-open` support the `ledger` subcommand, in addition to the existing
26+
`software` and `trezor`, which specifies the type of the wallet to operate on.
27+
28+
- Wallet:
29+
- Added support for Ledger hardware wallets (beta).
30+
- Now the wallet subscribes to events from the Mempool to include not yet confirmed transactions
31+
relevant to this wallet.
2432

2533
### Changed
2634
- Wallet RPC:

0 commit comments

Comments
 (0)