Skip to content

3.0#971

Open
reez wants to merge 10 commits intobitcoindevkit:masterfrom
reez:rc1
Open

3.0#971
reez wants to merge 10 commits intobitcoindevkit:masterfrom
reez:rc1

Conversation

@reez
Copy link
Copy Markdown
Collaborator

@reez reez commented Mar 11, 2026

Description

Exposing 3.0 items.

Notes to the reviewers

Documentation

Checklists

All Submissions:

  • I've signed all my commits
  • I followed the contribution guidelines
  • I ran cargo fmt and cargo clippy before committing
  • I've added a changelog in the next release tracking issue (see example)
  • I've linked the relevant upstream docs or specs above

New Features:

  • I've added tests for the new feature
  • I've added docs for the new feature

Bugfixes:

  • This pull request breaks the existing API
  • I've added tests to reproduce the issue which are now passing
  • I'm linking the issue being fixed by this PR

@reez reez changed the title (DRAFT) Rc1 (DRAFT) 3.0 Rc1 Mar 11, 2026
@thunderbiscuit
Copy link
Copy Markdown
Member

🚀 🚀 🚀 🚀 🚀

@reez
Copy link
Copy Markdown
Collaborator Author

reez commented Mar 17, 2026

bitcoindevkit/bdk-kyoto#155 I opened this Draft PR (and a related issue)

Just using my fork of bdk-kyoto with the change rn

@reez reez changed the title (DRAFT) 3.0 Rc1 (DRAFT) 3.0 RC's Mar 27, 2026
@reez reez linked an issue Mar 30, 2026 that may be closed by this pull request
@reez
Copy link
Copy Markdown
Collaborator Author

reez commented Apr 13, 2026

updated to official 3.0

@rustaceanrob
Copy link
Copy Markdown
Collaborator

bdk_kyoto = 0.16.0 is out and includes the 3.0.0 release

@reez
Copy link
Copy Markdown
Collaborator Author

reez commented Apr 14, 2026

bdk_kyoto = 0.16.0 is out and includes the 3.0.0 release

thanks I updated to 0.16.0 and made one small change update_rx: Mutex<UpdateSubscriber<bdk_kyoto::wallets::Single>> necessary along with it in 27be17f

@reez reez changed the title (DRAFT) 3.0 RC's (DRAFT) 3.0 Apr 14, 2026
Copy link
Copy Markdown
Member

@thunderbiscuit thunderbiscuit left a comment

Choose a reason for hiding this comment

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

I compiled and ran Rust tests locally today. Just started looking at this and left a few comments. I haven't gone through all files yet (tx_builder, types, wallet left to do). I'll try and migrate the Android app to this potential alpha to see how the migration goes! Looks like it should be pretty smooth.

Comment thread bdk-ffi/Cargo.toml Outdated
[package]
name = "bdk-ffi"
version = "2.4.0-alpha.0"
version = "3.0.0"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This one here I think should read 3.0.0-alpha.0 since this would merge on master.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Ahhh, I guess I did no -alpha just because in my head I was thinking we only bumped to -alpha after the release work was merged to master and the release was cut, but I might have been remembering that wrong.

No strong opinion from me, just wanted to double check w ya, but im good with whatever you comment back on this for me to change it to.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

(go w thunders suggestion here)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

updated w commit 061266b

Comment thread bdk-ffi/src/descriptor.rs
let secp = Secp256k1::new();
let (extended_descriptor, key_map) = descriptor.into_wallet_descriptor(&secp, network)?;
let (extended_descriptor, key_map) =
descriptor.into_wallet_descriptor(&secp, network.into())?;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I still need to get to grips with the NetworkKind type. Are there situations where we'd like to use that instead of the Network for example? Not sure.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I don’t have any concrete ffi facing cases that come to mind, since NetworkKind only has Main and Test... I’ve been thinking of it as mostly an internal/upstream type for apis that only care about that distinction, where bdk-ffi consumers would usually want the full Network to preserve the actual chain. But I need to keep thinking about it more too so im glad you commented on it here

