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).
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_signerargument and fetches keys from device
send: automatically sends transaction to device and waits
<cmd> is usually HWI, configured via
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
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
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.