Skip to content

Deprecate wallet-owned signing APIs - #505

Open
noahjoeris wants to merge 3 commits into
bitcoindevkit:release/3.xfrom
noahjoeris:feat/sign-psbt-migration
Open

Deprecate wallet-owned signing APIs#505
noahjoeris wants to merge 3 commits into
bitcoindevkit:release/3.xfrom
noahjoeris:feat/sign-psbt-migration

Conversation

@noahjoeris

@noahjoeris noahjoeris commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Description

Partially addresses #70

Deprecates wallet-owned signing APIs, migrating examples, tests, and documentation toward caller-owned keys using bitcoin::Psbt::sign and Wallet::sign_with_signers.

Depends on:

Notes to the reviewers

  • I migrated examples, docs and tests to use bitcoin::Psbt::sign where possible. And used Wallet::sign_with_signers if we need SignOptions.

Changelog notice

  • Deprecated Wallet::{add_signer, set_keymap, set_keymaps, get_signers, sign, policies}, CreateParams::keymap, and LoadParams::{keymap, extract_keys} in favor of caller-owned keys and bitcoin::Psbt::sign and Wallet::sign_with_signers.
  • Deprecated FullyNodedExport::export_wallet; use FullyNodedExport::export_wallet_with_keymaps to supply keymaps explicitly.
  • Added TxBuilder::set_condition as replacement for TxBuilder::policy_path.

Before submitting

@codecov

codecov Bot commented Jun 23, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 89.18919% with 8 lines in your changes missing coverage. Please review.
✅ Project coverage is 81.90%. Comparing base (0416409) to head (469d16c).

Files with missing lines Patch % Lines
src/wallet/mod.rs 84.61% 7 Missing and 1 partial ⚠️
Additional details and impacted files
@@               Coverage Diff               @@
##           release/3.x     #505      +/-   ##
===============================================
+ Coverage        81.77%   81.90%   +0.12%     
===============================================
  Files               25       25              
  Lines             6487     6499      +12     
  Branches           296      296              
