CLI tool
bitcoin-core/HWI avatar
bitcoin-core/HWI

Bitcoin Hardware Wallet Interface: one command set across vendors

Bitcoin Hardware Wallet Interface

603 stars244 forksPythonMIT

At a glance

What is it?
HWI is a Python library and command line tool that gives software a standard way to talk to Bitcoin hardware wallets, so applications do not have to implement device specific drivers. It is MIT licensed and ships as the hwi console script plus a Qt front end.
Who is it for?
HWI fits teams building wallet software in Python or in any language willing to shell out to a command and parse JSON, and it fits a person who wants one tool instead of a pile of vendor scripts. It does not fit a project that cannot install udev rules and USB libraries on the host, or one that needs mobile or remote signer access.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 59 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem is the driver layer, not the wallet

Every hardware wallet vendor ships its own way of talking to the device, and application authors end up writing that layer themselves, once per vendor. HWI exists to remove that work. The README describes it as a Python library and command line tool for interacting with hardware wallets, providing a standard way for software to work with hardware wallets without needing to implement device specific drivers.

There are two consumption paths, and that is the design decision worth understanding. Python software imports the library, hwilib. Software in other languages executes the hwi tool and reads its output. So the interface is a library first and a command line program second, with the command line existing to serve callers that cannot link against Python.

The README also attaches a caveat that is worth taking seriously as a user rather than as a formality: inclusion of a specific hardware wallet vendor does not imply any endorsement of quality or security. The support list tells you what is implemented, not what to trust with money.

The system libraries come before the Python package

Prerequisites are not optional. Python 3 is required, and the libraries and udev rules for each device must also be installed, with some libraries needing to be installed first. The udev rules live in the repository under hwilib/udev, with their own README.

On Ubuntu and Debian the README gives one command, and on CentOS another, and on macOS a third.

bash
sudo apt install libusb-1.0-0-dev libudev-dev python3-dev
bash
sudo yum -y install python3-devel libusbx-devel systemd-devel
bash
brew install libusb

The practical consequence is that installing HWI is a two stage job, one stage in the operating system and one in Python. A container image that has the Python package baked in is still missing the host level USB and udev plumbing, and the udev rules are per device, so a machine that supports three vendors may need three sets of rules installed.

Install from a clone with pip or Poetry

The README describes the project as using the Poetry dependency manager, and gives a clone based install.

bash
git clone https://github.com/bitcoin-core/HWI.git
cd HWI
pip install . # or poetry install

The same result is reachable two other ways. Running poetry install in the root source directory installs HWI and its dependencies, and pip3 install . uses the pyproject.toml to do the same automatically. The dependency file splits user dependencies under [tool.poetry.dependencies] from development dependencies under [tool.poetry.dev-dependencies], and the README notes that these are installed with any of the three installation methods.

The project metadata states the supported Python range explicitly.

toml
name = "hwi"
version = "3.2.0"
description = "A library for working with Bitcoin hardware wallets"
authors = [{ name = "Ava Chow", email = "<[email protected]>" }]
license = "MIT"
readme = "README.md"

requires-python = ">=3.10,<3.16"

An upper bound of 3.16 is not generous by current standards, so a team on a newer interpreter has to check compatibility before planning around HWI.

Enumerate first, then address the device by type and path

The command line flow is two steps. You enumerate all devices to find the one you want, then you issue commands to it by naming the device type and the device path.

bash
./hwi.py enumerate
bash
./hwi.py -t <type> -d <path> <command> <command args>

The output contract is what makes the tool usable from another language. All output is in JSON form and sent to stdout. Additional information or prompts go to stderr and are not necessarily in JSON, and the README says that additional information is for debugging purposes. So a shell script can parse stdout as data while a human still sees prompts, but any integration must be strict about not mixing stderr into the parsed stream.

Discovering the available commands is done through the standard help mechanism, both globally and per command.

bash
./hwi.py getdescriptors --help

The README points at the readthedocs documentation, a device support page with a support matrix describing which devices are supported and how, and a separate page on using Bitcoin Core with hardware wallets.

The dependency list is the real description of the attack surface

pyproject.toml is more informative than the README here, because it names every library the tool pulls in. The user dependencies include hidapi for HID access, libusb1 for USB devices, pyserial for serial devices, ecdsa and pyaes for elliptic curve and symmetric crypto work, mnemonic for seed phrase handling, cbor2 and protobuf for encoding, noiseprotocol, semver, and typing-extensions.

