doc: update interface, –stdin flag, signtx (#31005) #33765

pull cobratbq wants to merge 1 commits into bitcoin:master from cobratbq:external-signer-docs changing 1 files +58 −28
  1. cobratbq commented at 11:24 pm on November 2, 2025: none

    Updates to documentation for External Signer.

    • Added mention that signtransaction command is no longer primary mechanism.
    • Document inter-process communication via --stdin flag followed with stdin-content.
    • Document signtx command followed by Base64-encoded PSBT.

    Best to squash commits when ready to merge.

  2. DrahtBot added the label Docs on Nov 2, 2025
  3. DrahtBot commented at 11:25 pm on November 2, 2025: contributor

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    Code Coverage & Benchmarks

    For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/33765.

    Reviews

    See the guideline for information on the review process. A summary of reviews will appear here.

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #33112 (wallet: relax external_signer flag constraints by Sjors)
    • #30354 (doc: external-signer, example ‘createwallet’ RPC call requires eight argument by cobratbq)

    If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

    LLM Linter (✨ experimental)

    Possible typos and grammar issues:

    • “being written to external-signer process directly through stdin” -> “being written to the external-signer process directly through stdin” [missing definite article “the” makes the phrase slightly ungrammatical]
    • “This command reads request signtx <base64-encoded psbt> from stdin” -> “This command reads a request signtx <base64-encoded psbt> from stdin” [missing article “a” before “request” makes the sentence ungrammatical]

    No other typographic or grammatical errors that impact comprehension were found.

    2025-12-10

  4. in doc/external-signer.md:86 in 6f5fc6a949
    77@@ -78,6 +78,28 @@ Prerequisite knowledge:
    78 * [Output Descriptors](descriptors.md)
    79 * Partially Signed Bitcoin Transaction ([PSBT](psbt.md))
    80 
    81+### Flag `--stdin` (required)
    82+
    83+Usage:
    84+```
    85+$ <cmd> --stdin
    86+[…IPC interaction written to stdin…]
    


    Sjors commented at 11:13 am on November 11, 2025:

    The term “IPC” could be confused with our multiprocess integration, maybe just use the wording from hwi --help:

    --stdin Enter commands and arguments via stdin


    cobratbq commented at 10:01 pm on November 11, 2025:
    Makes sense. Will do. (FWIW, technically this is multi-process interop :-P)
  5. in doc/external-signer.md:95 in 6f5fc6a949
    90+
    91+```
    92+signtx "<Base64-encoded PSBT-content>"
    93+```
    94+
    95+`signtx` indicates a PSBT signing request, followed by Base64-encoded PSBT-content. Quotes are optional, added in more recent versions. Semantically there is no difference, as Base64-encoded content is an uninterrupted sequence of characters regardless.
    


    Sjors commented at 11:15 am on November 11, 2025:

    Afaik the use of quotes depends on the shell environment, I don’t think it’s worth documenting.

    More important is to point out that Bitcoin Core will use --stdin here, in order to support large PSBTs.


    cobratbq commented at 10:03 pm on November 11, 2025:
    This is content that is written to stdout, thus piped to external-signer. This is not part of the commandline, such that a shell might interfere or otherwise preprocess. Thus quotes are passed on as any other byte. Consequently, probably better to mention this.
  6. in doc/external-signer.md:121 in 6f5fc6a949
    119@@ -98,6 +120,8 @@ A future extension could add an optional return field `reachable`, in case `<cmd
    120 
    121 ### `signtransaction` (required)
    


    Sjors commented at 11:17 am on November 11, 2025:

    The original doc is wrong, there is only signtx, no signtransaction.

    signtx and its arguments, like all other commands, can optionally be passed via --stdin


    cobratbq commented at 10:05 pm on November 11, 2025:

    Is your comment that the doc is wrong, or that you moved away from that solution long ago? I only recently got involved with this side of Bitcoin, so I am really only familiar with v27+.

    I can drop the signtransaction shell command for the sake obsolescence regardless, but it would be nice to know.


    Sjors commented at 8:34 am on November 12, 2025:

    I don’t think there was ever a signtransaction, it was just a typo in the docs. The external signer feature was introduced in v22. The docs from that time mentions signtransaction and not signtx: https://github.com/bitcoin/bitcoin/blob/v22.0/doc/external-signer.md

    Looking at the code from v22.0 however, the actual command was already signtx.

  7. Sjors commented at 11:20 am on November 11, 2025: member
    Good idea to update these docs.
  8. cobratbq commented at 10:06 pm on November 11, 2025: none

    Good idea to update these docs.

    Yes … I was inspired by a certain #31005 (comment)

  9. cobratbq force-pushed on Nov 11, 2025
  10. in doc/external-signer.md:89 in e1d431cb2a
    84+```
    85+$ <cmd> --stdin
    86+[…command and arguments written to stdin…]
    87+```
    88+
    89+#### stdin-command `signtx` (required)
    


    Sjors commented at 8:37 am on November 12, 2025:

    signtx is not inherently stdin

    All (required) commands should work with or without --stdin. Bitcoin Core currently only uses it for signtx, and that’s worth mentioning, but it can change.


    cobratbq commented at 7:00 pm on November 12, 2025:

    Oookaaaaaay .. that changes things considerably. That was not at all clear to me.

    Any chance you can drop a link to the place in source-code (assuming it is somewhat concentrated), such that I can have a quick peek. I could search myself, but I suspect you are familiar with the code-base.



    cobratbq commented at 5:58 pm on November 26, 2025:
    yeah, sry, I had found it already. I realized that it essentially just concerns text being prepended, so it is mostly whoever “tells the story” on this API. I will make the changes, or have made; need to (re)check.
  11. cobratbq renamed this:
    doc: update interface, --stdin flag, IPC-command signtx (#31005)
    doc: update interface, --stdin flag, `signtx` (#31005)
    on Nov 17, 2025
  12. DrahtBot added the label CI failed on Nov 26, 2025
  13. maflcko commented at 2:29 pm on November 26, 2025: member

    Please use unique, descriptive commit message, or squash your commits according to https://github.com/bitcoin/bitcoin/blob/master/CONTRIBUTING.md#squashing-commits.

    Also, there are a few LLM linter comments. Not sure if they all apply, but the missing a article makes sense.

  14. cobratbq force-pushed on Nov 26, 2025
  15. cobratbq commented at 7:14 pm on November 26, 2025: none
    @maflcko I expected that someone would squash upon integrating the work. Now squashed. I included some of the changes from #33947, though not verbatim. It may be worth checking the changes again, as a whole.
  16. cobratbq force-pushed on Nov 27, 2025
  17. DrahtBot removed the label CI failed on Nov 28, 2025
  18. in doc/external-signer.md:44 in 8f6f147ddf
    42 
    43 Create a wallet, this automatically imports the public keys:
    44 
    45 ```sh
    46-$ bitcoin-cli createwallet "hww" true true "" true true true
    47+$ bitcoin-cli -named createwallet wallet_name="hww" disable_private_keys=true external_signer=true
    


    Sjors commented at 12:04 pm on December 10, 2025:
    Alternatively you can use bitcoin rpc createwallet, which sets -named automatically.

    cobratbq commented at 5:33 pm on December 10, 2025:
    Changed. I’m assuming you propose the contemporary way to access the RPC.
  19. in doc/external-signer.md:47 in 8f6f147ddf
    46-$ bitcoin-cli createwallet "hww" true true "" true true true
    47+$ bitcoin-cli -named createwallet wallet_name="hww" disable_private_keys=true external_signer=true
    48 ```
    49 
    50-`bitcoin rpc` can also be substituted for `bitcoin-cli`.
    51+You can also enter equivalent RPCs in the `bitcoin-qt` Debug Console instead of using `bitcoin-cli`.
    


    Sjors commented at 12:06 pm on December 10, 2025:
    “equivalent RPCs” -> “these commands”?

    cobratbq commented at 5:22 pm on December 10, 2025:
    Copied from other PR, to include their improvements. I’ll tweak it.
  20. in doc/external-signer.md:78 in 8f6f147ddf outdated
    75 ```
    76 
    77 ## Signer API
    78 
    79-In 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.
    80+More recent versions of Bitcoin, around v29 and later, have made significant improvements. It is recommended to use more recent versions.
    


    Sjors commented at 12:07 pm on December 10, 2025:
    I guess the goal here is to specify the minimum Bitcoin Core version that’s compatible with the API described here. If so, let’s say that specifically.

    cobratbq commented at 5:22 pm on December 10, 2025:

    Nope. I do not have sufficient knowledge of Bitcoin Core to state this. Do you have an idea? My goal is to emphasize that older versions behaved differently and less refined, such that there is benefit to start using external-signers with recent Bitcoin versions.

    Maybe we should just leave it out?

  21. in doc/external-signer.md:88 in 8f6f147ddf
    87 
    88+### Flag `--chain <name>` (required)
    89+
    90+With `<name>` one of `main`, `test`, `signet`, `regtest`.
    91+
    92+Previously, flag `--testnet` would be used to indicate "_testnet_" specifically. Presently, all calls of external-signer include `--chain` argument with value.
    


    Sjors commented at 12:08 pm on December 10, 2025:
    We already mention the minimum Bitcoin Core version above, so let’s not enumerate changes, that’s more something for release notes.
  22. in doc/external-signer.md:133 in 8f6f147ddf
    127@@ -96,35 +128,39 @@ A future extension could add an optional return field with device capabilities.
    128 
    129 A future extension could add an optional return field `reachable`, in case `<cmd>` knows a signer exists but can't currently reach it.
    130 
    131-### `signtransaction` (required)
    132+### `signtx` (required)
    133+
    134+`signtx` indicates a PSBT-signing-request, followed by Base64-encoded PSBT-content. Quotes are optional, added in more recent versions. Semantically, there is no difference as Base64-encoded content is an uninterrupted sequence of characters regardless.
    


    Sjors commented at 12:15 pm on December 10, 2025:
    As above, let’s leave out “added in more recent versions”. I would also leave out the “Semantically” comment.

    cobratbq commented at 5:19 pm on December 10, 2025:
    Dropping.
  23. in doc/external-signer.md:141 in 8f6f147ddf
    140+$ <cmd> --fingerprint=<fingerprint> signtx <psbt>
    141+<base64-encode (partially-)signed PSBT>
    142 ```
    143 
    144-The command returns a psbt with any signatures.
    145+With `<psbt>` a Base64-encoded PSBT and updated `<psbt>` result returned.
    


    Sjors commented at 12:17 pm on December 10, 2025:
    What do you mean by “With <psbt>”?

    cobratbq commented at 5:17 pm on December 10, 2025:
    Dropped this, and cleaning up other parts. This is messy because the documentation describes both the commandline interface and the stdin at the same time.
  24. in doc/external-signer.md:143 in 8f6f147ddf
    143 
    144-The command returns a psbt with any signatures.
    145+With `<psbt>` a Base64-encoded PSBT and updated `<psbt>` result returned.
    146 
    147-The `psbt` SHOULD include bip32 derivations. The command SHOULD fail if none of the bip32 derivations match a key owned by the device.
    148+The command reads the request from stdin and MUST return a JSON object. On success, it MUST contain `{"psbt": "<base64_psbt>"}` updated to include any new signatures. On failure, it SHOULD contain `{"error": "<message>"}`. A key `error` with value `null` is ignored, therefore interpreted as not an error.
    


    Sjors commented at 12:20 pm on December 10, 2025:

    The command reads the request from stdin

    You already cover this in the general section about stdin.

    and MUST return a JSON object

    All commands do.

    On success, it MUST contain … as not an err

    This seems needlessly verbose.

    A key error with value null is ignored,

    Is this a known HWI bug? Otherwise it doesn’t seem worth bringing up and client software shouldn’t do this.


    cobratbq commented at 5:15 pm on December 10, 2025:
    Not so. Not all commands are expected to interact via stdin. signtx does interact via stdin. I removed another sections, but left on the “On success ..”. Based on what is it verbose, because I am not otherwise familiar with Bitcoin Core RPC and I find it useful to have these bits of behavior made explicit.

    cobratbq commented at 5:16 pm on December 10, 2025:
    My involvement is not through HWI. I want to emphasize that presence of error in a successful result is not an issue if "error": null.
  25. in doc/external-signer.md:137 in 8f6f147ddf outdated
    145+With `<psbt>` a Base64-encoded PSBT and updated `<psbt>` result returned.
    146 
    147-The `psbt` SHOULD include bip32 derivations. The command SHOULD fail if none of the bip32 derivations match a key owned by the device.
    148+The command reads the request from stdin and MUST return a JSON object. On success, it MUST contain `{"psbt": "<base64_psbt>"}` updated to include any new signatures. On failure, it SHOULD contain `{"error": "<message>"}`. A key `error` with value `null` is ignored, therefore interpreted as not an error.
    149+
    150+PSBT-content SHOULD include BIP32-derivations. The command SHOULD fail if none of the BIP32-derivations match a key owned by the device.
    


    Sjors commented at 12:21 pm on December 10, 2025:
    Is there any hardware wallet that can sign without BIP32 derivations?

    cobratbq commented at 4:53 pm on December 10, 2025:
    Not all of the text is by my own judgement. However, you might leave out BIP-32 derivations for keys not under own management. Technically, those would never be expected to be signed with this call to external-signer.
  26. in doc/external-signer.md:214 in 8f6f147ddf
    216-It then imports descriptors for all support address types, in a BIP44/49/84 compatible manner.
    217+It then imports descriptors for all supported address types, in a BIP44/49/84/86 compatible manner.
    218 
    219 The `walletdisplayaddress` RPC reuses some code from `getaddressinfo` on the provided address and obtains the inferred descriptor. It then calls `<cmd> --fingerprint=00000000 displayaddress --desc=<descriptor>`.
    220 
    221+For external-signer wallets, spending uses `send` or `sendall`. Bitcoin Core builds a PSBT, calls the signer via stdin with `signtx`, and if signatures are sufficient, finalizes and broadcasts the transaction. If the signer is not connected or cancels, the call fails with an error. For fee-bumping on such wallets, use `psbtbumpfee` when interactive signing is required.
    


    Sjors commented at 12:23 pm on December 10, 2025:

    For external-signer wallets, sspending uses send or sendall

    I think you mean: to spend from an external-signer wallet, use the send or sendall RPCs.

    when interactive signing is required

    ?


    cobratbq commented at 4:56 pm on December 10, 2025:
    I took those from #33947. I’ll tweak them a bit.
  27. Sjors commented at 12:24 pm on December 10, 2025: member

    Looks mostly good, but some text seems off or needlessly verbose.

    I expected that someone would squash upon integrating the work.

    Maintainers don’t touch the original commits, which is especially nice if you GPG sign them.

    Whenever you push an update, just squash the changes right away, reviewers will figure out how to view the diff.

  28. cobratbq force-pushed on Dec 10, 2025
  29. doc: external signer: update interface, --stdin flag, IPC-command signtx, contains updates from #33947 15da876e6e
  30. cobratbq force-pushed on Dec 10, 2025
  31. cobratbq commented at 6:28 pm on December 10, 2025: none

    I expected that someone would squash upon integrating the work.

    Maintainers don’t touch the original commits, which is especially nice if you GPG sign them.

    That is a fair point. I could sign, but it feels like unnecessarily blowing up the size of a minor contribution.

    update I did a second push that rebases PR to current master.

  32. Sjors commented at 5:54 pm on December 12, 2025: member
    @cobratbq there’s certainly no need to sign commits, but when people do sign, it’s nice that we don’t break the signature.
  33. DrahtBot added the label CI failed on Dec 15, 2025
  34. DrahtBot removed the label CI failed on Dec 16, 2025

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2025-12-19 06:13 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me