Comment thread bdk-ffi/src/store.rs
#[derive(Debug, Clone, uniffi::Record)]
pub struct PreV1WalletKeychain {
/// The wallet keychain.
pub keychain: bdk_wallet::KeychainKind,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can we use our own KeychainKind from the types module here? I think they're functionally equivalent because it's using remote enums in uniffi, but could still be a tiny cleanup unless I am missing something.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I think the small uniffi wrinkle i found here was crate::types::KeychainKind isn’t currently usable from this module because the backing alias in types.rs is private so switching this line wasn't a easy one line cleanup, and since the rest of the code was also using bdk_wallet::KeychainKind directly I decided to leave it as is in this PR.

But its definitely something we could do, it just seemed like it might end up needing to be a separate/bigger refactor

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ok this is so confusing to me 😆😆😆.

You're right most of the codebase uses the Rust type directly! But it's also... a trick!? I was confused by this ability to just use the Rust enum without any other fanfare (maybe a new feature from 0.30 I didn't know about?), especially that when you look at the generated bindings Kotlin code, the enum used in types.rs is the same enum used in say descriptors.rs, when in fact looking at the code those are two completely different types (one is custom made by us, one is the bdk_wallet library's type).

And so I was like "ok let's just cut it completely then!", but if you try to do that (remove the KeychainKind from types.rs), you actually get errors at the uniffi level, saying that KeychainKind is undefined. But wait it's just using the one from bdk_wallet... mmmmm

So it turns out that it doesn't. All files rely on our KeychainKind in types.rs, and I think this is related to how the visibility modifiers in Rust are disregarded by uniffi. You're correct it's not public, and yet the sort of type alias or whatever is used wherever you use KeychainKind.

I was able to clean this up and reconcile this is by simply making the type public and cleaning up the misleading imports in files that use the type. You're right it's sort of a sidequest, so I'll open a separate PR for it.

Comment thread bdk-ffi/src/store.rs
}

/// Retrieve keychain metadata from a pre-v1 BDK SQLite wallet database.
pub fn get_pre_v1_wallet_keychains(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'd love to see a test for this one in the Android or Swift parts of the codebase if possible.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Yeah, that makes sense. I looked around the code and I think we already have Swift/Android persistence tests but I don’t think we had a pre-v1 SQLite database in the repo, so adding a bindings test for this I think would have meant adding that first. And then also I wasn't totally sure if we were going to expose this in 3.0 or not.

But im with you on if we do want to expose this for sure in our ffi 3.0 (or whenever we expose it in a release) that it would be quite nice to have a test for this, and prob worth putting in time to figure out how to test it well

Comment thread bdk-ffi/src/store.rs

/// Metadata describing a keychain in a pre-v1 BDK SQLite wallet database.
#[derive(Debug, Clone, uniffi::Record)]
pub struct PreV1WalletKeychain {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I was looking at the Rust code for this type and I see that the API docs have changed since you added it I think. See here.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

this is deep in the weeds, I love it, good catch!

updated in 6cca30e

@reez reez changed the title (DRAFT) 3.0 3.0 Apr 20, 2026
@reez reez marked this pull request as ready for review April 20, 2026 17:19
@reez
Copy link
Copy Markdown
Collaborator Author

reez commented Apr 20, 2026

@thunderbiscuit I rebased onto current master and dropped commits superseded by #978

@reez reez force-pushed the rc1 branch 2 times, most recently from 4e416f7 to 0fd82f2 Compare April 23, 2026 15:50
@reez
Copy link
Copy Markdown
Collaborator Author

reez commented Apr 23, 2026

rebased

Comment thread bdk-ffi/src/tests/tx_builder.rs Outdated

if utxos.is_empty() {
println!("No UTXOs available, skipping sighash PSBT assertion");
return;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nice addition covering the new sighash API.

One small test concern: this can pass without actually exercising the new behavior if the synced wallet has no UTXOs, because the test returns before checking input.sighash_type.

Would it be better to make the funded-wallet precondition explicit, or structure this so the test cannot silently skip the PSBT assertion?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

yeah, updated the test now

@reez
Copy link
Copy Markdown
Collaborator Author

reez commented Apr 29, 2026

rebased again

Copy link
Copy Markdown
Member

@thunderbiscuit thunderbiscuit left a comment

Choose a reason for hiding this comment

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

Still working through it but here are some thoughts!

Comment thread bdk-ffi/src/wallet.rs
///
/// [`apply_unconfirmed_txs`]: Self::apply_unconfirmed_txs
/// [`apply_update_events`]: Self::apply_update_events
pub fn apply_unconfirmed_txs_events(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'm looking at this and the sister method apply_unconfirmed_txs(), and I'm wondering: how would you come across an UnconfirmedTx? We only use them as inputs to these two methods, and so someone would need to create one to them apply it? Wondering what the workflow is

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I think this one is mostly for custom mempool/backend flows, not really the normal esplora/electrum sync -> apply_update path. (UnconfirmedTx is basically just the ffi version of upstream’s (tx, last_seen) tuple.) So the workflow in my mind would be something like: your app/backend sees a raw mempool tx, parses it into a Transaction, pairs it with the unix timestamp for when it saw it, and passes that in here.

Comment thread bdk-ffi/src/store.rs
/// Retrieve keychain metadata from a pre-v1 BDK SQLite wallet database.
pub fn get_pre_v1_wallet_keychains(
&self,
) -> Result<Vec<PreV1WalletKeychain>, PreV1MigrationError> {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The method is on the Persister type, but in the Rust library it's just a standalone function. I'm wondering if there is an advantage to this approach of making it into a associated fuction or some other reason you had in mind.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

yeah I was thinking of Persister as the FFI stand in for the rusqlite::Connection here. Since upstream takes &mut Connection (and bdk-ffi hides that behind Persister) putting it there let callers run the migration helper against the same sqlite persister they already use for loading/persisting.

BUT I see the downside that it shows up on custom persisters too and then needs the SqliteOnly error. I don’t feel super strongly about it. What ideas are you thiniking about that are better, im def open to them

Comment thread bdk-ffi/src/store.rs
#[derive(Debug, Clone, uniffi::Record)]
pub struct PreV1WalletKeychain {
/// The wallet keychain.
pub keychain: bdk_wallet::KeychainKind,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ok this is so confusing to me 😆😆😆.

You're right most of the codebase uses the Rust type directly! But it's also... a trick!? I was confused by this ability to just use the Rust enum without any other fanfare (maybe a new feature from 0.30 I didn't know about?), especially that when you look at the generated bindings Kotlin code, the enum used in types.rs is the same enum used in say descriptors.rs, when in fact looking at the code those are two completely different types (one is custom made by us, one is the bdk_wallet library's type).

And so I was like "ok let's just cut it completely then!", but if you try to do that (remove the KeychainKind from types.rs), you actually get errors at the uniffi level, saying that KeychainKind is undefined. But wait it's just using the one from bdk_wallet... mmmmm

So it turns out that it doesn't. All files rely on our KeychainKind in types.rs, and I think this is related to how the visibility modifiers in Rust are disregarded by uniffi. You're correct it's not public, and yet the sort of type alias or whatever is used wherever you use KeychainKind.

I was able to clean this up and reconcile this is by simply making the type public and cleaning up the misleading imports in files that use the type. You're right it's sort of a sidequest, so I'll open a separate PR for it.

@reez
Copy link
Copy Markdown
Collaborator Author

reez commented Apr 29, 2026

#971 (comment)

@thunderbiscuit

Yeah agree, ack'd it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

bdk_wallet 3.0

4 participants