Contrib: add multisig wizard #36325

pull rxbryan wants to merge 5 commits into bitcoin:master from rxbryan:contrib_multisig changing 4 files +710 −0
  1. rxbryan commented at 12:21 PM on September 24, 2026: none

    Per the discussion in #35645, this PR adds a Python utility that performs the multisig setup process, so that RPC and interface work is shaped by what that flow actually needs.

    It covers wallet creation, key generation at the BIP 87 path, collecting cosigner keys, assembling a wsh(sortedmulti()) or tr(musig(),sortedmulti_a()) descriptor, verifying it, and importing it.

    Gaps that need new functionality in C++

    • importdescriptors rejects a descriptor with no private keys when the wallet has private keys enabled. See #35377.
    • The wallet stores a multipath descriptor as two descriptors, so listdescriptors never shows the descriptor that was shared. See #36133.
    • The wallet labels addresses, not keys, so cosigner names live in the setup and are lost on import.
    • There is no RPC for validating a key expression, so the key is wrapped in pkh() for getdescriptorinfo to parse. See #35918, which exposes ParsePubkey().
    • createmultisig only takes plain public keys, not extended keys with origins, and cannot build a ranged or taproot multisig descriptor.
    • Nothing reports what a descriptor commits to, or whether this wallet holds one of its keys, before it is imported.

    Part of #35645.

  2. DrahtBot added the label Scripts and tools on Sep 24, 2026
  3. DrahtBot commented at 12:21 PM on September 24, 2026: contributor

    <!--e57a25ab6845829454e8d69fc972939a-->

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

    <!--006a51241073e994b41acfe9ec718e94-->

    External sites

    <!--021abf342d371248e50ceaed478a90ca-->

    Reviews

    See the guideline and AI policy for information on the review process.

    Type Reviewers
    Concept ACK BenWestgate

    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.

    <!--174a7506f384e20aa4161008e828411d-->

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #29247 <sub><img src="https://drahtbot.space/ack_count/bitcoin/bitcoin/29247.svg"></sub> (CAT in Tapscript (BIP-347) by arminsabouri)

    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.

    <!--5faf32d7da4f0f540f40219e4f7537a3-->

  4. rxbryan force-pushed on Sep 24, 2026
  5. rxbryan marked this as ready for review on Sep 24, 2026
  6. rxbryan force-pushed on Sep 24, 2026
  7. contrib: add multisig wizard
    Following the discussion on #36143, this commit adds a python
    utility implementing the multisig setup flow tracked in #35645
    using available RPCs and implements work arounds for missing RPC
    or wallet features.
    
    Adds wallet creation and key generation step.
    
    The wallet cannot store a name for a key, so cosigner names live
    in the setup and are lost on import.
    6feb6063bd
  8. contrib: validate cosigner key expressions
    Check a key expression before recording it, and reject private keys,
    derivation paths, multipath derivations, keys without origin information
    and duplicates.
    
    The wizard also requires the BIP 87 path, which the descriptor layer does
    not.
    6cfa28e1c8
  9. contrib: assemble wsh and taproot multisig descriptors
    Builds the ranged, multipath descriptor from the collected keys and
    a call to getdescriptorinfo checks the resulting descriptor and
    supplys the checksum.
    
    For taproot the key path is a MuSig2 aggregate of all n keys
    rather than a fixed or variable NUMS point: it cannot bypass the
    policy, since spending that way needs every signer, and it avoids
    the fingerprinting using a well-known internal key would cause.
    154fd8922f
  10. contrib: analyze and verify a multisig descriptor
    analyze_descriptor reports what the descriptor requires to spend.
    Which cosigner we are, and the first receive address,
    
    Accepted shapes are wsh(sortedmulti(...)) and, for taproot,
    tr(KEY,sortedmulti_a(...)) where KEY is either musig() of exactly
    the keys in the leaf, so that spending by key path needs
    every cosigner, or the NUMS point, which is provably unspendable.
    Anything else is rejected.
    
    Names are local, so any cosigner we have no name for is reported
    by fingerprint.
    039db5c3e3
  11. contrib: add import multisig descriptor step
    During the import process, the participant swaps their own key
    expression in the descriptor for the private one since
    importdescriptors reject a descriptor with no private keys when
    the wallet has private keys enabled. See #35377
    2803e1518b
  12. rxbryan force-pushed on Sep 25, 2026
  13. sedited commented at 7:43 AM on September 25, 2026: contributor

    Do we need this in the repository? Seems fine to me if it were just an external script.

  14. rxbryan commented at 8:33 AM on September 26, 2026: none

    Aside from being a demonstration of the multisig setup flow, the utility is intended to become a command-line equivalent of the GUI wizard that ships with Core so users can set up multisig without hand-assembling descriptors. The workarounds in it will eventually be superseded as functionality is moved to C++.

    Whether that belongs in the repo is worth settling first.

  15. DrahtBot added the label CI failed on Sep 26, 2026
  16. DrahtBot removed the label CI failed on Sep 26, 2026
  17. in contrib/multisig/README.md:6 in 2803e1518b
       0 | @@ -0,0 +1,11 @@
       1 | +# Multisig Setup Wizard
       2 | +
       3 | +Guides an orchestrator/participant through setting up a k-of-n multisig descriptor wallet.
       4 | +
       5 | +This utility implements the multisig setup flow tracked in #35645 using available
       6 | +RPCs and implements workarounds for missing RPC or wallet feature.
    


    BenWestgate commented at 11:44 PM on September 29, 2026:
    RPCs and implements workarounds for missing RPC or wallet features.
    
  18. in contrib/multisig/README.md:11 in 2803e1518b
       6 | +RPCs and implements workarounds for missing RPC or wallet feature.
       7 | +
       8 | +*configurations*
       9 | +`rpc` is a wallet rpc handle.
      10 | +All steps require an unlocked wallet with private keys enabled.
      11 | +A coordinator that does not contribute keys needs a watch-only wallet
    


    BenWestgate commented at 11:45 PM on September 29, 2026:
    A coordinator that does not contribute keys needs a watch-only wallet.
    
  19. BenWestgate commented at 12:18 AM on September 30, 2026: contributor

    cACK, only cursory code review of wizard.py but the interface and usage looks correct.

    As for @sedited wondering if we need this in the repository: For years, Core having user unfriendly multisig has been exploited by scammers to promote alternative multisig wallets with substantially less scrutiny than this repository.

  20. kevkevinpal commented at 5:00 PM on October 3, 2026: contributor

    I'm not sure we want this in this repository.

    Looking at the other scripts in contrib I don't see any that handle wallet utilities. If this were to be added it would make more sense to add it to the Bitcoin Core wallet.

    From what I understand in the discussion in #35645, this would not be used, as once the work in the GUI and wallet has finished, that would be preferred. The script is still valuable, but we might not want it with the contrib scripts.

    Core offline signing and multisig being non-technologist unfriendly has been exploited by scammers to push alternative multisig and airgap wallets with substantially less review than this repository.

    I don't think the goal of Bitcoin Core is to be "non-technologist" friendly, and also adding a new script to the repo does not guarantee that it will be maintained. It is just another piece of code the Bitcoin Core maintainers will need to worry about forever.


    To me, it makes the most sense to keep this change on your own fork and share it with the group in the thread so they can still use it without merging it into this repo, where it will need to be maintained

  21. BenWestgate commented at 12:12 AM on October 5, 2026: contributor

    maintainers will need to worry about forever. @rxbryan are you willing to maintain this script (including bug fixing) until the RPC obsoletes it?

    If this were to be added it would make more sense to add it to the Bitcoin Core wallet. @Sjors said in #36143 (comment) a wallet c++ implementation is premature and he preferred to: 1.introduce a Python utility that helps the user construct and import a multisig descriptor 2. gradually improve / add RPC methods to simplify that utility and eventually make it unnecessary

    The script serves as a functional to-do checklist for multisig, with its workarounds deleted as wallet PRs land.

    The advantage of merging it into this repo is better scrutiny and CI against bugs for adventurous users who'd like to use it on mainnet.

  22. rxbryan commented at 9:08 PM on October 5, 2026: none

    maintainers will need to worry about forever.

    @rxbryan are you willing to maintain this script (including bug fixing) until the RPC obsoletes it?

    Yes. I'll maintain it, we have enough test cases to force a maintenance contract on whoever modifies code touching it.


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-10-14 19:51 UTC

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