===============================================
+ Hits              5305     5323      +18     
+ Misses            1080     1071       -9     
- Partials           102      105       +3     
Flag Coverage Δ
rust 81.90% <89.18%> (+0.12%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@noahjoeris noahjoeris changed the title refactor: deprecate wallet-owned signing APIs Deprecate wallet-owned signing APIs Jun 23, 2026
@oleonardolima oleonardolima added this to the Wallet 3.2.0 milestone Jun 23, 2026
@oleonardolima oleonardolima moved this to In Progress in BDK Wallet Jun 23, 2026
@noahjoeris
noahjoeris force-pushed the feat/sign-psbt-migration branch 3 times, most recently from 44a49b6 to 769b782 Compare June 25, 2026 13:24
@thunderbiscuit thunderbiscuit mentioned this pull request Jun 26, 2026
4 tasks
@noahjoeris
noahjoeris force-pushed the feat/sign-psbt-migration branch from 769b782 to 8857be6 Compare June 26, 2026 11:20

@oleonardolima oleonardolima left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

overall it's looking good, it's best if you fix the first commit and let the last one just adding the deprecation notice. let's us know when it's ready for final review.

Comment thread examples/electrum.rs Outdated
Comment thread tests/psbt.rs Outdated
@noahjoeris
noahjoeris force-pushed the feat/sign-psbt-migration branch from 8857be6 to c810938 Compare July 1, 2026 08:17
@noahjoeris

Copy link
Copy Markdown
Contributor Author

Thanks for spotting this. It seems I added the change to the last commit and not the first, my bad. I cleaned up the commits.

@oleonardolima oleonardolima left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK c810938

@noahjoeris

noahjoeris commented Jul 5, 2026

Copy link
Copy Markdown
Contributor Author

I still need to look into Wallet::policies and Wallet::create_tx and what to do with them. They also use self.signers

@noahjoeris

Copy link
Copy Markdown
Contributor Author

For Wallet::policies(), I suggest deprecating it and adding something like Wallet::policies_with_signers(keychain, signers).

One tricky part is TxBuilder::finish() -> Wallet::create_tx(). It currently extracts policies with the wallet signers.

A possible migration path is adding TxBuilder::policy(policy, keychain). Then callers that use policies_with_signers(...) can pass the resulting policy into the builder. Existing callers can keep the current fallback behavior of using wallet-owned signers during the deprecation window.

Downside: policy-path users get one more builder call, and Policy becomes more directly part of the API. Maybe that's acceptable with our intention of slowly moving away from TxBuilder.

@vera945

vera945 commented Jul 7, 2026

Copy link
Copy Markdown

Neither policies nor create_tx needs deprecation. Here's the reasoning:

create_tx calls extract_policy only to invoke requires_path() and get_condition(). Both methods operate entirely on the descriptor's structural tree — SatisfiableItem — and never read the contribution field, which is the only output that depends on the signers container. So passing SignersContainer::default() is valid without changing the behavior. This is verifiable by creating a wallet from xpub descriptors and calling build_tx normally.

policies similarly behaves this way for watch-only wallets. The contribution field will be Satisfaction::None for all leaves, which correctly describes a wallet that holds no signing keys. If a caller wants to evaluate what their external signing keys can contribute, the right answer is wallet.public_descriptor(keychain).extract_policy(their_signers, ...), which is already the pattern #505 is establishing.

@noahjoeris

Copy link
Copy Markdown
Contributor Author

No, passing empty signers won't work. It can create different Policy IDs, and policy_path relies on those IDs.

A path built from Wallet::policies() can fail when create_tx() re-extracts with empty signers, because get_condition() looks up selections by self.id.

@noahjoeris

noahjoeris commented Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

So after some discussion with @thunderbiscuit and @notmandatory we concluded that we cannot remove the signers fields unless we update TxBuilder to accept a spending policy to be passed in. If we don't want to update it (from what I heard) then the wallet signer removal is coupled to the TxBuilder removal. And it might make sense to deprecate both at the same time once we integrated create_psbt.

Comment thread examples/electrum.rs
@ValuedMammal

Copy link
Copy Markdown
Collaborator

So after some discussion with @thunderbiscuit and @notmandatory we concluded that we cannot remove the signers fields unless we update TxBuilder to accept a spending policy to be passed in. If we don't want to update it (from what I heard) then the wallet signer removal is coupled to the TxBuilder removal. And it might make sense to deprecate both at the same time once we integrated create_psbt.

That sounds extreme. The whole policy path ceremony in create_tx exists to come up with the "requirements" which is just a Condition struct with two optional fields, so what you could do is deprecate TxBuilder::policy_path and provide a set_condition method to pass the Condition directly and that will forever decouple the policy from TxBuilder. policy_path is broken anyway because of the unstable policy id as you mention (#123).

@ValuedMammal
ValuedMammal changed the base branch from master to release/3.x July 27, 2026 14:57
@noahjoeris
noahjoeris force-pushed the feat/sign-psbt-migration branch from c810938 to 9a9b2ca Compare July 27, 2026 15:43
@noahjoeris
noahjoeris requested a review from oleonardolima July 27, 2026 15:58
@noahjoeris
noahjoeris marked this pull request as ready for review July 27, 2026 16:00
@noahjoeris
noahjoeris requested a review from ValuedMammal as a code owner July 27, 2026 16:00
Comment thread src/wallet/export.rs Outdated
Comment thread src/wallet/export.rs
Prefer bitcoin::Psbt::sign or Wallet::sign_with_signers in docs,
examples, and tests instead of relying on wallet-owned signer state.

Add FullyNodedExport::export_wallet_with_keymap for explicitly supplied
private descriptor material, while keeping export_wallet public-only and
independent of wallet-owned signer state.
Add TxBuilder::set_condition and wire create_tx to prefer an explicit
Condition, falling back to policy-path derivation. Export Condition /
Condition::merge. Migrate the compiler example off Wallet::policies.
Mark Wallet::sign, signer/keymap accessors, keymap load/create helpers,
Wallet::policies, and TxBuilder::policy_path as deprecated.

Replacement: keep KeyMaps/Xprivs outside Wallet; bitcoin::Psbt::sign or
Wallet::sign_with_signers; extract_policy + Policy::get_condition +
TxBuilder::set_condition for spending paths.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

5 participants