Ledger Core Library
- Clone project
- Build of C++ library
- Binding to node.js
- Test NodeJs
- Developement guidelines
- Q/A and troubleshooting
Core library which will be used by Ledger applications.
If you’re a developer and want to contribute, please refer to our contribution guidelines specific documentation.
git clone --recurse-submodules https://github.com/LedgerHQ/lib-ledger-core.git
If you had already forked / cloned the repository before issuing that command, it’s okay. You can initiate the submodules with the following commands:
cd lib-ledger-core git submodule init git submodule update
This project is based on cmake as a build system so you should install it before starting (at least version 3.7).
- Qt5 is needed to build tests of the library.
- Generation of binding is automated with Djinni.
- Build on multiple Operating Systems is based on polly toolchains.
Build of C++ library
cmake is building out of source, you should create a build directory (e.g.
. # Directory where clone command was launched ├── lib-ledger-core # Source files directory ├── lib-ledger-core-build # Build directory
If you respect this folder structure (and naming), after
cd lib-ledger-core-build, you can build the library by running:
cmake -DCMAKE_INSTALL_PREFIX=/path/to/qt5 ../lib-ledger-core && make
(macOSX users) If you struggle to find where Qt5 is located, for example, on
qt5can be found at:
Several CMake arguments might interest you there:
-DCMAKE_BUILD_TYPE=Debug: you should always set that when testing as you will get DWARF debug symbols and debugging instruments support.
-DCMAKE_EXPORT_COMPILE_COMMANDS=YES: useful when you’re using a C++ linter, such as cquery.
Building for JNI
Building with JNI (Java Native Interface), allows you to use the library with Java based software. In order to enable JNI mode use
This will add JNI files to the library compilation and remove tests. You need at least a JDK 7 to build for JNI (OpenJDK or Oracle JDK)
Build library on docker
You can build the core library or debug it from a docker image:
- Build the image
docker build -t ledger-core-env .(considering that you are currently at the root of the repository)
- Run the image
docker run -ti --cap-add=SYS_PTRACE --security-opt seccomp=unconfined ledger-core-env
- Notice that stopping a container will wipe it. If you need multiple instance over the same container one way is to start the container as a daemon and then get a shell on it.
- Start the container as daemon
docker run --cap-add=SYS_PTRACE --security-opt seccomp=unconfined -d ledger-core-env
- Get the container ID with
- Open shells
docker exec -ti :container_id zshwhere :container_id has to be replaced by the container you got from
- Start the container as daemon
Note: If you feel on fire you could use docker volumes to persist data.
Build library with OpenSSL
It is possible to build the library with embedded version of OpenSSL (which is advised for Android and iOS builds) or you can rely on OpenSSL provided by the system.
To build the library with system's OpenSSL you should configure the project by providing
-DSYS_OPENSSL=ON option plus some additional variables to allow
cmake to find OpenSSL library:
-DOPENSSL_ROOT_DIR=<path-to-openssl-root-dir>is needed, for example, if you installed OpenSSL through
brewyou can pass:
for example, if you installed OpenSSL through
apt-get it will look like:
In both cases we are supporting OpenSSL
Build library with PostgreSQL
Make sure that your have
PostgreSQL installed on your machine, otherwise the
find_package(PostgreSQL REQUIRED) will fail during configuration.
To compile libcore with PostgreSQL support, you should add
-DPG_SUPPORT=ON to your
CMake configuration command.
For Linux, you might need to add
-DPostgreSQL_INCLUDE_DIR=path/to/include/dir in your configuration
as a hint for headers' location (e.g.
Wallet Pool Configuration
To use with libcore, simply set value of the key
to the database's URL connection and set it in the pool's configuration.
It is also possible to configure the size of the connection pool when instantiating the
If testing locally, make sure to have a running PostgreSQL server.
As an example, if you are running it on
test_db as database name,
database's name forwarded to the pool (through configuration key
should look like :
You can generate the Doxygen documentation by running the
doc target (for instance,
Binding to node.js
The library can be compiled and integrated as an node module in a pretty straightforward way. You will be interested in either using it, or making a new version of the node module.
Using the node module
The lib-ledger-core-node-bindings repository contains the node.js bindings you will need to
lib-ledger-core. You can either clone the git repository or simply install from
npm i @ledgerhq/ledger-core
Generating a new node module for your system
Generating bindings is a several steps process:
- First, you need to make some changes to
lib-ledger-coreand generate a fresh version of
- Clone lib-ledger-core-node-bindings and edit the
package.jsonfile in order to remove or comment the
- In the folder of
lib-ledger-core, run the
tools/generateBindings.shscript by giving it the path to the bindings (i.e. where you cloned lib-ledger-core-node-bindings) and as second argument the path to the directory where you built the
lib-ledger-core— it should be something like
- This script requires an up-to-date djinni. To ensure it’s correctly up to date, go
get fetch origin --prune && git rebase origin/master.
- You will need
java8for a complete, working install.
- The script will generate files in both projects. You’re advised to remove the ones created
lib-ledger-core— if any — with a
git checkout .and/or
git reset ..
- This script requires an up-to-date djinni. To ensure it’s correctly up to date, go into
yarnto generate the bindings.
- You will have the module in
build/Release/ledgerapp_nodejs.nodein the bindings project.
npm ishould install your own version.
Libcore can be built for following OSes:
- MacOS: minimum supported version is
macOS 9.0, with
- Linux: Debian (stretch), Ubuntu and Arch are supported, with
- Windows: 64-bit architecture is built with
MSVC(starting from Visual Studio 15), 32-bit is built with
arm64architectures are supported, minimum supported version is
arm64-v8aarchitectures are supported, minimum supported version is
Android 7 (API 24)(Java 8 is needed).
- NodeJS bindings:
- Please use
<9.0.0(other versions are not tested (yet)),
- Node-gyp is used to build native module and requires
- Please use
You are advised to link your GitHub account to both CircleCI and Appveyor by signing-in. Because we are using shared runners and resources, we have to share CI power with other teams. It’s important to note that we don’t always need to run the CI. Example of situations when we do not need it:
- When we are updating documentation.
- When we are changing a tooling script that is not part of any testing suite (yet).
- When we are making a WIP PR that doesn’t require running the CI until everyone has agreed on the code (this is a tricky workflow but why not).
In those cases, please include the
[skip ci] or
[ci skip] text in your commit message’s
title. You could tempted to put it in the body of your message but that will not work with
Finally, it’s advised to put it on every commit and rebase at the end to remove the
[skip ci] tag
from your commits’ messags to have the CI re-enabled, but some runners might be smart enough to do
it for all commits in the PR.
Rebasing is done easily. If your PR wants to merge
feature/stuff -> develop, you can do something
like this — assuming you have cloned the repository with a correctly set
git checkout feature/stuff git rebase -i origin/develop
reword at the beginning of each lines without changing the text of
the commits — this has no effect. Save the file and quit. You will be prompted to change the
commits’ messages one by one, allowing you to remove the
[skip ci] tag from all commits.
Q/A and troubleshooting
I have updated an include file and test code doesn’t see the changes!
Currently, interface files (headers, .hpp) are not linked by copied directly into the test directory. That means that every time you make a change in the interface that is tested by any code in core/test/, you need to update the copy.
Just run this command:
cd $your_build_folder rm -rf CMakeFiles CMakeCache.txt
I have upgraded my macOSX system and now I can’t compile anymore.
Especially if you’ve upgraded to Mojave for which there are some breaking changes, you will need to perform some manual tasks — here, for macOSX Mojave:
xcode-select --install open /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg