Files
archy/docs/hardware-wallet-integration.md
Dorian f07ce10b1a refactor: update dependencies and remove unused code
- Added new dependencies: `adler2`, `crc32fast`, `flate2`, `miniz_oxide`, and `libredox`.
- Updated existing dependencies: `tokio-rustls` to version 0.26.4 and `filetime` to version 0.2.27.
- Removed the `backup.rs` file as it is no longer needed.
- Introduced tests for configuration and credential management.
- Enhanced the `identity` module to generate W3C compliant DID documents.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 00:19:30 +00:00

7.2 KiB

Hardware Wallet Integration Architecture

Overview

Archipelago supports hardware wallets for secure Bitcoin transaction signing via PSBT (Partially Signed Bitcoin Transactions). This document covers integration with ColdCard, Trezor, and Ledger hardware wallets.

Supported Devices

Device Connection PSBT Support DID Signing Detection
ColdCard Mk4 USB / MicroSD / NFC Native PSBT No (Bitcoin-only) USB VID 0xd13e
Trezor Model T/Safe 3 USB / WebUSB Via trezorctl No USB VID 0x534c (SatoshiLabs)
Ledger Nano S/X/Plus USB / Bluetooth Via HWI No USB VID 0x2c97

Architecture

┌─────────────────────────────────────────────────────────────────┐
│  Archipelago Node                                               │
│                                                                 │
│  ┌──────────┐    ┌────────────┐    ┌──────────────────────────┐ │
│  │ Web UI   │───▸│ RPC Server │───▸│ LND (gRPC)              │ │
│  │          │    │            │    │  - FundPsbt              │ │
│  │ QR code  │    │ lnd.create │    │  - SignPsbt (partial)    │ │
│  │ display  │    │   -psbt    │    │  - FinalizePsbt          │ │
│  │          │    │            │    │  - PublishTransaction    │ │
│  │ File     │    │ lnd.final  │    └──────────────────────────┘ │
│  │ upload   │    │   ize-psbt │                                 │
│  └──────────┘    └────────────┘                                 │
│       ▲                                                         │
│       │ PSBT (base64)                                           │
│       ▼                                                         │
│  ┌──────────────────────┐                                       │
│  │ Hardware Wallet      │                                       │
│  │  - USB direct        │                                       │
│  │  - QR code scan      │                                       │
│  │  - MicroSD (CC)      │                                       │
│  └──────────────────────┘                                       │
└─────────────────────────────────────────────────────────────────┘

PSBT Signing Flow

1. Create Unsigned PSBT

The user initiates a transaction (send coins, open channel, close channel). Instead of LND signing automatically, we create an unsigned PSBT.

RPC endpoint: lnd.create-psbt

{
  "method": "lnd.create-psbt",
  "params": {
    "outputs": [{"address": "bc1q...", "amount_sats": 50000}],
    "fee_rate_sat_per_vbyte": 10,
    "change_address": "bc1q..."
  }
}

Response:

{
  "psbt_base64": "cHNidP8BAH...",
  "psbt_hex": "70736274ff...",
  "estimated_fee_sats": 1420,
  "inputs": [{"txid": "abc...", "vout": 0, "amount_sats": 100000}],
  "outputs": [{"address": "bc1q...", "amount_sats": 50000}, {"address": "bc1q...", "amount_sats": 48580}]
}

LND gRPC mapping: Uses WalletKit.FundPsbt to select UTXOs and create the PSBT template.

2. Sign with Hardware Wallet

Three transfer methods supported:

QR Code (ColdCard NFC, Trezor via companion app)

  • Display PSBT as animated QR code (BBQr format for large PSBTs)
  • User scans with hardware wallet
  • Hardware wallet displays transaction details for verification
  • User confirms on device
  • Signed PSBT returned as QR code — user scans with camera or uploads screenshot

USB Direct (Trezor, Ledger)

  • Detect hardware wallet USB device
  • Pass PSBT via USB HID protocol
  • User confirms on device
  • Signed PSBT returned via USB

MicroSD (ColdCard)

  • Export PSBT file for download
  • User transfers to ColdCard via MicroSD
  • ColdCard signs and saves signed PSBT to MicroSD
  • User uploads signed PSBT file back to Archipelago

3. Finalize and Broadcast

RPC endpoint: lnd.finalize-psbt

{
  "method": "lnd.finalize-psbt",
  "params": {
    "signed_psbt_base64": "cHNidP8BAH..."
  }
}

Response:

{
  "txid": "abc123...",
  "raw_tx_hex": "0200000001...",
  "broadcast": true
}

LND gRPC mapping: Uses WalletKit.FinalizePsbt then WalletKit.PublishTransaction.

USB Device Detection

RPC endpoint: system.detect-usb-devices

Scans /sys/bus/usb/devices/ or uses lsusb to detect known hardware wallet vendor IDs:

Vendor VID Product IDs
ColdCard (Coinkite) 0xd13e 0xcc10 (Mk4), 0xcc20 (Q)
Trezor (SatoshiLabs) 0x534c 0x0001 (One), 0x0002 (T)
Ledger 0x2c97 0x0001 (Nano S), 0x0004 (Nano X), 0x0005 (Nano S+)

Implementation approach:

// Read from /sys/bus/usb/devices/*/idVendor and idProduct
async fn detect_usb_devices(known_vids: &[(u16, &str)]) -> Vec<DetectedDevice> {
    // Parse /sys/bus/usb/devices/X-Y/idVendor
    // Match against known VIDs
    // Return device list with type identification
}

The detection runs server-side since the hardware wallet is plugged into the Archipelago node (not the browser).

UI Integration Points

Send Coins View

  • Add "Sign with Hardware Wallet" toggle/option
  • When enabled: create unsigned PSBT → show QR/download → accept signed PSBT → finalize

Channel Management

  • Open Channel: PSBT funding option
  • Close Channel: Cooperative close via PSBT

Hardware Wallet Status

  • Show notification banner when USB device detected
  • Display device type and connection status
  • Auto-detect on the Server/Dashboard page

Security Considerations

  1. PSBT verification: Display transaction details (amounts, addresses, fees) before and after hardware signing — user should verify they match
  2. No private keys on node: When using hardware wallet flow, LND's internal wallet creates watch-only inputs; the hardware wallet holds the actual signing keys
  3. PSBT size limits: QR codes can handle ~2KB; larger PSBTs need animated QR (BBQr) or file transfer
  4. USB permissions: The archipelago user needs access to USB HID devices (udev rules)

Implementation Priority

  1. Phase 1 (HW-02): PSBT create/finalize RPC endpoints via LND gRPC
  2. Phase 2 (HW-03): QR code display + file upload UI
  3. Phase 3 (HW-04): USB device detection and notification
  4. Future: Direct USB HID communication (trezorlib, ledger-transport)

Dependencies

  • LND v0.18+ (PSBT API via WalletKit)
  • qrcode npm package (QR generation in UI)
  • lsusb or /sys/bus/usb/ access (device detection)
  • No external hardware wallet libraries needed for Phase 1-3 (PSBT is a standard format)