doc, wallet: align external signer documentation, reject sendtoaddress/sendmany #35424

pull w0xlt wants to merge 5 commits into bitcoin:master from w0xlt:doc-external-signer-protocol changing 5 files +56 −27
  1. w0xlt commented at 7:36 AM on May 31, 2026: contributor

    This PR aligns the external signer documentation with current behavior, and makes one previously implicit behavior explicit. Per review feedback, each commit fixes a limited set of issues:

    • doc, rpc: document enumerate model field and fingerprint deduplication — the enumerate response uses the optional model field, which Bitcoin Core maps to the name field of the enumeratesigners RPC result. Duplicate fingerprints are skipped, and wallet operations require exactly one connected signer.

    • doc: replace stale signtransaction wording with current signtx flow — spending from an external signer wallet uses send/sendall (and bumpfee for fee-bumping), which invoke <cmd> --stdin and pass the signtx subcommand and PSBT over stdin.

    • doc: clarify which commands receive --chain, --fingerprint and --stdin — mark --chain and --fingerprint as required except for enumerate, keep --stdin required for protocol flexibility, and match the order and form of the actual invocations in the usage examples.

    • doc: add taproot descriptor to getdescriptors example — show the BIP86 tr() descriptor alongside the other address types.

    • wallet: reject sendtoaddress and sendmany for external signers — return a specific error instead of the misleading "Private keys are disabled for this wallet", with functional test coverage. Cherry-picked from #33112 (thanks Sjors).

    How the documentation went stale:

    • The enumerate example has shown a name field since external signer support landed in #16546, but the implementation has always read model.

    • sendtoaddress/sendmany external signer support was effectively precluded by #21201, which was merged a few days before #16546, so the interaction was missed in review and the documented signtransaction flow never existed in this form.

    • Fingerprint deduplication was added in #35251.

    • The documentation was last updated in #33765.

  2. DrahtBot added the label Docs on May 31, 2026
  3. DrahtBot commented at 7:36 AM on May 31, 2026: contributor

    <!--e57a25ab6845829454e8d69fc972939a-->

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

    <!--006a51241073e994b41acfe9ec718e94-->

    Code Coverage & Benchmarks

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

    <!--021abf342d371248e50ceaed478a90ca-->

    Reviews

    See the guideline for information on the review process.

    Type Reviewers
    ACK Sjors, optout21
    Stale ACK naiyoma

    If your review is incorrectly listed, please copy-paste <code>&lt;!--meta-tag:bot-skip--&gt;</code> into the comment that the bot should ignore.

    <!--5faf32d7da4f0f540f40219e4f7537a3-->

  4. fanquake commented at 1:16 PM on June 1, 2026: member
  5. optout21 commented at 9:23 AM on June 2, 2026: contributor

    Should the eventual deduplication be mentioned when mentioning enumeration? (Related recent PR: #35251)

  6. naiyoma commented at 1:36 PM on June 2, 2026: contributor

    ACK bcc254d1eb4ba168b19532360df715f12f309c08

    Does it make sense to clarify this in the rpc as well?

    
    -                        {RPCResult::Type::STR, "name", "Device name"},
    +                        {RPCResult::Type::STR, "name", "Device name i.e, model returned by the 
    Signer"},
    
    
  7. w0xlt force-pushed on Jun 2, 2026
  8. w0xlt commented at 8:55 PM on June 2, 2026: contributor

    Good suggestions, @optout21 and @naiyoma.

    I added both of you as co-authors and updated the related external signer documentation as well.

  9. Sjors commented at 8:47 AM on June 5, 2026: member

    Concept ACK @w0xlt if it's not to hard to find, can you add links in the description to the pull requests where the current documentation went stale?

    Note that we recently updated this documentation in #33765.

    There's quite a few changes in 60015c927920f051ac5225cd07dc65a6bec73a5e, fixes (name -> model, switching from sendtoaddress to send) as well as improvements (e.g. adding the taproot descriptor). That's fine if I have to review it only once. But if there's going to be lots of followup changes, it's easy to overlook a mistake. So it might be better to split this into multiple commits, each fixing a limited set of issues.

  10. in doc/external-signer.md:70 in 60015c9279
      66 | @@ -67,7 +67,7 @@ Replace `<address>` with the result of `getnewaddress`.
      67 |  Under the hood this uses a [PSBT (Partially Signed Bitcoin Transaction)](psbt.md).
      68 |  
      69 |  ```sh
      70 | -bitcoin-cli -rpcwallet=<walletname> sendtoaddress <address> <amount>
      71 | +bitcoin-cli -rpcwallet=<walletname> -named send outputs='{"<address>": <amount>}'
    


    Sjors commented at 8:48 AM on June 5, 2026:

    Light preference for recommending bitcoin rpc rather than bitcoin-cli -named


    w0xlt commented at 5:55 PM on June 11, 2026:

    Done. Thanks

  11. in doc/external-signer.md:87 in 60015c9279 outdated
      83 | @@ -84,14 +84,18 @@ Prerequisite knowledge:
      84 |  * [Output Descriptors](descriptors.md)
      85 |  * Partially Signed Bitcoin Transaction ([PSBT](psbt.md))
      86 |  
      87 | -### Flag `--chain <name>` (required)
    


    Sjors commented at 9:26 AM on June 5, 2026:

    Alternatively: (required except for enumerate)


    w0xlt commented at 5:55 PM on June 11, 2026:

    Done. Thanks

  12. in doc/external-signer.md:91 in 60015c9279
      88 | +### Flag `--chain <name>`
      89 |  
      90 |  With `<name>` one of `main`, `test`, `signet`, `regtest`, `testnet4`.
      91 |  
      92 | -### Flag `--stdin` (required)
      93 | +Bitcoin Core passes this flag to commands that operate on a chain-specific signer: `getdescriptors`, `displayaddress`, and `signtx`. It is not passed to `enumerate`.
    


    Sjors commented at 9:28 AM on June 5, 2026:

    I suggest using "for example" so we don't need to keep this list up to date when adding new commands.


    w0xlt commented at 5:55 PM on June 11, 2026:

    Done. Thanks

  13. in doc/external-signer.md:93 in 60015c9279
      90 |  With `<name>` one of `main`, `test`, `signet`, `regtest`, `testnet4`.
      91 |  
      92 | -### Flag `--stdin` (required)
      93 | +Bitcoin Core passes this flag to commands that operate on a chain-specific signer: `getdescriptors`, `displayaddress`, and `signtx`. It is not passed to `enumerate`.
      94 | +
      95 | +### Flag `--stdin` (required for `signtx`)
    


    Sjors commented at 9:33 AM on June 5, 2026:

    I would keep this "required". Bitcoin Core happens to only use it for signtx, but clients should support it for all commands so we can be flexible.

    For example if we ever add BIP388 support (see https://github.com/Sjors/bitcoin/pull/91) then displayaddress needs to pass in the policy and xpubs, which I'd rather do through stdin.


    w0xlt commented at 5:55 PM on June 11, 2026:

    Done. Thanks

  14. in doc/external-signer.md:97 in 60015c9279
      94 | +
      95 | +### Flag `--stdin` (required for `signtx`)
      96 |  
      97 |  Indicate that (sub)command should be received over stdin and results returned in response to that. `--stdin` is a global flag, it is not used for all subcommands.
      98 |  
      99 | +Bitcoin Core uses this flag for `signtx`.
    


    Sjors commented at 9:34 AM on June 5, 2026:

    currently uses


    w0xlt commented at 5:55 PM on June 11, 2026:

    Done. Thanks

  15. in doc/external-signer.md:110 in 60015c9279 outdated
     110 | @@ -107,11 +111,11 @@ Usage:
     111 |  
     112 |  Note: remember that shell-expansion is not available on _stdin_. Consequently, commands such as `signtx`, may write their arguments in either quoted or unquoted form.
     113 |  
     114 | -### Flag `--fingerprint <fingerprint>` (required)
    



    w0xlt commented at 5:55 PM on June 11, 2026:

    Done. Thanks

  16. in doc/external-signer.md:222 in 60015c9279
     221 |  It then imports descriptors for all supported address types, in a BIP44/49/84/86 compatible manner.
     222 |  
     223 | -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>`.
     224 | -
     225 | -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` to involve an external signer.
     226 | +The `walletdisplayaddress` RPC reuses some code from `getaddressinfo` on the provided address and obtains the inferred descriptor. It then calls `<cmd> --chain <name> --fingerprint=00000000 displayaddress --desc=<descriptor>`.
    


    Sjors commented at 9:36 AM on June 5, 2026:

    Might as well drop the implementation detail "reuses some code" if you're touching this.


    w0xlt commented at 5:56 PM on June 11, 2026:

    Done. Thanks

  17. doc, rpc: document enumerate model field and fingerprint deduplication
    The external signer "enumerate" response uses the optional "model"
    field, not "name". Document that Bitcoin Core maps it to the "name"
    field of the enumeratesigners RPC result, and that signers with
    duplicate master key fingerprints are skipped.
    
    Also document that wallet operations require exactly one connected
    signer.
    
    Co-authored-by: optout <13562139+optout21@users.noreply.github.com>
    Co-authored-by: naiyoma <lankas.aurelia@gmail.com>
    fab92257fe
  18. doc: replace stale signtransaction wording with current signtx flow
    The protocol documentation still described a "signtransaction" command
    driven by sendtoaddress and sendmany. Those RPCs never gained external
    signer support: it was effectively precluded by #21201, which was
    merged a few days before external signer support landed in #16546, so
    the interaction was missed in review (#33112 has a commit making the
    rejection explicit). Spending from an external signer wallet uses
    send/sendall (and bumpfee for fee-bumping), which invoke the signer
    with `<cmd> --stdin` and pass the `signtx` subcommand and PSBT over
    stdin.
    
    Update the spending example and the protocol description accordingly,
    using `bitcoin rpc` for the example since it enables -named by default.
    4fdd4d8d29
  19. doc: clarify which commands receive --chain, --fingerprint and --stdin
    Bitcoin Core passes --chain and --fingerprint to every signer command
    except enumerate, so mark them "(required except for enumerate)" and
    name the current commands only as examples. Keep --stdin documented as
    required for all commands so the interface stays flexible, noting that
    Bitcoin Core currently only uses it for signtx.
    
    Add the missing flags to the getdescriptors and displayaddress usage
    examples and the corresponding doxygen comments, matching the order and
    form of the actual invocations, add testnet4 to the chain name lists,
    and drop the getaddressinfo implementation detail from the
    walletdisplayaddress description.
    7131c82937
  20. doc: add taproot descriptor to getdescriptors example
    Wallets import descriptors for all supported address types in a
    BIP44/49/84/86 compatible manner, so show the BIP86 tr() descriptor in
    the example response as well.
    bd5a32f7db
  21. wallet: reject sendtoaddress and sendmany for external signers
    The sendtoaddress and sendmany RPCs always go through SendMoney(), which
    expects to sign internally. External signer wallets should use the PSBT
    flow instead, via the send RPC.
    
    Return a more specific error for external signer wallets and add
    functional test coverage for both RPCs.
    2fe34808fa
  22. in doc/external-signer.md:224 in 60015c9279
     224 | -
     225 | -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` to involve an external signer.
     226 | +The `walletdisplayaddress` RPC reuses some code from `getaddressinfo` on the provided address and obtains the inferred descriptor. It then calls `<cmd> --chain <name> --fingerprint=00000000 displayaddress --desc=<descriptor>`.
     227 |  
     228 | -`sendtoaddress` and `sendmany` check `inputs->bip32_derivs` to see if any inputs have the same `master_fingerprint` as the signer. If so, it calls `<cmd> --fingerprint=00000000 signtransaction <psbt>`. It waits for the device to return a (partially) signed psbt, tries to finalize it and broadcasts the transaction.
     229 | +For 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.
    


    Sjors commented at 9:48 AM on June 5, 2026:

    It’s good to mention in the PR / commit description that sendtoaddress and sendmany external signer support was effectively precluded by #21201, which was merged before external signer support landed in #16546. The PRs landed only a few days apart, so the interaction was probably missed in review.

    #33112 has a commit, wallet: reject sendtoaddress and sendmany for external signers, that makes this behavior explicit.


    Sjors commented at 9:59 AM on June 5, 2026:

    Maybe cherry-pick a5eb9e13f258c001b3096a61cd6420830cd63bc2 here, I tried that the test passes without the rest of #33112.


    Sjors commented at 10:15 AM on June 5, 2026:

    We never had test coverage for external signer behavior with sendtoaddress and sendmany. Personally I only use send and the GUI. That partially explains how this omission went unnoticed for so long.


    w0xlt commented at 5:56 PM on June 11, 2026:

    Done. Cherry-picked a5eb9e1 here (last commit). Thanks.

  23. w0xlt force-pushed on Jun 11, 2026
  24. w0xlt renamed this:
    doc: align external signer protocol documentation
    doc, wallet: align external signer documentation, reject sendtoaddress/sendmany
    on Jun 11, 2026
  25. w0xlt commented at 5:58 PM on June 11, 2026: contributor

    As suggested in #35424 (comment), split into 5 commits separating the enumerate fixes, signtx flow, flag clarifications, and the taproot example.

    PR description now links the PRs where the docs went stale.

  26. Sjors commented at 3:48 PM on June 16, 2026: member

    ACK 2fe34808faaac41cca228b8795539b567908ad51

    You're welcome, but it's better not to tag usernames in the PR description because it will trigger many notifications as others projects pull it in :-)

  27. DrahtBot requested review from naiyoma on Jun 16, 2026
  28. optout21 commented at 4:22 PM on June 16, 2026: contributor

    ACK 2fe34808faaac41cca228b8795539b567908ad51


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: 2026-06-21 02:51 UTC

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