Skip to main content

Ledger Bitcoin application client

Overview

Client library for Ledger Bitcoin application.

Main repository and documentation: https://github.com/LedgerHQ/app-bitcoin-new

Install

If you just want to communicate through TCP socket (for example with the Speculos emulator), there is no dependency:

$ pip install ledger_bitcoin

otherwise, hidapi must be installed as an extra dependency:

$ pip install ledger_bitcoin[hid]

Getting started

The main method exported by the library is createClient, which queries the hardware wallet for the version of the running app, and then returns the appropriate implementation of the Client class.

See the documentation of the class and the example below for the supported methods.

When running on a legacy version of the app (below version 2.0.0), only the features that were available on the app are supported. Any unsopported method (e.g.: multisig registration or addresses, taproot addresses) will raise a NotImplementedError.

Running with speculos

It is possible to run the app and the library with the speculos emulator.

⚠️ Currently, speculos does not correctly emulate the version of the app, always returning a dummy value; in order to use the library, it is necessary to set the SPECULOS_APPNAME environment variable before starting speculos, for example with:

$ export SPECULOS_APPNAME="Bitcoin Test:2.0.0"

Similarly, to test the library behavior on a legacy version of the app, one can set the version to 1.6.5 (the final version of the 1.X series).

The expected application name is Bitcoin for mainnet, Bitcoin Test for testnet.

Example

The following example showcases all the main methods of the Client's interface.

If you are not using the context manager syntax when creating the client, remember to call the stop() method to release the communication channel.

Testing the sign_psbt method requires producing a valid PSBT (with any external tool that supports either PSBTv0 or PSBTv2), and provide the corresponding wallet policy; it is skipped by default in the following example.

from typing import Optional
from ledger_bitcoin import createClient, Chain, MultisigWallet, MultisigWallet, PolicyMapWallet, AddressType, TransportClient
from ledger_bitcoin.psbt import PSBT


def main():
    # speculos on default host/port
    # with createClient(TransportClient(), chain=Chain.TEST) as client:

    # Ledger Nano connected via USB
    with createClient(chain=Chain.TEST) as client:
        # ==> Get the master key fingerprint

        fpr = client.get_master_fingerprint().hex()
        print(f"Master key fingerprint: {fpr}")

        # ==> Get and display on screen the first taproot address

        first_taproot_account_pubkey = client.get_extended_pubkey("m/86'/1'/0'")
        first_taproot_account_policy = PolicyMapWallet(
            "",
            "tr(@0)",
            [
                f"[{fpr}/86'/1'/0']{first_taproot_account_pubkey}/**"
            ],
        )
        first_taproot_account_address = client.get_wallet_address(
            first_taproot_account_policy,
            None,
            change=0,
            address_index=0,
            display=True # show address on the wallet's screen
        )

        print(f"First taproot account receive address: {first_taproot_account_address}")

        # ==> Register a multisig wallet named "Cold storage"

        our_pubkey = client.get_extended_pubkey("m/48'/1'/0'/2'")
        other_key_info = "[76223a6e/48'/1'/0'/2']tpubDE7NQymr4AFtewpAsWtnreyq9ghkzQBXpCZjWLFVRAvnbf7vya2eMTvT2fPapNqL8SuVvLQdbUbMfWLVDCZKnsEBqp6UK93QEzL8Ck23AwF/**"

        multisig_policy = MultisigWallet(
            name="Cold storage",
            address_type=AddressType.WIT,
            threshold=2,
            keys_info=[
                other_key_info,                          # some other bitcoiner
                f"[{fpr}/48'/1'/0'/2']{our_pubkey}/**",  # that's us
            ],
        )

        policy_id, policy_hmac = client.register_wallet(multisig_policy)

        print(f"Policy hmac: {policy_hmac.hex()}. Store it safely (together with the policy).")

        assert policy_id == multisig_policy.id  # should never fail

        # ==> Derive and show an address for "Cold storage"

        multisig_address = client.get_wallet_address(multisig_policy, policy_hmac, change=0, address_index=0, display=True)
        print(f"Multisig wallet address: {multisig_address}")

        # ==> Sign a psbt

        # TODO: set a wallet policy and a valid psbt file in order to test psbt signing
        psbt_filename: Optional[str] = None
        signing_policy: Optional[PolicyMapWallet] = None
        signing_policy_hmac: Optional[bytes] = None
        if not psbt_filename or not signing_policy:
            print("Nothing to sign :(")
            return

        raw_psbt_base64 = open(psbt_filename, "r").read()
        psbt = PSBT()
        psbt.deserialize(raw_psbt_base64)

        result = client.sign_psbt(psbt, signing_policy, signing_policy_hmac)

        print("Returned signatures:")
        print(result)

if __name__ == "__main__":
    main()

Metadata

Release files for ledger-bitcoin 0.0.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ledger-bitcoin 0.0.1
File Size Uploaded
ledger_bitcoin-0.0.1.tar.gz 57.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for ledger-bitcoin 0.0.1
File Interpreter ABI Platform
ledger_bitcoin-0.0.1-py3-none-any.whl Python 3 none any Details

Total release size: 127.2 kB

Release files / ledger_bitcoin-0.0.1.tar.gz

Download URL ledger_bitcoin-0.0.1.tar.gz
Size 57.6 kB
Tags Source
SHA-256 checksum
How to use checksums
5e8680456c4761879b0884a489aa76e70662489624165f2457a07e177e6307a9
BLAKE2b-256 checksum
How to use checksums
0d967fe8919a750cd564520fd929b80c862a923285f2bbef487a35c945f50570
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.6.0 importlib_metadata/4.8.2 pkginfo/1.8.0 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.30.0 CPython/3.8.10

Release files / ledger_bitcoin-0.0.1-py3-none-any.whl

Download URL ledger_bitcoin-0.0.1-py3-none-any.whl
Size 69.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8602366318e7977cf693ab84904bc5ce28531911f816d7a23f578b37ace130f8
BLAKE2b-256 checksum
How to use checksums
268e4c48859bfbe5a6f066ec8b57ce40413de17fb3e6b1ebbd2bdaf7446d55a5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.6.0 importlib_metadata/4.8.2 pkginfo/1.8.0 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.30.0 CPython/3.8.10

Release history Release notifications | RSS feed

0.4.2

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

0.0.3

2 release files

0.0.2

2 release files

This release

0.0.1 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page