#ledger #ledger-hardware #hardware-wallet #usb-hid #wallet #usb #hid

nightly ledger-lib

Communication library for Ledger hardware wallets

1 unstable release

0.1.0 Jun 16, 2023

#1420 in Hardware support

Download history 38/week @ 2024-01-01 85/week @ 2024-01-08 73/week @ 2024-01-15 48/week @ 2024-01-22 57/week @ 2024-01-29 117/week @ 2024-02-05 76/week @ 2024-02-12 50/week @ 2024-02-19 31/week @ 2024-02-26 43/week @ 2024-03-04 13/week @ 2024-03-11 75/week @ 2024-03-18 15/week @ 2024-03-25 99/week @ 2024-04-01 21/week @ 2024-04-08 15/week @ 2024-04-15

153 downloads per month
Used in 2 crates

Apache-2.0

82KB
1.5K SLoC

A Ledger hardware wallet communication library

[Device] provides a high-level API for exchanging APDUs with Ledger devices using the [ledger_proto] traits. This is suitable for extension with application-specific interface traits, and automatically implemented over [Exchange] for low-level byte exchange with devices.

[LedgerProvider] and [LedgerHandle] provide a high-level tokio-compatible [Transport] for application integration, supporting connecting to and interacting with ledger devices. This uses a pinned thread to avoid thread safety issues with hidapi and async executors.

Low-level [Transport] implementations are provided for USB/HID, BLE and TCP, with a Generic implementation providing a common interface over all enabled transports.

Safety

Transports are currently marked as Send due to limitations of [async_trait] and are NOT all thread safe. If you're calling this from an async context, please use [LedgerProvider].

This will be corrected when the unstable async trait feature is stabilised, which until then can be opted-into using the unstable_async_trait feature

Examples

use ledger_lib::{LedgerProvider, Filters, Transport, Device, DEFAULT_TIMEOUT};

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    // Fetch provider handle
    let mut provider = LedgerProvider::init().await;

    // List available devices
    let devices = provider.list(Filters::Any).await?;

    // Check we have -a- device to connect to
    if devices.is_empty() {
        return Err(anyhow::anyhow!("No devices found"));
    }

    // Connect to the first device
    let mut ledger = provider.connect(devices[0].clone()).await?;

    // Request device information
    let info = ledger.app_info(DEFAULT_TIMEOUT).await?;
    println!("info: {info:?}");

    Ok(())
}

Dependencies

~8–43MB
~612K SLoC