Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1# Support for signing transactions outside of Bitcoin Core3Bitcoin Core can be launched with `-signer=<cmd>` where `<cmd>` is an external tool which can sign transactions and perform other functions. For example, it can be used to communicate with a hardware wallet.5Interaction with external signer uses [Partially Signed Bitcoin Transaction (PSBT)](psbt.md).7## Example usage9The following example is based on the [HWI](https://github.com/bitcoin-core/HWI) tool. Version 2.0 or newer is required. Although this tool is hosted under the Bitcoin Core GitHub organization and maintained by Bitcoin Core developers, it should be used with caution. It is considered experimental and has far less review than Bitcoin Core itself. Be particularly careful when running tools such as these on a computer with private keys on it.11When using a hardware wallet, consult the manufacturer website for (alternative) software they recommend. As long as their software conforms to the standard below, it should be able to work with Bitcoin Core.13Start Bitcoin Core:15```sh16bitcoind -signer=../HWI/hwi.py17```19`bitcoin node` can also be substituted for `bitcoind`.21### Device setup23Follow the hardware manufacturers instructions for the initial device setup, as well as their instructions for creating a backup. Alternatively, for some devices, you can use the `setup`, `restore` and `backup` commands provided by [HWI](https://github.com/bitcoin-core/HWI).25### Create wallet and import keys27Get a list of signing devices / services:29```sh30bitcoin-cli enumeratesigners31```33```34{35"signers": [36{37"fingerprint": "c8df832a",38"name": "trezor_t"39}40]41}42```44The master key fingerprint is used to identify a device.46Create a wallet, this automatically imports the public keys:48```sh49bitcoin rpc createwallet wallet_name="hww2" disable_private_keys=true descriptors=true external_signer=true50```52Creation of the external wallet can be confirmed with `getwalletinfo`, which will report `"external_signer": true`. These commands can also be executed using `bitcoin-qt` Debug Console instead of using `bitcoin rpc` or `bitcoin-cli`.54### Verify an address56Display an address on the device:58```sh59bitcoin-cli -rpcwallet=<walletname> getnewaddress60bitcoin-cli -rpcwallet=<walletname> walletdisplayaddress <address>61```63Replace `<address>` with the result of `getnewaddress`.65### Spending67Under the hood this uses a [PSBT (Partially Signed Bitcoin Transaction)](psbt.md).69```sh70bitcoin rpc -rpcwallet=<walletname> send outputs='{"<address>": <amount>}'71```73This constructs a PSBT and prompts your external signer to sign (will fail if it's not connected). If successful, Bitcoin Core finalizes and broadcasts the transaction.75```76{"complete": true, "txid": "<txid>"}77```79## Signer API81In order to be compatible with Bitcoin Core, any signer command should conform to the specification below. This specification is subject to change. Ideally a BIP should propose a standard so that other wallets can also make use of it.83Prerequisite knowledge:84* [Output Descriptors](descriptors.md)85* Partially Signed Bitcoin Transaction ([PSBT](psbt.md))87### Flag `--chain <name>` (required except for `enumerate`)89With `<name>` one of `main`, `test`, `signet`, `regtest`, `testnet4`.91Bitcoin Core passes this flag to commands that operate on a chain-specific signer, for example `getdescriptors`, `displayaddress` and `signtx`.93### Flag `--stdin` (required)95Indicate that (sub)command should be received over stdin and results returned in response to that. `--stdin` is a global flag, it is not specific to any subcommand.97Bitcoin Core currently uses this flag for `signtx`.99All subcommands SHOULD support both100- being called as commandline arguments; or101- being written to _external-signer_ process directly through stdin (with `--stdin`).103Usage:104```sh105<cmd> --stdin …106```108```109[…command and arguments written to stdin…]110```112Note: remember that shell-expansion is not available on _stdin_. Consequently, commands such as `signtx`, may write their arguments in either quoted or unquoted form.114### Flag `--fingerprint <fingerprint>` (required except for `enumerate`)116With `<fingerprint>` being the hexadecimal 8-symbol identifier for a wallet.118Bitcoin Core passes this flag to commands that operate on a specific external-signer wallet, for example `getdescriptors`, `displayaddress` and `signtx`.120### `enumerate` (required)122Usage:124```sh125<cmd> enumerate126```128```129[130{131"fingerprint": "00000000",132"model": "trezor_t"133}134]135```137The command MUST return an array, possibly empty, of entries that contain at least a `fingerprint` field.139If present, the optional `model` field is used as the device name in the `enumeratesigners` RPC result.141A future extension could add an optional return field with device capabilities. Perhaps a descriptor with wildcards. For example: `["pkh("44'/0'/$'/{0,1}/*"), sh(wpkh("49'/0'/$'/{0,1}/*")), wpkh("84'/0'/$'/{0,1}/*")]`. This would indicate the device supports legacy, wrapped SegWit and native SegWit. In addition it restricts the derivation paths that can used for those, to maintain compatibility with other wallet software. It also indicates the device, or the driver, doesn't support multisig.143A future extension could add an optional return field `reachable`, in case `<cmd>` knows a signer exists but can't currently reach it.145### `signtx` (required)147`signtx` indicates a PSBT signing-request, followed by Base64-encoded PSBT. Quotes are optional.149This command reads request `<base64-encoded psbt>` and MUST return a JSON object. On success, it MUST contain `{"psbt": "<base64-encoded psbt>"}` updated to include any new signatures. On failure, it SHOULD contain `{"error": "<message>"}`. Presence of a key `error` with value `null` is not considered an error.151PSBT SHOULD include BIP32 derivations. The command SHOULD fail if none of the BIP32 derivations match a key owned by the device.153The command SHOULD fail if the user cancels.155The command MAY complain if `--chain` is set to a test-network, but any of the BIP32 derivation paths contain a coin type other than `1h` (and vice versa).157### `getdescriptors` (optional)159Usage:161```sh162<cmd> --fingerprint <fingerprint> --chain <name> getdescriptors --account <account>163```165Returns descriptors supported by the device. Example:167```sh168<cmd> --fingerprint 00000000 --chain main getdescriptors --account 0169```171```172{173"receive": [174"pkh([00000000/44h/0h/0h]xpub6C.../0/*)#fn95jwmg",175"sh(wpkh([00000000/49h/0h/0h]xpub6B..../0/*))#j4r9hntt",176"wpkh([00000000/84h/0h/0h]xpub6C.../0/*)#qw72dxa9",177"tr([00000000/86h/0h/0h]xpub6C.../0/*)#4d8tq2ns"178],179"internal": [180"pkh([00000000/44h/0h/0h]xpub6C.../1/*)#c8q40mts",181"sh(wpkh([00000000/49h/0h/0h]xpub6B..../1/*))#85dn0v75",182"wpkh([00000000/84h/0h/0h]xpub6C..../1/*)#36mtsnda",183"tr([00000000/86h/0h/0h]xpub6C.../1/*)#d63h6jpt"184]185}186```188### `displayaddress` (optional)190Usage:191```sh192<cmd> --fingerprint <fingerprint> --chain <name> displayaddress --desc <descriptor>193```195Example, display the first native SegWit receive address on Testnet:197```sh198<cmd> --fingerprint 00000000 --chain test displayaddress --desc "wpkh([00000000/84h/1h/0h]tpubDDUZ..../0/0)"199```201The command MUST be able to figure out the address type from the descriptor.203The command MUST return an object containing `{"address": "[the address]"}`.204As a sanity check, for devices that support this, it SHOULD ask the device to derive the address.206If `<descriptor>` contains a master key fingerprint, the command MUST fail if it does not match the fingerprint known by the device.208If `<descriptor>` contains an xpub, the command MUST fail if it does not match the xpub known by the device.210The command MAY complain if `--chain` is set to a test-network, but the BIP32 coin-type is not `1h` (and vice versa).212## How Bitcoin Core uses the Signer API214The `enumeratesigners` RPC calls `<cmd> enumerate`, skips duplicate entries with the same `fingerprint`, and maps the optional `model` field to the RPC `name` field.216Wallet operations that need a signer (`createwallet`, `walletdisplayaddress` and spending) also call `<cmd> enumerate` and fail unless exactly one signer is found, so only one device should be connected at a time.218The `createwallet` RPC calls:220* `<cmd> --fingerprint 00000000 --chain <name> getdescriptors --account 0`222It then imports descriptors for all supported address types, in a BIP44/49/84/86 compatible manner.224The `walletdisplayaddress` RPC obtains the inferred descriptor for the provided address. It then calls `<cmd> --fingerprint 00000000 --chain <name> displayaddress --desc <descriptor>`.226For external-signer wallets, spending uses `send` or `sendall`, and fee-bumping uses `bumpfee`. Bitcoin Core builds a PSBT, adds key origin information, checks whether any input key origin fingerprint matches the signer, calls `<cmd> --stdin --fingerprint 00000000 --chain <name>`, and sends `signtx <psbt>` over stdin. If signatures are sufficient, it finalizes the transaction and, for broadcasting RPCs, broadcasts it. If signing cannot complete, the call fails with an error. For manual fee-bumping, use `psbtbumpfee` to obtain a PSBT for signing.
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.