This repository contains two ledger applications designed for retrieving keys and signing transactions, intended for use alongside the Desktop wallet.
- Main app (for Ledger Nano S, Ledger Nano S Plus and Ledger Nano X devices)
- Governance app (for Ledger Nano S, and Ledger Nano S Plus devices)
We depend on Nano S Secure SDK and Ledger Secure SDK, which have been added as git submodules. Make sure to initialize submodules when checking out this repository:
git submodule update --init
We provide a small Dockerfile that wraps ledger-app-builder which can be used for building, loading and deleting an application for the Ledger Nano S and Ledger Nano S Plus devices. Our Dockerfile provides the dependency required for zipping a release for sideloading.
To build the Docker image run:
docker build -t concordium/ledger-app-builder .You can now run the Docker container with
docker run --rm -ti -v "/dev/bus/usb:/dev/bus/usb" -v "$(realpath .):/app" --privileged concordium/ledger-app-builder:latestThis repo has two ledger apps. Staying in this folder inside the docker container will build the main app. Navigating into the goverance-app folder inside the docker container will build the governance ledger app (see governanceApp).
You now have access to the commands provided by the Makefile within the docker container:
# Load the application onto the connected device
make load # this does not work for macos/windows out of the box, due to limited usb support.Above command will hold with the output similar as follows when successful and you will need to continue the flow on your ledger device to approve the side loading onto your ledger device.
See Troubleshooting when you experience an error instead.
# Delete the application from the connected device
make delete# Switch BOLOS_SDK to build for Nano S Plus
# Note that 'make clean' is a requirement when switching BOLOS_SDK.
export BOLOS_SDK=$NANOSP_SDK
make clean
makeThis approach requires python, pip the pip module ledgerblue to be installed locally on the machine.
python -m ledgerblue.loadApp --targetId <target-id> --apiLevel 24 --fileName bin/app.hex --appName <app-name> --appVersion <app-version> --delete --tlv
- app-name: the application name used on the device.
- "Concordium" for the the app used for regular users
- "CCDGovernance" for the governance app
- app-version: the version of the application.
- target-id: the target id of the device.
- "0x33100004" for nano S+
Please note that the apiLevel changes according to the sdk used to build the application.
When side loading onto the ledger device, you may encounter the following common issues (the error codes are from the Ledger Nano S Plus device):
| Issue | Error Message | Resolution |
|---|---|---|
| Outdated Ledger firmware | ledgerblue.commException.CommException: Exception : Invalid status 511f (The OS version on your device does not seem compatible with the SDK version used to build the app) |
Update your device's firmware in Ledger Live. |
| Ledger not connected / unlocked | ledgerblue.commException.CommException: Exception : No dongle found |
Ensure your machine can detect the Ledger (test with Ledger Live) and unlock it by entering your PIN. |
| Not completing flows properly | ledgerblue.commException.CommException: Exception : Invalid status 6603 (Unknown reason)ledgerblue.commException.CommException: Exception : Invalid status 6601 (Unknown reason) |
Ensure you are on the main dashboard in the ledger device before trying to sideload an app. Ensure you complete the on-device prompts completely before sideloading again. The error can happen if you haven't properly completed a previously flow/prompt on the ledger device before trying to sideload again. Re-connecting the ledger device to your machine or moving around the cursor on the ledger device menu or open/closing apps on the ledger often resolves the issue so that the sideloading command works again. |
As the Ledger Nano X does not support sideloading, the only way to test updates on a Nano X is
to use the Speculos emulator. Please follow their documentation
for how to setup the emulator. To build the .elf file required by the emulator run:
export BOLOS_SDK=$NANOX_SDK
make emulator
The file will be available at bin/app.elf.
Refer to the official documentation provided by Ledger. For quick development when deploying to the device, make sure to deploy a custom certificate to the device. See the "PIN Bypass" section here.
For documentation of the exposed functionality and how to integrate with the Concordium specific applications, please take a look here.
A make target is available for linting:
make lintThere are unit tests on some of the functions that do not rely on Ledger specific libraries. First, you must have the following installed:
- CMake >= 3.10
- CMocka >= 1.1.5
To build the tests:
cd unit_tests
cmake -Bbuild -H. && make -C buildWhile still in the unit_tests directory, execute the following to run the unit tests:
CTEST_OUTPUT_ON_FAILURE=1 make -C build testAn end to end test is available for each instruction implemented in the application. The end
to end tests depend on having built the application for Nano S, Nano SP and Nano X, and having placed
their .elf files correctly. This can achieved by running (from within Docker):
cd tests
./build_binaries.shTo fetch the required dependencies run:
yarnWhile still in the tests directory, execute the following to run the end to end tests:
yarn testNote that it is only possible to build a release for the Ledger Nano S and the Ledger Nano S plus. This is because only those devices allow for sideloading of an application.
To make a new release of the Concordium Ledger application you must use the Docker setup described above.
Additionally you must set the following environment variables
LEDGER_SIGNING_KEY=private_key_used_for_signing_releases
LEDGER_PUBLIC_KEY=public_key_matching_the_signing_key
To build a new release make sure that APPVERSION has been bumped correctly, and then run
make clean
export BOLOS_SDK=$NANOS_SDK
make release
make clean
export BOLOS_SDK=$NANOSP_SDK
make release
The release will be packaged into two .zip archives, each with the required binary and the corresponding install scripts.
