Skip to content

Instantly share code, notes, and snippets.

@Sjors Sjors/overview.md

Last active Aug 6, 2020
Embed
What would you like to do?
Hardware Wallet Support in GUI and RPC, using HWI

Project: https://github.com/bitcoin/bitcoin/projects/15

Final User Experience

A user plugs in their hardware wallet and creates a new wallet. It automatigically detects the device and imports the keys:

The user can verify a receive address on their device with just a click:

And they can create a transaction just like usual, except that they approve it on the device.

The only inconvienient step required is to install HWI, or any program with the same interface, and maybe point to it in settings:

This has all been roughly implemented in bitcoin-core/gui#4, this gist explains the prerequisites. I try to keep this PR rebased, and I actually use it (though that's not a recommendation).

First, RPC

It's easier to implement new RPC commands, and it's especially easier to provide good test coverage for them. This is what #16546 does.

It adds the following RPC methods:

  • enumeratesigners: asks for a list of signers (e.g. devices) and their master key fingerprint
  • signerdisplayaddress <address>: asks to display an address

It enhances the following RPC methods:

  • createwallet: takes an additional external_signer argument and fetches keys from device
  • send: automatically sends transaction to device and waits

Where <cmd> is usually HWI, configured via -signer.

These RPC calls add less value than the GUI changes, because anyone who can use the RPC can also use HWI directly. enumeratesigners is mostly a way to check your configuration. However they still offer a flow that's significantly easier compared to HWI's current instructions. Creating a wallet, verifying an address and sending coins takes far less back and forth.

RPC & GUI prequisite 1: spin up process, get JSON result

Merged!

Both the RPC and GUI PR's need a way to communicate with HWI. PR #15382 provides this. It introduces UniValue runCommandParseJSON(const std::string& strCommand), similar to runCommand, but with the ability to process the result. You'd think this is trivial, but if you read the PR discussion you'll find it's not. It uses Boost::Process for lack of better alternative, as evidenced by 18 months of such alternative not magically showing up :-) This can be swapped out later.

RPC & GUI prequisite 2: PSBT support for sendmany, sendtoaddress or new RPC

I initially tried overloading the sendmany and sendtoaddress RPC calls with PSBT functionality, but this was seen as problematic. So instead I'm introducing a brand new send RPC in #16378. That itself isn't terribly complicated, but it comes with three dependencies of its own, in particular #11413. These are stuck in review limbo, but I think they can move forward. If not, it should be possible to work around them as well.

To make review easier, I inserted a quick-hack commit into #16546 which overloads sendmany. That's the only commit (marked as DO NOT MERGE) not ready for review in that PR, and replacing it should have neglible effect on the rest.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.