Two of those deserve attention from a security standpoint without exaggerating: mnemonic handling and the crypto primitives are exactly where a wallet tool is either careful or dangerous, and the dependency list shows that both concerns live inside the project rather than being delegated. It also shows the interface is not USB only. hidapi and pyserial together mean devices reachable over HID and serial are in scope, not just USB.

The development dependency group tells you what the maintainers use: pyinstaller for building the standalone binaries, autopep8 and flake8 and mypy for linting and typing, and sphinx with sphinxcontrib-autoprogram to generate the command line reference.

Two entry points ship in the package

The project metadata declares a console script and a GUI script.

toml
[project.scripts]
hwi = 'hwilib._cli:main'

[project.gui-scripts]
hwi-qt = 'hwilib._gui:main'

So a pip install gives you an hwi executable on your path and an hwi-qt launcher for the graphical front end. The repository root carries hwi.py and hwi-qt.py as thin entry scripts alongside the hwilib package, and hwi-qt.spec for packaging the GUI on platforms that use that format.

The GUI has a Python version constraint of its own. The optional dependency group is pyside2, pinned to versions at or above 5.15.2.1 and below 6.0, and marked to apply only when python_version is below 3.11. On Python 3.11 and later, that optional dependency does not install, so a deployment that wants the graphical tool on a modern interpreter needs to resolve the Qt binding separately. The packaging configuration also excludes docs and test from the distribution and includes the udev directory, which is a reminder that the rules ship with the package.

Where HWI is the wrong tool

The library does not remove the host work, it standardises the command layer. The udev rules for each device still have to be installed, the USB and HID libraries still have to exist on the machine, and on Linux that is a privileged operation per device. If your deployment model is an isolated server or a container without USB passthrough, none of this applies and HWI is the wrong shape of solution.

For a team writing in a language other than Python, the tool is usable but less pleasant. You shell out to hwi, you get JSON on stdout, and you inherit the process boundary: timeouts, exit codes, and the fact that interactive prompts go to stderr. If your application needs a tight request and response cycle with a device, wrapping a process call is a different engineering exercise from importing a library.

There is also a versioning question for anything that holds funds. The release list shows 3.1.0 on 2024-09-17, a 3.2.0 release candidate on 2026-02-03 and 3.2.0 on 2026-02-10, and the last push was on 2026-08-25, so the tree moves after a release and the tag is not the whole picture. The repository is not archived, the licence is MIT with copyright Andrew Chow, and the documentation is versioned on readthedocs, so a deployment pinning a release should pin the docs version with it.

Editorial conclusion

HWI fits teams building wallet software in Python or in any language willing to shell out to a command and parse JSON, and it fits a person who wants one tool instead of a pile of vendor scripts. It does not fit a project that cannot install udev rules and USB libraries on the host, or one that needs mobile or remote signer access. Verify first that the device you need appears in the support matrix page and that its driver and udev rules are installed, then check the README install path, which asks for Python 3 and a pip or poetry install from a clone.

Frequently asked questions

How do I install the Bitcoin Hardware Wallet Interface?

Python 3 is required, along with the system libraries and udev rules for each device, then you clone the repository and run pip install . or poetry install in the root source directory. The pyproject.toml lists a supported range of requires-python ">=3.10,<3.16".

How do I list the connected hardware wallets with HWI?

Run ./hwi.py enumerate to enumerate all devices and find the one you want, then issue commands with ./hwi.py -t <type> -d <path> <command> <command args>. All output is JSON on stdout, while additional information and prompts go to stderr.

Can software written in a language other than Python use HWI?

Yes. The README states that Python software can use the provided library, hwilib, while software in other languages can execute the hwi tool, so the command line program is the supported interface for non-Python callers.

What licence does the Bitcoin Hardware Wallet Interface use?

The project is available under the MIT License, with the README giving copyright Andrew Chow, and the package metadata also lists license = "MIT".

Official sources

  1. bitcoin-core/HWI on GitHub
  2. Issues
  3. License: MIT
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/bitcoin-core-hwi.svg)](https://hysenlabs.com/projects/bitcoin-core-hwi)

Was this useful?