From: thunderbiscuit Date: Fri, 25 Sep 2026 18:07:07 +0000 (-0400) Subject: docs: migrate blog posts to true blog feature in zensical X-Git-Url: http://internal-gitweb-vhost/-script/src/blockdata/script/bitcoin/amount/struct.SignedAmount.html?a=commitdiff_plain;p=bitcoindevkit.org docs: migrate blog posts to true blog feature in zensical --- diff --git a/docs/blog/2023_q4_update.md b/docs/blog/2023_q4_update.md deleted file mode 100644 index 09e1f1a60b..0000000000 --- a/docs/blog/2023_q4_update.md +++ /dev/null @@ -1,57 +0,0 @@ -# 2023 Q4 Project Update - -:lucide-pen-tool:   [`Steve Myers`](https://github.com/notmandatory)   [`Daniela Brozzoni`](https://github.com/danielabrozzoni) -:lucide-calendar-1:   `Feb 20, 2024` ---- - -The [Spiral](https://spiral.xyz) team has graciously supported BDK financially (and spiritually) for the past four years and since early 2022 the BDK team has let folks know what we've been up to via the [Spiral blog](https://spiral.xyz/blog/). As of last summer we are grateful to also have received a generous [OpenSats grant](https://opensats.org/blog/bitcoin-and-nostr-grants-august-2023) supporting our project. To keep our current and future financial supporters, open source contributors, and downstream users updated on our progress, starting this year we will be publishing a quarterly BDK project updates here on our blog. - -### End of Year Review - -The BDK project is made up of a core suite of [rust](https://www.rust-lang.org/) libraries ([bdk-*](https://github.com/bitcoindevkit/bdk?tab=readme-ov-file#architecture)) that work together to provide everything an application developer needs to incorporate on-chain bitcoin wallet functionality into their project. Wrapped around the BDK core libraries is our [bdk-ffi](https://github.com/bitcoindevkit/bdk-ffi) bindings libraries that let Kotlin (desktop/android), Swift (desktop/iOS), and Python developers use BDK seamlessly in their projects. And wrapped around all of this software is documentation and examples. For over a year the BDK team has been working on a major re-architecture of the BDK libraries to improve blockchain syncing, embedded device support ([no-std](https://docs.rust-embedded.org/book/intro/no-std.html)), update key dependencies ([rust-bitcoin](https://github.com/rust-bitcoin/rust-bitcoin), [rust-miniscript](https://github.com/rust-bitcoin/rust-miniscript)) and finally to provide a stable 1.0 API that our users can rely on for their production applications. - -The team is currently working on the 1.0.0-alpha release train. The purposed of these alpha releases is to give early adopters (including our own `bdk-ffi` contributors) a chance to try-out new BDK features and updated APIs and provide feedback. Once we have a stable, feature complete 1.0.0 BDK that our alpha users love we'll begin publishing 1.0.0-beta releases. With our beta releases we will finish updating tutorials and examples and performance testing, and ask all BDK users to start migrating and testing their applications with BDK 1.0.0. When our key contributors and users are satisfied that we have shaken out any final 1.0.0-beta issues we'll publish our BDK 1.0.0 release. Once 1.0.0 is out subsequent releases will use [semantic versioning](https://semver.org/). - -For those keeping score, we'd originally planned to have the BDK 1.0.0 release out last year, but (spoiler) that didn't happen. As I'm sure our kind readers understand making safe, feature rich, easy to use bitcoin software isn't easy, reviewing it is even harder, and we, like every project in the space are short-handed. But with every release, as we build the software we also on-board new contributors and build the team that will deliver BDK 1.0.0, 1.1.0, 2.0.0, and beyond. - -### Core BDK - -For Q4 2023 we [merged 33 PRs](https://github.com/bitcoindevkit/bdk/pulls?page=1&q=is%3Apr+merged%3A2023-10-01..2023-12-31), [closed 32 issues](https://github.com/bitcoindevkit/bdk/issues?q=is%3Aissue+closed%3A2023-10-01..2023-12-31), and completed two 1.0.0-alpha releases, [1.0.0-alpha.2](https://github.com/bitcoindevkit/bdk/releases/tag/v1.0.0-alpha.2) and [1.0.0-alpha.3](https://github.com/bitcoindevkit/bdk/releases/tag/v1.0.0-alpha.3). The primary deliverable of these releases was to further stabilize the `bdk_chain` crate which provides the central logic for tracking and updating wallet keychains and scripts to be tracked and manages all of the related blockchain and transaction data. Additional PRs started this quarter lay the groundwork for the next phase of development focused on improving how we sync data via blockchain clients and save that data to persistent storage. We also made one maintenance release [0.29.0](https://github.com/bitcoindevkit/bdk/releases/tag/v0.29.0) that upgraded our `rust-bitcoin` dependency to release to 0.30. - -### BDK-FFI - -In Q4 the BDK-FFI bindings for Kotlin, Swift, and Python saw [23 PRs merged](https://github.com/bitcoindevkit/bdk-ffi/pulls?page=1&q=is%3Apr+merged%3A2023-10-01..2023-12-31) and [15 issues closed](https://github.com/bitcoindevkit/bdk-ffi/issues?q=is%3Aissue+closed%3A2023-10-01..2023-12-31). One maintenance release was completed, [v0.31.0](https://github.com/bitcoindevkit/bdk-ffi/releases/tag/v0.31.0), which updated the language bindings dependency to the latest rust `bdk` maintenance release 0.29.0 and in doing so updated the BDK FFI `rust-bitcoin` dependency to version 0.30. This quarter the team took on the major task of creating the first language bindings based on the `bdk` 1.0.0-alpha API. The resulting `bdk-ffi` [v1.0.0-alpha2a](https://github.com/bitcoindevkit/bdk-ffi/releases/tag/v1.0.0-alpha.2a) release is only able to expose part of the full `bdk` 1.0.0 API but prepares the project for full support in future releases. As part of this work the current Kotlin API docs were removed, but fear not they will return in future alpha releases and be better than ever with not only API docs for Kotlin but also Swift and Python. - -### BDK contributors spotlight - -In this section we share what some of our hardworking contributors are doing to educate people about BDK, help on board new projects, and generally promote bitcoin and open source development around the world. - -**[Daniela Brozzoni](https://github.com/danielabrozzoni/)** - -November 3: Gave a [bolt.fun](https://bolt.fun) talk on open source development, [YouTube](https://www.youtube.com/watch?v=P75nCR1owws). - -October 25-26: Joined a ["Contributing to free and open source projects" panel](https://planb.lugano.ch/contributing-to-free-and-open-source-projects/) at [Plan B](https://planb.lugano.ch/) lugano. - -**[Evan Linjin](https://github.com/evanlinjin/)** - -November 15: Worked with [wizardsardine](https://wizardsardine.com/) team to [extract and integrate BDK coin-selection into the Liana wallet](https://twitter.com/darosior/status/1724842410839093562). - -December 3: Spoke at the [Bitcoin Tech Summit Taipei](https://twitter.com/TaiwanBitdevs/status/1726537941688967238). - -December 13: Gave a talk about Bitcoin and BDK at [Taipei Blockchain Week](https://twitter.com/JCBA_org/status/1735100779172856170). - -**[Thunderbiscuit](https://github.com/thunderbiscuit/)** - -November 8: Created the educational [Opcode Explained](https://opcodeexplained.com/) website to help... explain bitcoin opcodes! - -November 15: Joined the panel on the [Bitcoin Review Podcast Episode 55](https://bitcoin.review/podcast/episode-55/) to talked about his [padawan-wallet](https://github.com/thunderbiscuit/padawan-wallet) project. - -**[Matthew Ramsden](https://github.com/reez/)** - -October 11: Spoke at the [Bitcoin Park OpenHouse](https://www.meetup.com/bitcoinpark/events/291768716/) on the topic ["Exploring the Lightning Network"](https://podcasts.apple.com/us/podcast/open-house-exploring-the-lightning-network-ldk/id1646515985?i=1000631904227). - -November 8: Created a video for the [Bitcoin Developers](https://www.youtube.com/@bitcoindevelopers) channel on YouTube titled ["Lightning Development with Swift: Make Your First Lightning App with LDK Node Swift"](https://www.youtube.com/watch?v=rcU3LU6iZCs). - -**Other current and future contributors...** - -If you are a contributor to BDK and doing something fun that's BDK and/or bitcoin related let us know! Tag [@bitcoindevkit](https://twitter.com/bitcoindevkit/) on X, [notmandatory](https://primal.net/profile/npub1ke470rdgnxg4gjs9cw3tv0dp690wl68f5xak5smflpsksedadd7qtf8jfm) on nostr, or send us an email: blog at bitcoindevkit dot org. \ No newline at end of file diff --git a/docs/blog/2024_q1_update.md b/docs/blog/2024_q1_update.md deleted file mode 100644 index bb9671b73d..0000000000 --- a/docs/blog/2024_q1_update.md +++ /dev/null @@ -1,30 +0,0 @@ -# 2024 Q1 Project Update - -:lucide-pen-tool:   [`Steve Myers`](https://github.com/notmandatory) -:lucide-calendar-1:   `Mar 21, 2024` ---- - -### Core BDK - -The majority of BDK rust library work this quarter was towards finishing new and improved electrum, esplora and Bitcoin Core RPC (block-by-block) syncing APIs. Bug fixes and improvements were also completed for the transaction builder and other wallet APIs. Six bi-weekly 1.0.0-alpha releases were made ([alpha.3](https://github.com/bitcoindevkit/bdk/releases/tag/v1.0.0-alpha.3), [alpha.4](https://github.com/bitcoindevkit/bdk/releases/tag/v1.0.0-alpha.4), [alpha.5](https://github.com/bitcoindevkit/bdk/releases/tag/v1.0.0-alpha.5), [alpha.6](https://github.com/bitcoindevkit/bdk/releases/tag/v1.0.0-alpha.6), [alpha.7](https://github.com/bitcoindevkit/bdk/releases/tag/v1.0.0-alpha.7), [alpha.8](https://github.com/bitcoindevkit/bdk/releases/tag/v1.0.0-alpha.8)). For the quarter [54 PRs](https://github.com/bitcoindevkit/bdk/pulls?q=is%3Apr+merged%3A2024-01-01..2024-03-31+) were merged and [55 issues](https://github.com/bitcoindevkit/bdk/issues?q=is%3Aissue+closed%3A2024-01-01..2024-03-31+) were closed. - -### BDK-FFI - -For the language binding libraries (Kotlin, Swift, Python) the focus was on small bug fixes for the pre-1.0 releases ([0.30.0](https://github.com/bitcoindevkit/bdk-ffi/releases/tag/v0.31.0) and [0.30.1](https://github.com/bitcoindevkit/bdk-ffi/releases/tag/v0.31.1)) and creating the first 1.0.0-alpha bindings release ([1.0.0-alpha.7](https://github.com/bitcoindevkit/bdk-ffi/releases/tag/v1.0.0-alpha.7)). For the quarter [23 PRs](https://github.com/bitcoindevkit/bdk-ffi/pulls?q=is%3Apr+merged%3A2024-01-01..2024-03-31+) were merged and [8 issues](https://github.com/bitcoindevkit/bdk-ffi/issues?q=is%3Aissue+closed%3A2024-01-01..2024-03-31+) closed. - -### Plans for Next Quarter - -The focus for Q2 development is completing our first 1.0.0 beta release and improving user docs and testing for it. The team will also work on updating all language bindings (Kotlin/Swift/Python) to use new rust lib 1.0.0 beta APIs. - -### BDK contributors spotlight - -In this section we share what some of our hardworking contributors are doing to educate people about BDK, help on board new projects, and generally promote bitcoin and open source development around the world. - -**[Evan Linjin](https://github.com/evanlinjin/)** - -February 22: Gave a talk on [BDK 1.0 at BTC++](https://btcplusplus.dev/conf/ba24/talks) in Buena Aires, Argentina. - - -**Other current and future contributors...** - -If you are a contributor to BDK and doing something fun that's BDK and/or bitcoin related let us know! Tag [@bitcoindevkit](https://twitter.com/bitcoindevkit/) on X, [notmandatory](https://primal.net/profile/npub1ke470rdgnxg4gjs9cw3tv0dp690wl68f5xak5smflpsksedadd7qtf8jfm) on nostr, or send us an email: blog at bitcoindevkit dot org. \ No newline at end of file diff --git a/docs/blog/2024_q2_update.md b/docs/blog/2024_q2_update.md deleted file mode 100644 index 0f03cd82e8..0000000000 --- a/docs/blog/2024_q2_update.md +++ /dev/null @@ -1,39 +0,0 @@ -# 2024 Q2 Update: What Have We Been Up To? - -:lucide-pen-tool:   [`thunderbiscuit`](https://github.com/thunderbiscuit) -:lucide-calendar-1:   `Jul 1, 2024` ---- - -The bitcoindevkit team has been hard at work for Q2 in 2024, pushing to stabilize the API of its `bdk_wallet` crate and releasing 4 new alpha versions (9, 10, 11, and 12!), and aiming to release a 1.0 beta in July. Here are some of the notable changes and upgrades to the software libraries we maintain: - -- **Update `bdk_electrum` to use merkle proofs.** This PR is the first step in reworking `bdk_electrum` to use merkle proofs. When we fetch a transaction, we now also obtain the merkle proof and block header for verification. We then confirm a transaction is in a block only after validating it's Merkle proof. -- **Upgrade of rust-bitcoin and rust-miniscript.** We upgraded our dependencies on these crates to the latest `0.32.0` and `0.12.0` respectively. -- **Added examples.** We added examples and cleaned up our current example crates to help builders stay up-to-date on the latest changes. -- **Use bitcoin::Amount in most public APIs.** This change ensures type safety when requiring and providing bitcoin amount in our APIs, using the rust-bitcoin crate `Amount` type. -- **Introduce Sync and FullScan related types.** This change introduced universal structures that represent sync/full-scan requests/results for all SPK-based syncing clients. -- **Allow user provided RNG.** This change makes the `rand` dependency optional. - -The language bindings for iOS, Android, and Python have also seen some new alpha release and a ton of new features, in preparation for the beta release. - -- **Upgrade to the latest uniffi (0.28.0).** This was a major upgrade that gave us a whole new set of functionalities: the ability to implement traits in the foreign languages, using the `Display` trait to auto-generate the `toString()` methods, enable API docs in the UDL file, and support for async! -- **Brand new iOS build workflow.** This one is nerdy but a goodie. Anyone interested in how we build bindings should check out this major cleanup of our iOS library build workflow! -- **Starting the work on bitcoin-ffi.** The team has started the work on a separate crate called [bitcoin-ffi](https://github.com/bitcoindevkit/bdk-ffi), effectively migrating the types we exposed from rust-bitcoin into a standalone crate that other projects building on uniffi can use. - - -### Our Grantees in Action - -In addition to our full-time grantees, the [BDK Foundation](https://bitcoindevkit.org/foundation/about/) provides part-time grants to folks on special projects. Q2 is funding 2 projects in particular: - -- **Wei Chen.** Wei has been contributing to BDK since late 2023 and was formerly a full stack Java developer based in Washington D.C. with ten years of experience. The focus of his contributions will be towards assisting with the restructuring of the electrum crate, reengineering of the TxGraph data components to simplify the tracking of lineal conflicts, as well as on performance optimization and the continued debugging of BDK. -- **Manuel Gatti.** Manuel is a Project Manager at Wizard Sardine. He is involved in some educational projects related to bitcoin in Italy and hosts an Italian podcast about libertarian philosophy with episodes dedicated to bitcoin as a tool for freedom. He has been contributing to BDK since April 2023 mostly on the project management side (holding calls, helping with triage and prioritization, updating stakeholders). His project consists of conducting user interviews in order to get feedback on BDK usage and possible pain points with the aim to help the team with the definition and prioritization of the development activities. - -We've also been active at conferences! - -- Evan made his way to South Korea to host a workshop at the [Bitcoin Seoul](https://www.bitcoinseoul.kr/) conference. -- Evan and ValuedMammal also made their way to the [bitcoin++ conference in Buenos Aires](https://btcplusplus.dev/conf/ba24) to talk about BDK. -- thunderbiscuit was in Montreal for the [Canadian Bitcoin Conference](https://canadianbitcoinconf.com) again this year. A fantastic event with many users of BDK present! - -### BDK in the Wild - -- In Q2, [Bitkey](https://bitkey.world/en-US) open sourced their app, making it one of the biggest users of BDK on mobile. -- [Bull Bitcoin](https://www.bullbitcoin.com/) released their [Android app](https://play.google.com/store/apps/details?id=com.bullbitcoin.mobile) based on the bdk-flutter library at the Canadian Bitcoin Conference in Montreal! diff --git a/docs/blog/2024_q3_update.md b/docs/blog/2024_q3_update.md deleted file mode 100644 index 75552531aa..0000000000 --- a/docs/blog/2024_q3_update.md +++ /dev/null @@ -1,44 +0,0 @@ -# 2024 Q3 Update: What Have We Been Up To? - -:lucide-pen-tool:   [`thunderbiscuit`](https://github.com/thunderbiscuit) -:lucide-calendar-1:   `Nov 7, 2024` ---- - -The bitcoindevkit team has been hard at work for Q3 in 2024, polishing the API of our `bdk_wallet` crate and releasing 4 new beta versions (1, 2, 3, and 4!), and aiming to release a final 1.0 release by the end of 2024. Here are some of the notable changes and upgrades to the software libraries we maintain: - -- **RBF by default on TxBuilder.** The transaction builder in BDK will now signal RBF by default. -- **New wallet builder API.** The new wallet builder offers flexibility and ease-of-development for future features. We've also been listening to user feedback, and brought back support for single-descriptor wallets. -- **MVP of the Book of BDK.** We are working on a high-level documentation website for BDK libraries called the Book of BDK. The MVP website is live at [bookofbdk.com](https://bookofbdk.com/). -- **Bug chasing and optimizations.** As feedback from early testers comes in, we are keeping a close eye on reported bugs and questions, and have been fixing a ton of smaller but very important snags! -- **Development of a CBF client crate and related bindings.** Work is ongoing on a crate to allow BDK users to interoperate with a new CBF library called [Kyoto](https://github.com/rustaceanrob/kyoto). Work has been done to integrate this with the language bindings for mobile users, and the preliminary integrations have been very positive. - -The language bindings for iOS, Android, and Python have also seen some new beta releases and a ton of new features, in preparation for the 1.0 final release. - -- **Exposing a much larger number of Wallet APIs.** The Wallet type in the language bindings now exposes most of what users will need for a 1.0 release. -- **Rework of the Kotlin and Swift build systems.** We have migrated the build workflows for bdk-jvm and bdk-android from Gradle scripts to shell scripts, making them easier to parse and consume for contributors and other libraries wanting to leverage our approach to bindings. We have also made it much easier to build the Swift package for iOS users. -- **Testing of Compact Block Filters for both Android and iOS.** Both our wallet examples have full examples of using the new [Kyoto](https://github.com/rustaceanrob/kyoto) client on mobile phones. Once the PR for the new client lands, users will have access to clear examples on how to leverage the new client! -- **Building bitcoin-ffi.** The team has been working on a crate called [bitcoin-ffi](https://github.com/bitcoindevkit/bdk-ffi), migrating the types we exposed from rust-bitcoin into a standalone crate that other projects building on uniffi can use. We have been stress-testing this in production and are finding new ways to leverage this approach. - -### Our Grantees in Action - -Full-time grants changes: -- Our lead Rust developer Evan is moving to a part-time grant while he goes and works for a company that leverages BDK! -In addition to our full-time grantees, the [BDK Foundation](https://bitcoindevkit.org/foundation/about/) provides part-time grants to folks on special projects. Q3 is funding 2 projects in particular: -- **Leonardo.** [Leo]()'s been working on our integration of the Tor Rust client into the Electrum and Esplora crates. -- **Rob.** [Rob]() is the brain behind the [Kyoto]() client, its BDK integration with `bdk_kyoto`, and the PR to wrap it all up into our language bindings! -- **Wei Chen.** [Wei](https://github.com/LagginTimes) is continuing his work on the lower-level BDK crates `bdk_chain` and `bdk_core`, as well as his work on the Electrum client. - -We've also been active at conferences! - -- Steve [was on a panel at the 2024 Bitcoin Conference](https://www.youtube.com/watch?v=Qlbwxbe7xHE) discussing with 2 teams that are building on BDK. -- The team was in Nashville for a week of hard work and collaboration between devs in the Rust bitcoin ecosystem we called the "Rust Bitcoin Summit". The event was so successful we're hoping to do it again next year! Here is a link to a [Citadel Dispatch podcast](https://serve.podhome.fm/episodepage/CitadelDispatch/cd136-rust-bitcoin-summit-with-poelstra-harding-myers-corallo-and-more) with some of the devs who hosted and participated. - -### BDK in the Wild - -In Q3, a number of new projects have started using BDK: -- The Protonmail team has released the latest tool in the Proton family: the [Proton Bitcoin Wallet App](https://proton.me/blog/proton-wallet-launch). The wallet is using the 1.0 beta version of the library. Welcome aboard Proton! -- The [bark Ark implementation]() started using the BDK beta releases for its wallet implementation. -- [Bitcoin Safe](https://bitcoin-safe.org/) released its first beta release. -- [Satsails](https://www.satsails.com/) is now live on the Play Store! -- [Strata](https://www.stratabtc.org/) has released a devnet version of their CLI wallet, which uses BDK. -- Our BDK Swift Example Wallet is [now available on iOS Testflight](https://testflight.apple.com/join/A3nAuYvZ)! diff --git a/docs/blog/2024_q4_code_audit.md b/docs/blog/2024_q4_code_audit.md deleted file mode 100644 index 6d7dd3b733..0000000000 --- a/docs/blog/2024_q4_code_audit.md +++ /dev/null @@ -1,13 +0,0 @@ -# 2024 Q4 Code Audit - -:lucide-pen-tool:   [`Steve Myers`](https://github.com/notmandatory) -:lucide-calendar-1:   `Dec 3, 2024` ---- - -A heartfelt thank you to our friends at [Spiral](https://spiral.xyz/) for sponsoring a code audit of the current `bdk` 1.0.0-beta Rust codebase. The effort was led by [Antoine Poinsot](https://github.com/darosior) from [Wizardsardine](https://wizardsardine.com/), who did a fantastic job providing insightful and actionable recommendations for the BDK team. You can find the full report [here](https://gist.github.com/darosior/4aeb9512d7f1ac7666abc317d6f9453b). - -As outlined in Antoine's report, the audit's primary focus was to review the core components that constitute a BDK-based wallet, particularly the new methods for managing and synchronizing chain data. The audit scope included some reasonable simplifying assumptions, such as trusting that the Electrum or Esplora servers to which BDK wallets connect are not malicious. However, Antoine went above and beyond and also recommended a few simple fixes we can do to guard against certain types of bad server behavior. - -While no critical defects were identified, a potential denial of service/performance issue was uncovered, along with opportunities to improve the code's fault tolerance and API documentation. The team is currently addressing the performance issue, as well as some of the more straightforward recommendations. All suggested improvements have been [added to our issues backlog](https://github.com/bitcoindevkit/bdk/issues?q=is%3Aissue+label%3Aaudit) for future releases. - -If you are a user or potential user of BDK, or a Bitcoin Rust developer, we would love to hear your feedback. Please reach out on the [BDK Discord](https://discord.gg/dstn4dQ) or comment on individual [GitHub issues](https://github.com/bitcoindevkit/bdk/issues?q=is%3Aissue+is%3Aopen). As a fully free and open-source project, the BDK team relies on YOU our community of users and contributors to help us deliver the best Bitcoin wallet library possible. diff --git a/docs/blog/2024_q4_update.md b/docs/blog/2024_q4_update.md deleted file mode 100644 index 1c2d3d25e9..0000000000 --- a/docs/blog/2024_q4_update.md +++ /dev/null @@ -1,45 +0,0 @@ -# 2024 Q4 Update: What Have We Been Up To? - -:lucide-pen-tool:   [`thunderbiscuit`](https://github.com/thunderbiscuit) -:lucide-calendar-1:   `Jan 15, 2025` ---- - -The bitcoindevkit team was very proud to release the 1.0 stable version of our bdk_wallet API in Q4! It's been a long time coming, and all that testing, reviewing, refactoring, and polishing finally paid off. Onwards! 🎉 - -Here are some of the notable releases and changes over Q4 to the software libraries we maintain: - -- **The bdk_wallet library is now 1.0.** If you've been with us for a while you know that this has been a big goal over the past year. -- **The Book of BDK is live and out of beta.** Check out [https://bookofbdk.com](https://bookofbdk.com) for high-level documentation on a range of things related to the family of libraries we maintain. -- **The work continued on Kyoto (Compact Block Filters client).** The [bdk-kyoto](https://github.com/bitcoindevkit/bdk-kyoto) library also moved into the [Bitcoin Dev Kit GitHub organization](). Congrats Rob! -- **Triaging for the new feature release cadence.** We have agreed on a new, 8-week release cadence for the feature releases of 1.0 (1.1, 1.2, 1.3, etc.). [You can see our milestones for those releases here](https://github.com/bitcoindevkit/bdk/milestones?direction=asc&sort=due_date&state=open). This should allow us to release stuff on a steady cadence. Look out for the things that didn't make it into the initial 1.0 but should be ready soon! -- **Bugfix release 0.32.0.** We published a fix to the 0.31 library in December. Check it out if you're still migrating to the 1.0 API. - -The language bindings for iOS, Android, and Python have also seen some new beta releases and a ton of new features, in preparation for the 1.0 final release. - -- **Exposing Wallet and TxBuilder APIs.** Most of the `Wallet` and `TxBuilder` APIs from bdk_wallet are now available to language bindings users. -- **Better and more useful clients.** Our Electrum and Esplora clients have more methods exposed and can perform more things Rust users can do on the language bindings. -- **Docstrings are added to the library.** Leveraging a new feature of uniffi, this allows us to build API documentation for Kotlin, Swift, and Python once we're ready. -- **Increase our use of bitcoin-ffi type.** The bitcoin-ffi library is becoming more useful, with review from ldk-node and Payjoin developers. We're leaning on it more, and intend to continue its development moving forward. - -### BDK Team in Action - -Full-time grants changes: - -- Our part-time grantee [Wei Chen](https://github.com/LagginTimes) transitioned into a full-time role! Welcome to the team Wei. -In addition to our full-time grantees, the [BDK Foundation](https://bitcoindevkit.org/foundation/about/) provides part-time grants to folks on special projects. Q4 is funding 1 project in particular: -- **Nymius.** [Nymius](https://github.com/nymius)'s been working on the clean up of the `filestore` crate as well as reviewing and helping the continuation of development for the `bdk_chain` and `bdk_core` crates. - -We've also been active at conferences! - -- [Leo](https://github.com/oleonardolima) presented a workshop on BDK at [SatsConf](https://www.satsconf.com.br/) in Sao Paulo! -- [Rob](https://github.com/rustaceanrob) presented on the [Kyoto](https://github.com/rustaceanrob/kyoto) client at [TabConf](https://6.tabconf.com/) this year. -- [Steve](https://github.com/notmandatory) also presented a workshop at [TabConf](https://6.tabconf.com/) on a demo axum async web based bdk wallet. -- [Alekos](https://github.com/afilini) presented on BDK at [Adopting Bitcoin](https://sv24.adoptingbitcoin.org/) in El Salvador! - -### BDK in the Wild - -Q4 saw 3 new projects integrating BDK into their software: - -- [Alby](https://getalby.com/) is a browser extension that makes lightning and nostr easier to build on and use. -- [TwentyTwo](https://twenty-two.xyz/) produces the first 100% open source mobile-native hardware wallet: designed to keep your keys safe and seamlessly integrate into any mobile wallet app. -- The [Satoshi](https://satoshi.money/) app is live and is using BDK! diff --git a/docs/blog/2025_q1_new_bdkf_members.md b/docs/blog/2025_q1_new_bdkf_members.md deleted file mode 100644 index c295715221..0000000000 --- a/docs/blog/2025_q1_new_bdkf_members.md +++ /dev/null @@ -1,46 +0,0 @@ -# 2025 Q1 New BDK Foundation Members - -:lucide-pen-tool:   [`Steve Myers`](https://github.com/notmandatory) -:lucide-calendar-1:   `Apr 8, 2025` ---- - -The Bitcoin Dev Kit (BDK) Foundation is happy to announce our first new corporate members for 2025 - [AnchorWatch](https://www.anchorwatch.com/), [CleanSpark](https://www.cleanspark.com/), and [Proton Foundation](https://proton.me/foundation)! A big thanks to our new Foundation members as well as our founding members [Spiral](https://spiral.xyz/) and [OpenSats](https://opensats.org/) for supporting our mission. Corporate members' yearly dues fund the small team of open source developers who maintain the core BDK libraries and related, supporting FOSS projects. - -The BDK Foundation is a US non-profit organization with the mission to promote the common business interests of the Bitcoin software development industry. To that end the Foundation focuses on enhancing the capabilities of businesses, individuals, and organizations who use Bitcoin related technology in their products and services. The primary way the Foundation carries out this mission is through our stewardship of free and open source (FOSS) tools such as the BDK suite of libraries and related training material. The Foundation also hosts forums for developer mentoring and networking, and in-person talks and workshops. - -We invite all businesses big or small who support the BDK Foundation's mission to join us as corporate members. Please see our [membership](/foundation/become-a-member/) page for more information or contact us at [hello@bitcoindevkit.org](https://mailto:hello@bitcoindevkit.org/). - -
- -
- -- ### AnchorWatch - - --- - - AnchorWatch - - AnchorWatch is a Lloyd's of London coverholder, offering 1:1 insurance on bitcoin held in its cold storage solution Trident Vault for up to $100 Million per customer. Serving both retail and commercial clients today in the United States, AnchorWatch leverages advanced Bitcoin smart contracts with the functionality of Miniscript which is supported within BDK. - - [:octicons-arrow-right-24: Website](https://www.anchorwatch.com) - -- ### Proton Foundation - - --- - - Proton Foundation - - Proton Mail started in 2014 with uncensorable donations from the Bitcoin community. In 2024, Proton Wallet launched as a BDK-based Bitcoin wallet to protect financial freedom for all. As Proton's primary shareholder, the non-profit Proton Foundation supports technologies that advance privacy, freedom, and democracy around the world. - - [:octicons-arrow-right-24: Website](https://proton.me/foundation) - -- ### CleanSpark - - --- - - CleanSpark - - CleanSpark responsibly develops infrastructure for Bitcoin, an essential tool for financial independence and inclusion. We strive to leave the planet better than we found it by investing in communities that we operate in. Bitcoin is a watershed moment, not only in the history and invention of money, but in how we relate to each other. - - [:octicons-arrow-right-24: Website](https://www.cleanspark.com) -
diff --git a/docs/blog/2025_q1_update.md b/docs/blog/2025_q1_update.md deleted file mode 100644 index 3b33492f21..0000000000 --- a/docs/blog/2025_q1_update.md +++ /dev/null @@ -1,41 +0,0 @@ -# 2025 Q1 Update: What Have We Been Up To? - -:lucide-pen-tool:   [`thunderbiscuit`](https://github.com/thunderbiscuit) -:lucide-calendar-1:   `Apr 2, 2025` ---- - -The bitcoindevkit team is hitting cruising speed after the release of the 1.0 bdk_wallet API. We are implementing a new release cadence of 8-week cycles, planning to do a feature release (1.1, 1.2, etc.) on [these dates for 2025]( -https://github.com/bitcoindevkit/bdk/milestones). - -Here are some of the notable releases and changes over Q1 to the software libraries we maintain: - -- **The new bdk_wallet 1.1 library is out.** This one includes some of the goodies we could not release in 1.0, including support for Testnet 4, creating transactions version 2 by default, and supporting single-descriptor wallets! -- **The Book of BDK has seen significant improvements.** After a few months of use and feedback on the book, we have updated a ton of pages and examples to reflect some of the new and unclear questions we were getting from users on our Discord server and on GitHub. Check out [https://bookofbdk.com](https://bookofbdk.com)! -- **Kyoto (a new Compact Block Filters client) is now usable with BDK.** The [bdk-kyoto](https://github.com/bitcoindevkit/bdk-kyoto) library moved into the [Bitcoin Dev Kit GitHub organization](), and while the client should be considered experimental, it can now be used directly with BDK wallets! -- **Preparing for BDK Tech Talks.** The BDK Foundation is planning to host a series of technical talks relating to BDK, including team members showcasing their work, sample apps, or ongoing PRs, and BDK users telling their story of using BDK in production. See [this issue]() for all the details! Some of the talks will be recorded and posted on our [Youtube channel](https://www.youtube.com/@bitcoindevkit). -- **PGP Keys for the team are published.** Our website has a [new page with PGP keys](https://bitcoindevkit.org/foundation/pgp/) for some of the core members of the team as well as board members of the Foundation. - -The language bindings for iOS, Android, and Python have released their first stable release (1.1)! 🎉. This is a significant milestone for the language bindings team, and for all our users on mobile. - -- **1.1 is out.** This is our first stable release. Tons of new stuff was added since the 0.32.0 release, too much to list out! -- **Kyoto is merged on the master branch.** If you're looking to start experimenting with Compact Block Filters on mobile, we've got you covered! You can build the latest version of the libraries and use the new experimental client directly. We also have examples on [Android](https://github.com/bitcoindevkit/devkit-wallet) and [Desktop](https://github.com/thunderbiscuit/godzilla-wallet) ready to dig into. -- **We now release API docs for Kotlin + Swift.** Our API docs are getting a facelift! Check out the [Book of BDK](https://bookofbdk.com) for all the details! - -## Our Grantees in Action - -Full-time grants changes: - -- Our part-time grantee [Nymius](https://github.com/nymius) transitioned from a part-time grant into a full-year project grant! His core project is working on the development of Silent Payments for BDK. Welcome to the team Nymius. - -We've also been active at conferences! - -- [Leo](https://github.com/oleonardolima) hosted an introduction to BDK and BDK PR Review Club and also took part in a discussion with other Brazilian grantees about his FOSS experience for the Vinteum BDL Residency folks the week before bitcoin++ in São Paulo! - -## BDK in the Wild - -Q1 saw 4 new projects integrating BDK into their software: - -- [Frostnap](https://frostsnap.com/) produces hardware and mobile apps that together form the ultimate bitcoin security system is ready for early adopters. -- [Cove Wallet](https://covebitcoinwallet.com/) is a simple yet powerful bitcoin mobile wallet. It's intuitive and simple for newcomers while being powerful enough for experienced bitcoiners. -- [Fedimint](https://fedimint.org/) is a modular open source protocol to custody and transact bitcoin in a community context, built on a strong foundation of privacy. -- [BitVault](https://www.bitvault.sv/) is your fortress against physical attacks and hacks, by employing time-delayed transactions and a multisig convenience service to shield your assets. diff --git a/docs/blog/2025_q2_update.md b/docs/blog/2025_q2_update.md deleted file mode 100644 index f8834233fa..0000000000 --- a/docs/blog/2025_q2_update.md +++ /dev/null @@ -1,59 +0,0 @@ -# 2025 Q2 Update: What Have We Been Up To? - -:lucide-pen-tool:   [`matthewramsden`](https://github.com/reez) -:lucide-calendar-1:   `Jul 2, 2025` ---- - -The second quarter of 2025 was an exciting one for the Bitcoin Dev Kit. With major releases, new libraries, a YouTube launch, and ongoing contributions from our community of grantees and collaborators, BDK continues to push forward the frontier of building Bitcoin wallets. - -Here are some of the notable releases and changes over Q2 to the software libraries we maintain: - -- **The bdk_wallet 2.0 release!** Following on the heels of 1.0, we've released [BDK 2.0](https://github.com/bitcoindevkit/bdk_wallet/releases/tag/wallet-2.0.0) which includes a bug fix for handling stuck or evicted transactions, performance enhancements for large wallets, more extensive test coverage, and the return of TxDetails. -- **BDK CLI 1.0.** Our [command-line interface has reached its 1.0 milestone](https://github.com/bitcoindevkit/bdk-cli/releases/tag/v1.0.0), uses bdk_wallet 1.0.0 and integrates Kyoto, the new client for compact block filters in BDK. It sets SQLite as the default database and drops support for sled. -- **Language Bindings version 1.2 for iOS, Android, and Python 1.2** The [bdk-ffi 1.2 release](https://github.com/bitcoindevkit/bdk-ffi/releases/tag/v1.2.0) brings Compact Block Filter support through our Kyoto integration, making privacy-preserving light clients accessible to mobile developers. We've also published comprehensive [API documentation](https://javadoc.io/doc/org.bitcoindevkit/bdk-android)) for Kotlin, Java, and Android bindings. - -There are also new projects and initiatives being built. - -- **Silent Payments.** The new [bdk-sp](https://github.com/bitcoindevkit/bdk-sp) crate brings BIP352 Silent Payments functionality to BDK. It has delivered a complete CLI implementation with wallet initialization, PSBT creation and signing, and blockchain scanning capabilities, and full compatibility with BIP352 test vectors and integration examples with bdk-tx. -- **Transaction Building.** The experimental [bdk-tx](https://github.com/bitcoindevkit/bdk-tx) project represents an evolution of transaction building. This effort to decouple transaction building from the wallet, using rust-miniscript's planning module for optimal satisfaction-weight calculations and the new bdk_coin_select crate for policy-aware coin selection. -- **Streaming Electrum Client.** The [electrum_streaming_client](https://github.com/bitcoindevkit/electrum_streaming_client) is a streaming, sans-IO Electrum client for asynchronous and blocking Rust applications. This crate provides low-level primitives and high-level clients for communicating with Electrum servers over JSON-RPC. It supports both asynchronous (futures/tokio) and blocking transport models. - -## Our Grantees in Action - -We're excited to welcome new Silver [corporate members](../foundation/members.md) to the BDK Foundation and thank them for their financial support! - -- [AnchorWatch](https://www.anchorwatch.com) -- [CleanSpark](https://www.cleanspark.com) -- [Proton Foundation](https://proton.me/foundation) - -We're also excited to welcome new Associate members who are supporting the BDK Foundation by training & funding developers working on BDK! - -- [Btrust](https://www.btrust.tech) -- [Vinteum](https://vinteum.org) - -**Grantees** - -BDK Project Maintainer - -- [Leonardo](https://github.com/oleonardolima), funded by Vinteum, continues his work on Tor integration for the Electrum and Esplora crates, enhancing privacy options for BDK users. - -Btrust Starter Grantees - -- [Itoro Ukpong](https://github.com/ItoroD), working on the bdk-ffi language bindings and Android example wallet. -- [Peter Tyonum](https://github.com/tvpeter), upgrading bdk-cli to the latest bdk rust libraries and adding new features. - -Thunderbiscuit is taking a 2-month break from BDK using an HRF grant to create an iOS version of [Padawan Wallet](https://play.google.com/store/apps/details?id=com.coyotebitcoin.padawanwallet) - -We've launched our official [BDK YouTube channel](https://www.youtube.com/@bitcoindevkit) featuring our [Technical Talks series of 6 videos](https://www.youtube.com/playlist?list=PLFQTgyPgNM1iP9vqO6-Oic02x-MhxrNQu), covering topics: - -1. Language Bindings by [thunderbiscuit](https://github.com/thunderbiscuit) -2. Silent Payments by [nymius](https://github.com/nymius) -3. [Transaction Ordering](https://github.com/ValuedMammal/valuedmammal.github.io?tab=readme-ov-file#which-came-first) by [ValuedMammal](https://github.com/ValuedMammal) -4. CLI by [Peter Tyonum](https://github.com/tvpeter) -5. Compact Block Filters by [Robert Netzke](https://github.com/rustaceanrob) -6. Mobile by [Matthew Ramsden](https://github.com/reez) - -## BDK in the Wild - -- [Cove Wallet](https://covebitcoinwallet.com/) is a simple yet powerful bitcoin mobile wallet that is now officially released on the App Store. -- [Frostnap](https://frostsnap.com/) produces hardware and mobile apps that together form the ultimate bitcoin security system is now open for pre-orders. diff --git a/docs/blog/2025_q3_update.md b/docs/blog/2025_q3_update.md deleted file mode 100644 index adca7946b8..0000000000 --- a/docs/blog/2025_q3_update.md +++ /dev/null @@ -1,29 +0,0 @@ -# 2025 Q3 Update: What Have We Been Up To? - -:lucide-pen-tool:   [`thunderbiscuit`](https://github.com/thunderbiscuit) -:lucide-calendar-1:   `Nov 6, 2025` ---- - -Q3 saw a new feature release of the bdk_wallet library (`2.1.0`), with great new features being added including support for multipath descriptors, more flexible transaction building capabilities, as well as better caching when working with large wallets. - -Here are some of the notable releases and changes over Q3 to the software libraries we maintain: - -- **We have a new _Release Notes_ section** on the Book of BDK. Head over to the [book of BDK Release Guide section](https://bookofbdk.com/release-guide/2.2/notes/) for notes on the latest releases. -- **The Electrum, Esplora, and Kyoto client** have all gotten new releases with some small added features and bug fixes. -- **The Book of BDK examples have all been updated to reflect the new 2.0 APIs.** Check out [https://bookofbdk.com](https://bookofbdk.com)! -- **We've split up some of the language bindings libraries** into their own repositories in order to make it easier for devs to contribute to those, and for new languages to copy our workflow! Keep an eye out for our experimental React Native and Flutter libraries, to be announced later this year... -- **The work on Silent Payments** with BDK is ongoing with [nymius](https://github.com/nymius) working full-time on a range of libraries that must come together in the Rust ecosystem to bring this all the way down to wallet devs through BDK. Conferences, hackathons, example cli tools to showcase the workflows and libraries, Nymius is working hard to get Silent Payments in BDK! -- **Lots of new features** are being worked on as part of the preparation for a 3.0 release! See our [3.0 milestone](https://github.com/bitcoindevkit/bdk_wallet/milestone/3) for all the gory details. - -## Our Grantees in Action - -Full-time grants changes: - -- We now have [Luis](https://github.com/luisschwab) working on a project grant, integrating Floresta with BDK! - -## BDK in the Wild - -- Q3 saw new projects integrating BDK into their software, most notably [MetaMask](https://metamask.io/) with a WASM language bindings library now maintained by the BDK Foundation ([see the repository here](https://github.com/bitcoindevkit/bdk-wasm)). -- We have continued to record the BDK Tech Talk videos, and they're on YouTube! Check them out: - - [BDK on Mobile](https://www.youtube.com/watch?v=J2wLCv_fx5Y) - - [BDK at Portal](https://www.youtube.com/watch?v=koaeRIpXUZM&t=29s) diff --git a/docs/blog/2025_q4_btcnews_interview.md b/docs/blog/2025_q4_btcnews_interview.md deleted file mode 100644 index 3c6f448a97..0000000000 --- a/docs/blog/2025_q4_btcnews_interview.md +++ /dev/null @@ -1,15 +0,0 @@ -# BDK Featured in Bitcoin News Interview - -:lucide-pen-tool:   [`Steve Myers`](https://github.com/notmandatory) -:lucide-calendar-1:   `Dec 17, 2025` ---- - -I recently joined Bitcoin News for a friendly conversation about Bitcoin Development Kit’s origins, mission, and where we’re headed. I shared how BDK grew from an early side project into a cross-platform foundation, powering wallets and Bitcoin applications across the ecosystem. - -The chat also covered BDK’s open-source philosophy, support for layer two protocols, and how developers use BDK to ship safer, more flexible Bitcoin products, without reinventing core infrastructure. Check out [the full conversation](https://bitcoinnews.com/p/bitcoin-development-kit-steve-myers) to hear the complete story behind BDK, its real-world impact, and what’s coming next. - -**About Bitcoin Development Kit**: -Bitcoin Development Kit (BDK) is an open-source library that simplifies building Bitcoin wallets and applications. Written in Rust with bindings for multiple languages, BDK handles core Bitcoin functionality, like key management, transaction construction, and blockchain syncing. BDK is maintained by the Bitcoin Dev Kit Foundation and is used by wallets, exchanges, and infrastructure projects across the Bitcoin ecosystem. - -**About Bitcoin News**: -Bitcoin News Inc is a US-based media company focused on delivering accurate and accessible coverage of the Bitcoin ecosystem. Working alongside [its partners](https://RhinoBitcoin.com), Bitcoin News aims to inform readers about the trends, innovations, and businesses shaping Bitcoin’s continued growth. diff --git a/docs/blog/2025_q4_update.md b/docs/blog/2025_q4_update.md deleted file mode 100644 index 2a01b9c4aa..0000000000 --- a/docs/blog/2025_q4_update.md +++ /dev/null @@ -1,42 +0,0 @@ -# 2025 Q4 Update: What Have We Been Up To? - -:lucide-pen-tool:   [`thunderbiscuit`](https://github.com/thunderbiscuit) -:lucide-calendar-1:   `Jan 21, 2026` - ---- - -Q4 saw two new feature releases of the bdk_wallet library (`2.2.0` and `2.3.0`), continued work on documentation, and a strong presence at TABConf where four team members presented talks and workshops. We also had a productive three-day summit in Nashville where a large part of the team met with other Rust + Bitcoin developers. - -Here are some of the notable releases and changes over Q4 to the software libraries we maintain: - -- **Release 2.2 and 2.3 of `bdk_wallet`.** These releases continue to build on the 2.0 foundation with new features and improvements. Along came the [2.2](https://github.com/bitcoindevkit/bdk-ffi/releases/tag/v2.2.0) release of bdk-ffi, including the Swift, Android, JVM, and Python libraries. -- **Release 0.24.1 of `rust-electrum-client`.** This release fixed some long-standing issues identified by users of the library. -- **PayJoin support added to bdk-cli.** We've added a PayJoin feature to bdk-cli to test basic integration with BDK. See [the PR](https://github.com/bitcoindevkit/bdk-cli/pull/200) for details. -- **New Book of BDK section: Release Guide.** We've added a comprehensive [Release Guide](https://bookofbdk.com/release-guide/guide/) to help developers understand our release process. -- **Library Tiers defined.** We now have clearly defined [Library Tiers](https://bookofbdk.com/getting-started/tiers/) to help developers understand the maturity and stability of our various libraries. -- **MetaMask adds self-custodial Bitcoin snap built with bdk-wasm.** MetaMask wallet announced a new self-custodial Bitcoin "snap" (plugin) built using our bdk-wasm library, bringing BDK to a massive user base. - -## Our Grantees in Action - -We had a strong presence at TABConf this year with four presentations from the team: - -- [Luis](https://github.com/luisschwab) presented "Merkle Trees is the Perfect Place for UTXOs: Floresta as a chain source for BDK" ([Day 4](https://github.com/TABConf/7.tabconf.com/issues/33)) -- [ValuedMammal](https://github.com/ValuedMammal) presented "Planning ahead: building transactions with complex spending conditions in BDK" ([Day 4](https://github.com/TABConf/7.tabconf.com/issues/52)) -- [Thunderbiscuit](https://github.com/thunderbiscuit) presented "Documenting BDK" ([Day 4](https://github.com/TABConf/7.tabconf.com/issues/38)) -- [Nymius](https://github.com/nymius) hosted a workshop "Adding silent payments support to BDK" ([Day 4](https://github.com/TABConf/7.tabconf.com/issues/32)) - -Following TABConf, the BDK team met with other Rust and Bitcoin-based developers in Nashville for a three-day summit, collaborating on initiatives and planning for the year ahead. - -## BDK in the Wild - -Q4 saw new projects integrating BDK into their software and being added to our [adoption page](../adoption/all/): - -- [Eigenwallet](https://eigenwallet.org/) -- [Satsigner](https://satsigner.com/) -- [MetaMask](https://metamask.io/) -- [SatGo](https://satgo.io/) - -Other notable integrations: - -- **Bitcoin Safe released Kyoto on Mainnet.** Bitcoin Safe is now running Kyoto, our Compact Block Filters client, on mainnet! -- **rust-cktap in iOS.** Our [rust-cktap](https://github.com/bitcoindevkit/rust-cktap) library is being used in [SatsBuddy](https://github.com/reez/SatsBuddy), an iOS app for interacting with SATSCARD devices. diff --git a/docs/blog/2026_q1_update.md b/docs/blog/2026_q1_update.md deleted file mode 100644 index dbfcdede60..0000000000 --- a/docs/blog/2026_q1_update.md +++ /dev/null @@ -1,37 +0,0 @@ -# 2026 Q1 Update: What Have We Been Up To? - -:lucide-pen-tool:   [`thunderbiscuit`](https://github.com/thunderbiscuit) -:lucide-calendar-1:   `Apr 20, 2026` - ---- - -Q1 2026 was headlined by the release candidate cycle for `bdk_wallet` 3.0.0, a major milestone the team has been building toward for over a year. Alongside that, we welcomed two new associate members to the BDK Foundation, saw continued momentum in mobile library development, and formalized maintainership and support tiers across every library in the GitHub org. - -Here are some of the notable releases and changes over Q1 to the software libraries we maintain: - -- **Release candidates for `bdk_wallet` 3.0.0.** Two release candidates ([3.0.0-rc1](https://github.com/bitcoindevkit/bdk/releases/tag/v3.0.0-rc1) and [3.0.0-rc2](https://github.com/bitcoindevkit/bdk/releases/tag/v3.0.0-rc2)) were published this quarter, bringing the team close to a stable 3.0 release. We encouraged library integrators to begin testing against the release candidates and provide feedback. -- **New migration utilities for older BDK wallets.** We've updated and simplified the workflow required to migrate older (0.X) BDK wallets into their 2.X and 3.X counterparts! See our docs on this in migration section of the [Book of BDK](https://bookofbdk.com/getting-started/migrating/). -- **Release 0.23.3 of `bdk_chain`.** This patch release addresses issues identified by downstream users and improves internal consistency ahead of the 3.0 release. -- **Releases 2.3.0 and 2.3.1 of `bdk-ffi`.** The language bindings libraries—covering Swift, Android, JVM, and Python—received two releases this quarter, continuing to track improvements in the underlying Rust libraries. Work is underway to release the 3.0 version in the next quarter! -- **`bdk-dart` and `bdk-rn` ready for testing.** Both the [Dart/Flutter](https://github.com/bitcoindevkit/bdk-dart) and [React Native](https://github.com/bitcoindevkit/bdk-rn) libraries have reached a stage where they are ready for integration testing in users' applications. If you are building a mobile bitcoin wallet, now is a great time to try them out and share your feedback with the team. -- **Maintainership and library tiers finalized across the org.** All libraries under the [bitcoindevkit GitHub organization](https://github.com/bitcoindevkit) now have formally defined support tiers, as well as designated primary and secondary maintainers. This makes it easier for contributors and integrators to understand the maturity and ownership of each project at a glance. -- **Devkit Wallet revamped.** The [Devkit Wallet](https://github.com/bitcoindevkit/devkit-wallet) received a significant update this quarter with a fully revamped UI and a new default chain source: compact block filters via [Kyoto](https://crates.io/crates/bip157). This makes it a great reference app for developers looking to see BDK and compact block filters working together in a real Android wallet. -- **Release 0.22.2 of `bdk_esplora`.** This patch release brings fixes and improvements to the Esplora chain source client, used by wallets that rely on an Esplora backend for chain data. -- **Release of bdk-cli 3.0.0.** We released version 3.0 of our sample command line wallet! Tons of new features, including configuration files that make it easier to work with the wallet, and support for Payjoin! - -## New Associate Members - -We're pleased to welcome two new associate members to the BDK Foundation this quarter: - -- **[Bitshala](https://bitshala.org/)** — a Bitcoin-focused education initiative helping developers in the Global South learn to build on Bitcoin. -- **[Satoshi Pacioli](https://satoshi-pacioli.com/)** — bringing double-entry Bitcoin accounting tools to the ecosystem. - -Their support helps sustain the development of open-source Bitcoin infrastructure for everyone. - -## BDK in the Wild - -Q1 brought a new wallet integration to our [adoption page](https://bitcoindevkit.org/adoption/): - -- [Arké](https://arkewallet.com/) - -We're always happy to see new projects choosing BDK as their wallet foundation. If your project is building with BDK and isn't listed yet, let us know! diff --git a/docs/blog/2026_q2_new_bdkf_members.md b/docs/blog/2026_q2_new_bdkf_members.md deleted file mode 100644 index fae7304fcc..0000000000 --- a/docs/blog/2026_q2_new_bdkf_members.md +++ /dev/null @@ -1,37 +0,0 @@ -# 2026 Q2 New BDK Foundation Members - -:lucide-pen-tool:   [`Steve Myers`](https://github.com/notmandatory) -:lucide-calendar-1:   `June 1, 2026` ---- - -The Bitcoin Dev Kit (BDK) Foundation is happy to announce two new corporate members joining us in Q2 2026 - [Satoshi Patcioli](https://satoshipacioli.com) and [mempool.space](https://mempool.space)! A big thanks to our new Foundation members as well as our continuing members [Spiral](https://spiral.xyz/), [OpenSats](https://opensats.org/), [AnchorWatch](https://www.anchorwatch.com/), [CleanSpark](https://www.cleanspark.com/), and [Proton Foundation](https://proton.me/foundation) for supporting our mission. Corporate members' yearly dues fund the small team of open source developers who maintain the core BDK libraries and related, supporting FOSS projects. - -The BDK Foundation is a US non-profit organization with the mission to promote the common business interests of the Bitcoin software development industry. To that end, the Foundation focuses on enhancing the capabilities of businesses, individuals, and organizations who use Bitcoin related technology in their products and services. The primary way the Foundation carries out this mission is through our stewardship of free and open source (FOSS) tools such as the BDK suite of libraries and related training material. The Foundation also hosts forums for developer mentoring and networking, and in-person talks and workshops. - -We invite all businesses big or small who support the BDK Foundation's mission to join us as corporate members. Please see our [membership](/foundation/become-a-member/) page for more information or contact us at [hello@bitcoindevkit.org](https://mailto:hello@bitcoindevkit.org/). - -
- -
- -- ### Satoshi Pacioli Accounting - - --- - - Satoshi Pacioli Accounting - - Satoshi Pacioli Accounting bridges traditional & bitcoin-specific accounting, providing expert help for tax compliance, financial ops & complex processes. - - [:octicons-arrow-right-24: Website](https://satoshipacioli.com) - -- ### mempool.space - - --- - - mempool.space - - Mempool.space is the leading open-source Bitcoin blockchain explorer and mempool visualizer. It provides real-time transaction tracking, fee estimation, and network statistics used by millions worldwide. - - [:octicons-arrow-right-24: Website](https://mempool.space) - -
diff --git a/docs/blog/2026_q2_update.md b/docs/blog/2026_q2_update.md deleted file mode 100644 index c19849bbf5..0000000000 --- a/docs/blog/2026_q2_update.md +++ /dev/null @@ -1,53 +0,0 @@ -# 2026 Q2 Update: What Have We Been Up To? - -:lucide-pen-tool:   [`thunderbiscuit`](https://github.com/thunderbiscuit) -:lucide-calendar-1:   `Aug 27, 2026` - ---- - -Q2 2026 is the quarter the 3.0 line landed. `bdk_wallet` 3.0.0 shipped in April, 3.1.0 followed in June, and the 3.0 API made its way out to every language we support: Swift, Kotlin, Android, JVM, Python, React Native, and Dart. Along the way we welcomed two new corporate members to the BDK Foundation, added two new grantees to the team, and published the first release of a brand new library. - -Here are some of the notable releases and changes over Q2 to the software libraries we maintain: - -- **`bdk_wallet` 3.0.0 is out!** [The 3.0.0 release](https://github.com/bitcoindevkit/bdk_wallet/releases/tag/v3.0.0) brings persistent UTXO locking, structured wallet events, the adoption of `NetworkKind` throughout the codebase, support for importing and exporting the Caravan wallet format, and a migration utility for SQLite databases created before version 1.0. -- **Release 3.1.0 of `bdk_wallet`.** [This release](https://github.com/bitcoindevkit/bdk_wallet/releases/tag/v3.1.0) adds the `Wallet::sign_with_signers` method, which gives callers control over the signing process by accepting a custom list of signers, as well as a `LoadParams::two_path_descriptor` method for validating descriptors loaded from persistence. It also carries a long list of bug fixes, and we added a `SECURITY.md` document to the repository with instructions on how to report vulnerabilities. Eight developers made their first contribution to the library in this release! -- **Release 2.4.0 of `bdk_wallet`.** For teams not ready to jump to 3.0 yet, [the 2.4.0 release](https://github.com/bitcoindevkit/bdk_wallet/releases/tag/wallet-2.4.0) backports the pre-1.0 SQLite migration helper and the new event tracking methods to the 2.x line. -- **Release 3.0.0 of the language bindings.** [bdk-ffi 3.0.0](https://github.com/bitcoindevkit/bdk-ffi/releases/tag/v3.0.0) brings the 3.0 API to Swift, Kotlin, Android, JVM, and Python. Highlights include the new `NetworkKind` type, locked outpoints and their persistence, the wallet event helpers, a much more complete set of `Descriptor` constructors, transaction builder controls for sighash and transaction ordering, and optional timeout and retry parameters on the Electrum client. -- **`bdk-rn` 1.0.0.** Our [React Native library](https://github.com/bitcoindevkit/bdk-rn/releases/tag/v1.0.0) reached 1.0, built on the 3.0.0 API of bdk-ffi. -- **`bdk-dart` release candidates.** The [Dart/Flutter bindings](https://github.com/bitcoindevkit/bdk-dart) published their first two release candidates on the road to 1.0, tracking bdk-ffi 3.0.0, publishing to pub.dev, and adding Android 16 KB page-size alignment so the native library meets Google Play requirements. If you are building a Flutter bitcoin wallet, this is a great moment to try it out and send us feedback. -- **Release 0.2.0 of `bdk-tx`.** [This release](https://github.com/bitcoindevkit/bdk-tx/releases/tag/0.2.0) is a big one for our transaction building library: a reworked change output API through the new `ChangeScript` type, improved timelock and spendability handling, anti-fee-sniping support (BIP326), per-input sequence control, and better encapsulation of the selection result. -- **Release 0.25.0 of `rust-electrum-client`.** [The 0.25.0 release](https://github.com/bitcoindevkit/rust-electrum-client/releases/tag/0.25.0) implements Electrum protocol v1.6, adds dynamic authorization support, simplifies the cargo features, and relicenses the crate under MIT/Apache-2.0. -- **Releases 0.16.0 and 0.17.0 of `bdk-kyoto`.** Our compact block filters chain source was updated to track the latest releases of the [bip157](https://crates.io/crates/bip157) crate. -- **A new library: `bdk-message-signer`.** [Version 0.1.0](https://github.com/bitcoindevkit/bdk-message-signer) of a new library shipped this quarter, providing a script-generic signed message format for proving fund availability or committing to a message. -- **The Book of BDK is on 3.0.** All Rust, Swift, Kotlin, and Python examples have been updated to the 3.0.0 API, the Kyoto example now uses the 0.17.0 API, and we published [release notes](https://bookofbdk.com/release-guide/3.1/notes/) for the 2.4, 3.0, and 3.1 releases. The Python examples moved to the `uv` build tool and the Kotlin examples to the Amper toolchain. -- **Example wallets on 3.0.** Our sample Android app, the [Devkit Wallet](https://github.com/bitcoindevkit/devkit-wallet), followed the release candidates through May and now runs bdk-android 3.0.0, and the [BDK Swift Example Wallet](https://github.com/bitcoindevkit/BDKSwiftExampleWallet) was updated to bdk-ffi 3.0.0 as well. -- **A new website.** The website you're reading this on was rebuilt on [Zensical](https://zensical.org/) and deployed in April, with a new logo, icons, and favicon. We also published a PGP key for [security@bitcoindevkit.org](../foundation/pgp.md) so that vulnerabilities can be reported to us privately. - -## New Foundation Members - -Two new corporate members joined the BDK Foundation this quarter (see the [full announcement](2026_q2_new_bdkf_members.md)): - -- **[Satoshi Pacioli Accounting](https://satoshipacioli.com)** — bridging traditional and bitcoin-specific accounting, with expert help for tax compliance and financial operations. -- **[mempool.space](https://mempool.space)** — the leading open-source bitcoin blockchain explorer and mempool visualizer. - -Corporate members' yearly dues fund the small team of open source developers who maintain the core BDK libraries and the supporting FOSS projects around them. Thank you! - -## Our Grantees in Action - -Two new grantees joined the team this quarter, both funded by [Btrust](https://www.btrust.tech/): - -- **[John Osezele](https://github.com/Johnosezele)** is a mobile engineer working on the Dart language bindings. He is a co-maintainer of [bdk-dart](https://github.com/bitcoindevkit/bdk-dart) and leads the development of the [BDK Dart Wallet](https://github.com/bitcoindevkit/bdk-dart/tree/main/bdk_demo), a demo app built in Flutter. -- **[Abiodun Awoyemi](https://github.com/aagbotemi)** works on wallet infrastructure and transaction building. He is a co-maintainer of [bdk-tx](https://github.com/bitcoindevkit/bdk-tx) and leads the development of [bdk-message-signer](https://github.com/bitcoindevkit/bdk-message-signer). - -See our [grantees page](../foundation/grantees.md) for the full roster of developers funded through the Foundation. - -## BDK in the Wild - -Q2 saw new projects integrating BDK into their software and being added to our [adoption page](../adoption/all.md): - -- [Grimm App](https://usegrimm.app/) — a self-custodial bitcoin wallet supporting on-chain and Lightning payments. -- [Cyberkrill](https://github.com/douglaz/cyberkrill) — a comprehensive CLI toolkit for Bitcoin and Lightning Network operations, written in Rust. -- [Tetrapolar](https://tetrapolar.com) — bitcoin-native settlement for global trade. -- [Ibis Wallet](https://github.com/aeonBTC/IbisWallet) — Self-custody modular Bitcoin wallet built for power users, with a focus on privacy and customizability. - -We're always happy to see new projects choosing BDK as their wallet foundation. If your project is building with BDK and isn't listed yet, let us know! diff --git a/docs/blog/bdk_core_pt1.md b/docs/blog/bdk_core_pt1.md deleted file mode 100644 index bd42966bdb..0000000000 --- a/docs/blog/bdk_core_pt1.md +++ /dev/null @@ -1,308 +0,0 @@ -# `bdk_core`: a new architecture for the Bitcoin Dev Kit - -:lucide-pen-tool:   [`Lloyd Fournier`](https://github.com/LLFourn) -:lucide-calendar-1:   `May 9, 2022` ---- - -The Bitcoin Devkit (BDK) lets you do a lot of useful things through convenient high level -abstractions. It works great when these abstractions map nicely onto what you are trying to do. My -goal is to develop a new `bdk_core` library for when they don't. I want `bdk_core` to expose all the -useful *mechanisms* that BDK has inside it without them being tied to any particular usage *policy* -and with very minimal dependencies. - -The `bdk_core` idea is still "in the lab". We're not sure yet whether `bdk_core` will just be what's -left of `bdk` once we spin off all the components that have extra dependencies into their own crates -and refine it a bit. In that case `bdk_core` will just be called `bdk v1.0.0` or something. Or it might -be that `bdk` lives on with its current APIs and uses stuff `bdk_core` to implement it internally. - -## The separation of policy and mechanism - -My guiding principle for `bdk_core` is the *separation of policy and mechanism*. This is -what I mean by these terms: - -- *mechanism*: How you do a particular thing. Mechanism code is functional and doesn't change much. -- *policy*: What you want to do. Policy code composes mechanisms to achieve something in - an application. - -Here's a nice passage about why the designers of the [X window system] applied this principle. X has -been around since 1984 and doesn't look like it's going anywhere so it probably has a lot to teach us. -From *[The Art of UNIX Programming]*: - -> ...we observed that the designers of X made a basic decision to implement “mechanism, not policy”—to -> make X a generic graphics engine and leave decisions about user-interface style to toolkits and -> other levels of the system. We justified this by pointing out that policy and mechanism tend to -> mutate on different timescales, with policy changing much faster than mechanism. Fashions in the -> look and feel of GUI toolkits may come and go, but raster operations and compositing are forever. - -> Thus, hardwiring policy and mechanism together has two bad effects: It makes policy rigid and -> harder to change in response to user requirements, and it means that trying to change policy has a -> strong tendency to destabilize the mechanisms. - -> On the other hand, by separating the two we make it -> possible to experiment with new policy without breaking mechanisms. We also make it much easier to -> write good tests for the mechanism (policy, because it ages so quickly, often does not justify the -> investment). - - * [ ] > This design rule has wide application outside the GUI context. In general, it implies that we -> should look for ways to separate interfaces from engines. - -You'll notice we have a similar situation in Bitcoin engineering. We have mechanism code like -signing algorithms, key derivation, transaction construction logic, etc., that don't change much. But -how these compose together in applications changes quickly over time and between applications. - -The main culprit of policy and mechanism conflation in `bdk` is the main [`Wallet`] type. -Wallets do all of the following: - -1. Store one or two descriptors (external and optional internal). -2. Keep track of which addresses you've given out so you only give out fresh ones from each descriptor. -3. Keep a list of transactions associated with the addresses in the wallet. -4. Given a source of blockchain data it can update its internal list of transactions. -5. Given some parameters it can build a PSBT from transaction outputs. -6. Given a PSBT it can sign it with its [`Signers`][`Signer`]. - -All of that is very useful but it is bound together with the particular policies and opinions of `Wallet`. -If `Wallet`'s policy is not your policy it's going to be tricky to get it to do what you want. -Here are some examples: - -1. In order to control how the `Wallet` will select coins for a transaction internally you have to - pass in something implementing the [`CoinSelectionAlgorithm`] trait. A coin selection algorithm - is clearly mechanism code but the policy of `Wallet` restricts that mechanism's interface. We - have [very old issues](https://github.com/bitcoindevkit/bdk/issues/281) related to what the - interface of this trait should be and we don't have a clear way forward. In `bdk_core` I want to - purely provide the coin selection mechanisms for figuring out whether you need to select more - UTXOs or whether you need a change output etc. How you use that mechanism will be up to you. -2. Another trait that has a similar structure is the [`Signer`] trait. You have to pass in signers - so your wallet can sign PSBTs but you have little control over how the wallet chooses which - signers to use in any given situation. Right now the wallet will just iterate through all the - signers and ask them to sign. This is not always appropriate. In `bdk_core` I want to provide - functions for populating PSBTs given something that can sign. You'll be in control of when they - get called. - -## A syncing mechansim without the policy - -Syncing in `bdk` is the place where the design of `Wallet` is most restrictive. The [`WalletSync`] -trait forces you to sync all addresses in a wallet in one big batch. But this is not always what you -want to do. I spoke to a developer who wanted to sync his wallet slowly over time with each address -being queried over a different Tor connection. It would be really difficult to implement -`WalletSync` with such a strategy. Another example where `WalletSync` isn't the right fit is the -[Sensei] project which uses BDK but incrementally updates the database whenever new information -comes in from the blockchain. - -Even if syncing all addresses at the same time is roughly what you want to do `WalletSync` still -gets in the way since it defines whether you do it synchronously or asynchrononusly. Applications -can control this through `bdk`'s `async-interface` feature flag which internally changes the trait -definition through macros. Another annoyance is that when using `async-interface` the future that -gets returned from `WalletSync` [cannot be `Send`](https://github.com/bitcoindevkit/bdk/issues/165) -because of how `Wallet` handles database mutability internally, meaning you can't spawn the future -into a new thread. - -### A general syncing mechanism - -So what is the most general syncing mechanism that solves these problems? These are the things I -think it has to do regardless of where the blockchain data comes from or how it's stored: - -1. Generate and store addresses. -2. Index transaction data, e.g. transaction outputs we own, when/if they were spent, etc. -3. Keep track of which addresses have been given out and which have been used. -4. Be able to "roll back" our view of the above data if a reorg makes some of it stale. -5. Keep track of transactions related our addresses in our mempool. - -Let's talk about how to implement a mechanism that does all that. - -### How to store and index transactions - -Different persistent storage backends have different APIs and their own indexing strategies. That's -why the [`Database`] trait exists in BDK, to make a clean API to the different storage engines. It's -important to note that the database in BDK only holds public data that could always be retrieved -from the chain. It's just a cache. Despite this we support different backends. Right now it is a -lot of work to add a new index to the data since you have to add it to every backend and you might have -to apply schema changes (we still [don't have a standard approach to -this](https://github.com/bitcoindevkit/bdk/issues/359)). - -Thomas Eizinger [suggested](https://github.com/bitcoindevkit/bdk/issues/165#issuecomment-1047483895) -doing everything in memory and only writing to persistent storage when it was convenient. It took me -some time but I came around to this idea. It would allow us to get rid of the `Database` trait (at -least at the `bdk_core` level) and greatly simplify what the persistent storage layer has to do. -Whenever the data is loaded from persistent storage we can just do the indexing in memory and -present it to the application. - -*But wait! Wouldn't this mean we'd use way more memory than we need to?* Yes but memory is cheap. -Consider that if we say the average transaction size is 300 bytes then with all our indexes each -transaction might cost 1kb of memory (pessimistically). This means we could index one thousand -transactions in a single megabyte! My iPhone has 4gb of memory so it could index a million -transactions with plenty of memory to spare. *But what if some users can't afford an iPhone?* Then -they also couldn't have afforded to have made a million Bitcoin transactions! *But what about memory -constrained devices like hardware wallets!?* Those devices typically don't store and retrieve -transactions. They're usually just signing devices. Perhaps one day someone will build a memory -constrained device that needs to do this work but until then I think this is a fine approach to -take. - -For now I'm calling this thing that does the in-memory indexing of transactions related to a single -descriptor a `DescriptorTracker`. Here's a diagram that communicates how I imagine it relates to the -other components. - -![](../assets/blog/descriptor-tracker.jpg) - -### Rolling back, rolling forward and syncing to disk - -State changes in blockchains are clearly delineated. They all happen in blocks! Every view of the -blockchain, whether you're getting it through compact block filters, an electrum server or something -wacky like a utreexo bridge will have a concept of blocks and transactions in them. For a wallet we -only need a very sparse view of the blockchain that includes at which block a set of transactions -existed. That way, if a block disappears we know that all those transactions might disappear too. - -With `bdk_core` I want to introduce the concept of a *checkpoint*, which is a block height and hash and -a set of txids that were present at that height **but not present in the previous checkpoint**. In -this way we create an append-only data structure that can easily be rolled back to a previous height -if there is a reorg. After rolling back we can then roll forward and apply the new blocks. - -Here's an example of how this idea works: - -![](../assets/blog/checkpoints.jpg) - -There are a few edge cases I'd like to cover: - -1. What if when gathering new data from the chain to update a `DescriptorTracker` we find an old transaction that belongs to an earlier checkpoint that we had missed form our earlier syncs? -2. What if when we go to write to persistent storage from a `DescriptorTracker` we find that it has some transactions the tracker doesn't? Should we try and reconcile the two sets of transactions? - -I think the correct approach is to treat the chain data as the source of truth for the -`DescriptorTracker` and the `DescriptorTracker` as the source of truth for persistent storage. That -is in the case of (1) we should just rollback the `DescriptorTracker` and insert the old but -recently discovered transaction in the right place. In the case of (2) we should roll back the -persistent storage to the point where it differs and apply changes from there. This implies that you -should only keep one instance of a `DescriptorTracker` for a descriptor in your application and only -update persistent storage by first applying the changes to the tracker. - -## Examples - -Here are some examples of what I think this may end up looking like in code. Keep in mind that if -this looks complicated it will probably be more complicated in practice! This doesn't mean that we -can't create simplifying abstractions and tools around these primitives to cover common policies. I hope we can implement `Wallet` with `DescriptorTracker`s internally. - -### Doing an initial sync of a descriptor that may already contain coins - -When we first sync a descriptor that may already contain coins we want to iterate over all the -scripts of the wallet and then stop if there's a big enough gap (e.g. 20). In this example we use an -stateless [esplora-like API](https://mempool.space/docs/api/rest). - -```rust -// create a descriptor tracker the external addresses of a BIP86 key -let mut tracker = DescriptorTracker::new("tr([73c5da0a/86'/0'/0']xpub6BgBgsespWvERF3LHQu6CnqdvfEvtMcQjYrcRzx53QJjSxarj2afYWcLteoGVky7D3UKDP9QyrLprQ3VCECoY49yfdDEHGCtMMj92pReUsQ/0/*)"); - -let esplora = bdk_esplora::Client::new(); -let update = esplora.fetch_related_transactions(bdk_esplora::Params { - // iterate over all addresses in a descriptor - scripts: Some(tracker.iter_scripts()), - // stop if you find a gap of 20 unused addresses - stop_gap: Some(20), - ..Default::default() -}).await?; - -tracker.apply_update(update)?; - -// now we want to persist this disk -let db_update = tracker.generate_update(Params { - start_checkpoint: None, -}); - -// Note that the db_update type is the same as the `update` above. -my_db.apply_update(db_update); -``` - -### Doing a sync of a wallet after you already have sync'd - -Now imagine you just want to check if any UTXOs in your wallet have been spent. In this case we've -already sync'd before so we need to load that data into the tracker from disk first (rather than -going straight to the blockchain). Then we just ask esplora for transactions related to these -transaction outputs. - -```rust -// create a descriptor tracker the external addresses of a BIP86 key -let mut tracker = DescriptorTracker::new("tr([73c5da0a/86'/0'/0']xpub6BgBgsespWvERF3LHQu6CnqdvfEvtMcQjYrcRzx53QJjSxarj2afYWcLteoGVky7D3UKDP9QyrLprQ3VCECoY49yfdDEHGCtMMj92pReUsQ/0/*)"); - -let init_update = my_db.generate_update(Params { - checkpoint: None -}); - -// get up to speed with what was on disk. -tracker.apply_update(init_update); -// get the latest checkpoint -let checkpoint = tracker.get_checkpoint(0); - -let esplora = bdk_esplora::Client::new(); - -// Fetch transactions spending any utxos we have -let update = esplora.fetch_related_transactions( bdk_esplora::Params { - checkpoint: Some(checkpoint), - tx_outs: Some(tracker.iter_unspent()), - ..Default::default() -}).await?; - -match update { - Ok(update) => { - tracker.apply_update(update)?; - // now we want to persist this disk - let db_update = tracker.generate_update(Params { - // this call could fail if tracker no longer has this checkpoint. - // In this case we'd ask persistent_storage for an earlier checkpoint and try again. - start_checkpoint: persistent_storage.get_checkpoint(0), - }); - - persistent_storage.apply_update(db_update); - } - Err(bdk_esplora::Error::StaleCheckpoint) => { - // here we should call fetch related transactions with an earlier checkpoint. - // In practice this logic will be called in a loop - } -} -``` - -### Updating state when you get the data in real time - -If you have an event based view of the blockchain that feeds you block connected or block -disconnected events then I imagine the API would look something like this. -There's quite a bit left out here but I hope you get the idea. - -```rust -// create a descriptor tracker the external addresses of a BIP86 key -let mut tracker = DescriptorTracker::new("tr([73c5da0a/86'/0'/0']xpub6BgBgsespWvERF3LHQu6CnqdvfEvtMcQjYrcRzx53QJjSxarj2afYWcLteoGVky7D3UKDP9QyrLprQ3VCECoY49yfdDEHGCtMMj92pReUsQ/0/*)"); - - -let blockchain_events = { /* get a Stream of blockchain block connected/disconnected events */ }; - -loop { - let blockchain_event = blockchain_events.next().await; - match blockchain_event { - BlockChainEvent::Connected(new_block) => { - match tracker.apply_block(new_block) => { - Ok(modified) => if modified { - // update persistent storage from tracker - } - Err(ApplyBlockError::OutOfOrder) => { - // the block event we got was not the next block we expected. - // How to recover from this will depend on the application and block source - } - }, - BlockchainEvent::Disconnected((disconnected_height, disconnected_hash)) => { - // this might invalidate a checkpoint - tracker.disconnect_block(disconnected_height, disconnected_hash); - // Now apply to persistent storage - } - } - } -} -``` - -## Feedback - -The best way to give feedback on this would be to comment on the [pull request](https://github.com/bitcoindevkit/bitcoindevkit.org/pull/100) for this blog post. -Thanks in advance. - -[X window system]: https://en.wikipedia.org/wiki/X_Window_System -[The Art of UNIX Programming]: https://en.wikipedia.org/wiki/The_Art_of_Unix_Programming -[`Wallet`]: https://docs.rs/bdk/latest/bdk/wallet/struct.Wallet.html -[`CoinSelectionAlgorithm`]: https://docs.rs/bdk/latest/bdk/wallet/coin_selection/trait.CoinSelectionAlgorithm.html -[`Signer`]: https://docs.rs/bdk/latest/bdk/wallet/signer/index.html -[`WalletSync`]: https://docs.rs/bdk/latest/bdk/blockchain/trait.WalletSync.html -[Sensei]: https://l2.technology/sensei -[`Database`]: https://docs.rs/bdk/latest/bdk/database/trait.Database.html diff --git a/docs/blog/bindings-scope.md b/docs/blog/bindings-scope.md deleted file mode 100644 index caf7957f70..0000000000 --- a/docs/blog/bindings-scope.md +++ /dev/null @@ -1,38 +0,0 @@ -# BDK's Scope and Approach to Rust Bindings - -:lucide-pen-tool:   [`thunderbiscuit`](https://github.com/thunderbiscuit) -:lucide-calendar-1:   `Jun 2, 2023` ---- - -**tldr;** _we can't produce and maintain bindings for all Rust crates we get requests for, but we are working to help others build their own bindings by (1) making our architecture composable and reusable, and (2) building strong examples and documentation on how to do it for other crates._ - -Over the past 2 years, the Bitcoin Development Kit team has been successful at building and releasing language bindings for our Rust library. In particular, over the past 18 months we have locked in and solidified our approach for the iOS, Android, Kotlin, Java, and Python bindings by using a Rust library called [Uniffi](https://github.com/mozilla/uniffi-rs). - -Over the course of the year, we've had many requests to add to the bindings certain features that are not directly in the Rust BDK library. These request mainly break down into two groups: -1. Features that are part of crates "upstream" of BDK (rust-bitcoin, rust-miniscript) -2. Features that are not but that have Rust crates and would be useful on mobile (payjoin, coinjoin implementations, silent payments, BIP-47) - -## Current architecture - -The current architecture for the BDK bindings is more or less wrapping the bdk, rust-bitcoin, and rust-miniscript crates and exposing an API that allows users to leverage them similarly to how they would BDK in Rust if they were using it in a Rust project. - -While we started with a simplified version of the Rust BDK API, over time users asked for more and more functionality, and exposing some of the underlying rust-bitcoin constructs became important. This makes sense, and indeed users of the bitcoin development kit in Rust have access to all the related APIs by simply importing rust-bitcoin and rust-miniscript, hence our desire to accommodate these use cases as well. However, this is currently done all in one "bindings" library (i.e. if you import `bdk-android` in a project, you'll have access to an API that is mostly bdk-based, but also contains a bit of rust-bitcoin and rust-miniscript). - -## Moving forward: building a family of libraries - -At the same time, other Rust-based libraries started using the uniffi approach (a good example is [ldk-node](https://github.com/lightningdevkit/ldk-node)) to expose bindings. When developing and using those libraries together, it quickly became clear that much of the work was duplicated; both libraries needed access to underlying rust-bitcoin types, but they both exposed their own versions of it. - -Over the coming months, the team is looking at extracting the rust-bitcoin part of the BDK bindings library (bdk-ffi) and publishing that library on [crates.io](https://crates.io/) so as to make it available to others who wish to build Rust bindings using uniffi. - -## Why can't we just build one big BDK library with _everything_ in it? - -1. The short answer to this is that it would simply not be maintainable. If we rely on many underlying Rust crates, we'd need to release patches every time one of the underlying libraries patches a bug. We'd also need to keep them all in sync (what API versions work with what), and we'd be relying on work from teams that may or may not have the capacity to keep their crates up to date. -2. Scope creep. Unless we define a narrow and structured scope for the library, we will forever be handling requests for features that may or may not be feasible to accommodate. -3. Library size. Because one of our primary focus for the bindings is mobile devices, we need to make sure we don't build a library that is too big. This is a more nuanced issue, but it relates to point (2), where too large a scope would eventually produce a library that is potentially not optimal for mobile devices because it attempts to do too much all in one package. - -## Are you looking to build Rust bindings yourself? - -We got your back! The Bitcoin Development Kit team intends to help others in the Rust bitcoin ecosystem build bindings if they wish to. To that effect, we maintain 3 repositories that should help you get going with bindings in no time: -1. **[Uniffi library template](https://github.com/thunderbiscuit/uniffi-bindings-template)**. This is a repository you can fork and start adding code to produce bindings directly for iOS and Android. Included are our custom-made Gradle plugin and Swift release shell scripts, as well as information about the little build quirks you need to know about for smooth releases. -2. **[Uniffi examples](https://github.com/thunderbiscuit/uniffi-examples)**. This repository provides boiled-down examples of APIs exposed using uniffi, with an [accompanying documentation website](https://thunderbiscuit.github.io/uniffi-examples/). Functions, enums, objects, callbacks, multi-libraries, a lot of information and examples to get you started. -3. **[Sandbox library `bitcoin-frontier`](https://github.com/thunderbiscuit/bitcoin-frontier)**. This repository is meant as a sandbox to start developing and testing your own bindings. Simply fork it and start adding code! It comes with a fully working Android app you can leverage to test out whatever bindings you're building. diff --git a/docs/blog/first_bdk_taproot_tx.md b/docs/blog/first_bdk_taproot_tx.md deleted file mode 100644 index fa6ab84eee..0000000000 --- a/docs/blog/first_bdk_taproot_tx.md +++ /dev/null @@ -1,661 +0,0 @@ -# The first BDK Taproot TX: a look at the code (Part 1) - -:lucide-pen-tool:   [`Alekos Filini`](https://github.com/afilini) -:lucide-calendar-1:   `Nov 15, 2021` ---- - -This is the first of a two-parts blog series in which I will try to explain all the changes that I made to BDK (and some of its dependencies) to make our [first Taproot transaction in mainnet][first-mainnet-tx], which also -turned out to be [the first ever use of the new `OP_CHECKSIGADD` opcode][first-ever-use-checksigadd]. - -Hopefully this will give an insight into what kind of changes need to be made to a wallet in order to support spending `P2TR` outputs, both with key-spend and script-spend. BDK actually delegates -most of the hard work to [rust-miniscript], and luckily most of the Taproot code was already implemented by the time I started working on it. I only had to patch a few little bugs here and there, and it ended up -working flawlessly in the end. - -In this first part I will focus on the changes made to our dependencies, [rust-bitcoin] and [rust-miniscript]. In the second part I will talk about BDK itself. - -## Backstory - -On the evening of Thursday, November 11th I was attending our weekly [Satoshi Spritz] meetup in Milan. The activation of Taproot was right around the corner, and naturally that was the main discussion -topic that night. The activation was forecasted for the early afternoon of Sunday, November 14th, a little less than 72h later. - -I began to wonder how hard it would be to patch BDK and add support for Taproot. I knew most of the work had already been done in our main dependencies, [rust-bitcoin] and [rust-miniscript], and so I decided -to challenge myself: could I make it in time for the activation? - -The following day I started digging into the topic. It didn't help that up until that time I only had a rather "high level" idea of how Taproot worked, but luckily all the BIPs were very well written and -straightforward to understand. - -By Friday night (or rather, early Saturday morning) [I had Taproot key-spend working][first-key-spend], which made me pretty optimistic even though the activation date was actually moving closer, now being forecasted for -Sunday *morning*. - -After a few hours of sleep I went back to work and by early Saturday afternoon [I had Taproot script-spend working as well][first-script-spend]. This left me a few hours to coordinate with some friends and [generate a vanity address][vanity-addr] -to deposit funds into temporarily, as we didn't trust sending them to Taproot addresses before the activation (as they were anyone-can-spend according to the pre-activation rules). - -After another pretty short night, I woke up a 5:30 AM on Sunday to monitor the activation. I broadcasted our transactions shortly after 6:00 AM as the activation block was being mined. Unfortunately, the first -three blocks that were enforcing Taproot rules [didn't include any Taproot transaction][no-taproot-transactions-blocks], which indicates that the miners weren't actually running the new Bitcoin Core 22.0 nodes. The fourth block, mined by `Foundry -USA` [included my transaction][my-taproot-transaction] and [a few others][few-other-transactions]. - -In the end our transaction was the third Taproot script-spend in the block, but the first to use the new [`OP_CHECKSIGADD`] opcode, as the two preceding it were respectively [a single-sig][taproot-single-sig] and [a 2-of-2 multisig][taproot-bitgo-multisig] -script, made with with two `OP_CHECKSIG(VERIFY)`s. - -Now, with the context out of the way, we can begin talking about the code! - -## rust-bitcoin - -The first dependency I had to update was [rust-bitcoin]. Most of the taproot stuff were already merged in `master` (altough they hadn't been released yet). One notable missing part was the support for [`BIP371`], -which is an extension of [`BIP174`], aka the `Partially Signed Bitcoin Transaction` BIP. This new BIP defines a few new fields that are required to properly handle Taproot transactions. - -Luckily most of the work had already been done by [sanket1729], so I forked his branch and made only few very minor changes, just to expose a structure that I will have to use later which in his code wasn't public. - -You can find all the commits mentioned here in [my rust-bitcoin `taproot-testing` branch][rust-bitcoin-taproot-testing]. - -``` -$ git diff 187234f f830df9 -``` - -```diff -diff --git a/src/lib.rs b/src/lib.rs -index 87d9c36..d5e5802 100644 ---- a/src/lib.rs -+++ b/src/lib.rs -@@ -54,7 +54,6 @@ - #![deny(unused_mut)] - #![deny(dead_code)] - #![deny(unused_imports)] --#![deny(missing_docs)] - #![deny(unused_must_use)] - #![deny(broken_intra_doc_links)] - -diff --git a/src/util/taproot.rs b/src/util/taproot.rs -index 674eeee..3d56cbc 100644 ---- a/src/util/taproot.rs -+++ b/src/util/taproot.rs -@@ -440,7 +440,7 @@ impl TaprootBuilder { - // Internally used structure to represent the node information in taproot tree - #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] - #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] --pub(crate) struct NodeInfo { -+pub struct NodeInfo { - /// Merkle Hash for this node - pub(crate) hash: sha256::Hash, - /// information about leaves inside this node -@@ -448,8 +448,12 @@ pub(crate) struct NodeInfo { - } - - impl NodeInfo { -+ pub fn hash(&self) -> &sha256::Hash { -+ &self.hash -+ } -+ - // Create a new NodeInfo with omitted/hidden info -- fn new_hidden(hash: sha256::Hash) -> Self { -+ pub fn new_hidden(hash: sha256::Hash) -> Self { - Self { - hash: hash, - leaves: vec![], -@@ -457,7 +461,7 @@ impl NodeInfo { - } - - // Create a new leaf with NodeInfo -- fn new_leaf_with_ver(script: Script, ver: LeafVersion) -> Self { -+ pub fn new_leaf_with_ver(script: Script, ver: LeafVersion) -> Self { - let leaf = LeafInfo::new(script, ver); - Self { - hash: leaf.hash(), -@@ -466,7 +470,7 @@ impl NodeInfo { - } - - // Combine two NodeInfo's to create a new parent -- fn combine(a: Self, b: Self) -> Result { -+ pub fn combine(a: Self, b: Self) -> Result { - let mut all_leaves = Vec::with_capacity(a.leaves.len() + b.leaves.len()); - for mut a_leaf in a.leaves { - a_leaf.merkle_branch.push(b.hash)?; // add hashing partner - -``` - -There isn't much to explain here: I disabled the `missing_docs` lint so that the compiler wouldn't complain about the new public methods that aren't documented. -Then, I added a getter for the `hash` field of `NodeInfo` and made the struct itself and a bunch of methods public. - -We will use this structure later to recover the merkle root of a Taproot script tree, given one leaf and the other "hidden" branches. - -## rust-miniscript - -Moving on to [rust-miniscript]: once again, most of the work required to support Taproot had already been done, but this time I was working with very "early" prototype-like code, so I was prepared to -make some changes to the code to get it to work how I wanted. - -Instead of showing one big diff I will talk about the commits individually, which I think will help making more clear what I was doing. - -Once again, you can find all the commits referenced here in [my rust-miniscript `taproot` branch][rust-miniscript-taproot]. - -``` -$ git show 34cf15b -``` - -```diff -commit 34cf15b3aac1d8c2693af1b9749b888f3f29e510 -Author: Alekos Filini -Date: Fri Nov 12 12:06:35 2021 +0100 - - Fix TapTree iter depth - -diff --git a/src/descriptor/tr.rs b/src/descriptor/tr.rs -index 79d3c05..314c7f4 100644 ---- a/src/descriptor/tr.rs -+++ b/src/descriptor/tr.rs -@@ -65,7 +65,7 @@ impl TapTree { - - /// Iterate over all miniscripts - pub fn iter(&self) -> TapTreeIter { -- TapTreeIter { stack: vec![self] } -+ TapTreeIter { stack: vec![(0, self)] } - } - - // Helper function to translate keys -@@ -262,7 +262,7 @@ pub struct TapTreeIter<'a, Pk: MiniscriptKey> - where - Pk: 'a, - { -- stack: Vec<&'a TapTree>, -+ stack: Vec<(usize, &'a TapTree)>, - } - - impl<'a, Pk> Iterator for TapTreeIter<'a, Pk> -@@ -273,13 +273,13 @@ where - - fn next(&mut self) -> Option { - while !self.stack.is_empty() { -- let last = self.stack.pop().expect("Size checked above"); -+ let (depth, last) = self.stack.pop().expect("Size checked above"); - match &*last { - TapTree::Tree(l, r) => { -- self.stack.push(&r); -- self.stack.push(&l); -+ self.stack.push((depth + 1, &r)); -+ self.stack.push((depth + 1, &l)); - } -- TapTree::Leaf(ref ms) => return Some((self.stack.len(), ms)), -+ TapTree::Leaf(ref ms) => return Some((depth, ms)), - } - } - None -``` - -`TapTreeIterator` is an iterator that goes through a `TapTree` and yields a `(depth, node)` pair. This is then fed to [`TaprootBuilder`][taproot-builder-iter], which returns an error if trying to insert nodes -in [an order that is not DFS][order-that-is-not-dfs]. - -The way the depth was computed before made the builder always fail for non-trivial trees (i.e. more than 1 node). - -Here I decided to play the safe card, and just keep track of the depth explicitly: I think there might be a way to compute the depth just knowing the `self.stack.len()` (assuming the tree has a specific structure, -which I'm not sure applies here), but anyway I didn't have much time to think about it and I just went for the "dumb but idiot-proof" way which ended up working fine. - -``` -$ git show f4a3459 -``` - -```diff -commit f4a3459128e37ca0c2701b8b6da064d4952296ff -Author: Alekos Filini -Date: Sat Nov 13 14:15:52 2021 +0100 - - Switch rust-bitcoin rev - -diff --git a/Cargo.toml b/Cargo.toml -index 12825e8..8240024 100644 ---- a/Cargo.toml -+++ b/Cargo.toml -@@ -17,7 +17,7 @@ rand = ["bitcoin/rand"] - - [dependencies] - # bitcoin = "0.27" --bitcoin = {git = "https://github.com/sanket1729/rust-bitcoin", branch = "taproot_psbt"} -+bitcoin = { git = "https://github.com/afilini/rust-bitcoin.git", branch = "taproot-testing" } - - [dependencies.serde] - version = "1.0" -``` - -Trivial commit, switch to [my fork of rust-bitcoin][rust-bitcoin-taproot-testing] so that I can make changes if necessary. - -``` -$ git show 0446b16 -``` - -```diff -commit 0446b1631cec9f7118d46f0f4c94ccd20de29f94 -Author: Alekos Filini -Date: Sat Nov 13 14:25:18 2021 +0100 - - Parse x-only keys - -diff --git a/src/descriptor/key.rs b/src/descriptor/key.rs -index 4108d00..b7f90b5 100644 ---- a/src/descriptor/key.rs -+++ b/src/descriptor/key.rs -@@ -283,9 +283,9 @@ impl FromStr for DescriptorPublicKey { - - fn from_str(s: &str) -> Result { - // A "raw" public key without any origin is the least we accept. -- if s.len() < 66 { -+ if s.len() < 64 { - return Err(DescriptorKeyParseError( -- "Key too short (<66 char), doesn't match any format", -+ "Key too short (<64 char), doesn't match any format", - )); - } - -@@ -301,6 +301,14 @@ impl FromStr for DescriptorPublicKey { - derivation_path, - wildcard, - })) -+ } else if key_part.len() == 64 { -+ // x-only pubkey, prefix it with `02` -+ let key = bitcoin::PublicKey::from_str(&format!("02{}", key_part)) -+ .map_err(|_| DescriptorKeyParseError("Error while parsing x-only public key"))?; -+ Ok(DescriptorPublicKey::SinglePub(DescriptorSinglePub { -+ key, -+ origin, -+ })) - } else { - if key_part.len() >= 2 - && !(&key_part[0..2] == "02" || &key_part[0..2] == "03" || &key_part[0..2] == "04") -diff --git a/src/lib.rs b/src/lib.rs -index e168b16..3a2335e 100644 ---- a/src/lib.rs -+++ b/src/lib.rs -@@ -95,8 +95,6 @@ - #![deny(non_snake_case)] - #![deny(unused_mut)] - #![deny(dead_code)] --#![deny(unused_imports)] --#![deny(missing_docs)] - - pub extern crate bitcoin; - #[cfg(feature = "serde")] -``` - -This, I'm not really sure of: Taproot uses x-only public keys, which means that the first byte (which is usually a `03` or a `02`) that indicates the parity of the EC point is completely dropped, and it's implicit -that the point is even (= `02`). Check out [`BIP340`] for a much better explanation. - -So here when I find a string that is only 64 characters long I will assume it's an x-only pubkey, and I will parse it as a normal `bitcoin::PublicKey` by prefixing it with `02`. - -I guess one alternative could have been to try and parse it as a `schnorr::PublicKey` and then "convert" it to a `ecdsa::PublicKey` which should be supported, but once again I just wanted to get it done quickly and -this worked fine. - -I also disabled the `unused_imports` and `missing_docs` lint so that the compiler wouldn't whine too much. - -``` -$ git show 87316ff -``` - -```diff -commit 87316fffd06ab3bdf300fd1a958ddaa2789a6696 -Author: Alekos Filini -Date: Sat Nov 13 14:26:01 2021 +0100 - - Parse `tr()` descriptors - -diff --git a/src/descriptor/mod.rs b/src/descriptor/mod.rs -index 06d98e1..4190786 100644 ---- a/src/descriptor/mod.rs -+++ b/src/descriptor/mod.rs -@@ -610,6 +610,7 @@ where - ("wpkh", 1) => Descriptor::Wpkh(Wpkh::from_tree(top)?), - ("sh", 1) => Descriptor::Sh(Sh::from_tree(top)?), - ("wsh", 1) => Descriptor::Wsh(Wsh::from_tree(top)?), -+ ("tr", _) => Descriptor::Tr(Tr::from_tree(top)?), - _ => Descriptor::Bare(Bare::from_tree(top)?), - }) - } -diff --git a/src/expression.rs b/src/expression.rs -index 1cef614..11a68d3 100644 ---- a/src/expression.rs -+++ b/src/expression.rs -@@ -100,7 +100,12 @@ impl<'a> Tree<'a> { - - sl = &sl[n + 1..]; - loop { -- let (arg, new_sl) = Tree::from_slice_helper_round(sl, depth + 1)?; -+ let (arg, new_sl) = if sl.contains('{') { -+ Tree::from_slice_helper_curly(sl, depth + 1)? -+ } else { -+ Tree::from_slice_helper_round(sl, depth + 1)? -+ }; -+ - ret.args.push(arg); - - if new_sl.is_empty() { -``` - -When trying to parse a descriptor (essentially turning a recursive string of `operator(args)` into an abstract tree in memory) use a *curly-bracket-aware* parser if there is one in the string. - -The code to then build a `Tr` struct given an `expression::Tree` (and the `from_slice_helper_curly` function) were already implemented, so it was just a matter of correctly -building the abstract tree by parsing curly brackets in descriptors. - -``` -$ git show 3055cab -``` - -```diff -commit 3055cabef8bd51eda344ce501b03c533fd367b4f -Author: Alekos Filini -Date: Sat Nov 13 14:26:30 2021 +0100 - - Fix control block creation when satisfying `Tr` - -diff --git a/src/descriptor/tr.rs b/src/descriptor/tr.rs -index 314c7f4..8487d56 100644 ---- a/src/descriptor/tr.rs -+++ b/src/descriptor/tr.rs -@@ -571,17 +571,14 @@ impl DescriptorTrait for Tr { - } else { - let ver = LeafVersion::default(); - let leaf_script = (ms.encode(), ver); -- let control_block_set = spend_info -- .as_script_map() -- .get(&leaf_script) -- .expect("Control block must exist in script map for every known leaf"); -+ // let control_block_set = spend_info -+ // .as_script_map() -+ // .get(&leaf_script) -+ // .expect("Control block must exist in script map for every known leaf"); -+ let control_block = spend_info.control_block(&leaf_script).expect("Control block must exist in script map for every known leaf"); - wit.push(leaf_script.0.into_bytes()); // Push the leaf script - // There can be multiple control blocks for a (script, ver) pair - // Find the smallest one amongst those -- let control_block = control_block_set -- .iter() -- .min_by(|x, y| x.as_inner().len().cmp(&y.as_inner().len())) -- .expect("Atleast one control must exist for a known leaf"); - wit.push(control_block.serialize()); - // Finally, save the minimum - min_wit = Some(wit); - -``` - -This is where things get more interesting: this section of code builds the witness to satisfy a Taproot descriptor. In case of a script-spend, we need to prove that the script we are using had been committed -into the public key of our `P2TR` input. We do this by adding a "control block", that contains data about the parity of the key, the leaf version used, and the merkle path from the leaf we are using to spend -up to the merkle root, which is committed into the public key. Once again, this is explained very well in [`BIP341`]. - -Before my patch the code was only getting the set of merkle paths that could lead from the root to the leaves that contain a given script. For context, the signature of `TaprootSpendInfo::as_script_map(&self)` is: - -```rust -/// Access the internal script map -pub fn as_script_map(&self) -> &BTreeMap<(Script, LeafVersion), BTreeSet> {} -``` - -Then the code would look for the "shortest" path to that specific script, as it would save size in the final transaction (leaves that are more "deep" in the tree than others naturally have more hidden branches -in their path to the root, and thus require a longer control block to reveal them all). - -The issue here is that the `control_block` variable is then serialized directly into the witness. But this is not a control block, it's just a set of merkle paths! A control block only has *one* merkle path, and -includes the leaf version and the key parity bit. - -Conveniently, the `TaprootSpendInfo` struct also has this other method (I'm including the implementation as well, because it shows that internally it does the same "trick" to find the shortest path): - -```rust -/// Obtain a [`ControlBlock`] for particular script with the given version. -/// Returns [`None`] if the script is not contained in the [`TaprootSpendInfo`] -/// If there are multiple ControlBlocks possible, this returns the shortest one. -pub fn control_block(&self, script_ver: &(Script, LeafVersion)) -> Option { - let merkle_branch_set = self.script_map.get(script_ver)?; - // Choose the smallest one amongst the multiple script maps - let smallest = merkle_branch_set - .iter() - .min_by(|x, y| x.0.len().cmp(&y.0.len())) - .expect("Non-empty iterator"); - Some(ControlBlock { - internal_key: self.internal_key, - output_key_parity: self.output_key_parity, - leaf_version: LeafVersion::default(), - merkle_branch: smallest.clone(), - }) -} -``` - -So to fix this code we just have to use that method instead, and we can get it done in one single line! - -Instead of removing the old code at the time I only commented it out, because I initially thought I would still have to look for the shortest script myself, and I figured the "sorting" code would come in handy -later on. - -Also, if you are an acute observer, you might have noticed that there's a bug in this last snippet of code. Feel free to think about it a little bit, then check out the [PR][fix-control-block-bug-pr] I made -if you wanna know the answer! - -``` -git show 35378ad -``` - -```diff -commit 35378ad01a6f2b8161a3f36448b24d031f8aeaec -Author: Alekos Filini -Date: Sat Nov 13 14:27:14 2021 +0100 - - Consider key-spend max satisfaction weight - -diff --git a/src/descriptor/tr.rs b/src/descriptor/tr.rs -index 8487d56..fabf860 100644 ---- a/src/descriptor/tr.rs -+++ b/src/descriptor/tr.rs -@@ -593,7 +593,7 @@ impl DescriptorTrait for Tr { - } - - fn max_satisfaction_weight(&self) -> Result { -- let mut max_wieght = None; -+ let mut max_wieght = Some(65); - for (depth, ms) in self.iter_scripts() { - let script_size = ms.script_size(); - let max_sat_elems = match ms.max_satisfaction_witness_elements() { -``` - -This is a little bug in the code that tries to compute what the maximum satisfaction weight would be for a descriptor. For instance, we use this in BDK to compute how many extra sats of fees we need to pay -in order to target a given fee rate, assuming the descriptor is satisfied with the worst (larger and most expensive) path. - -For Taproot descriptors, it's just a matter of iterating over the leaves in the tree and pick the most expensive one... or is it? This doesn't take into account that Taproot outputs can also be spent with -key-spend, which means just pushing a signature to the witness. This signature is 64 bytes long when using the new [`SIGHASH_DEFAULT`][`BIP341`] sighash, or 65 otherwise. Since we are thinking about the maximum satisfaction -weight, or the worst case possible, we naturally pick the latter. - -Note that theoretically you could build a Taproot address "without" an available key-path spend (by using an unspendable Schnorr public key), but the code here in rust-miniscript doesn't take that into -account, as there's no way that I'm aware of to specificy in a `tr()` descriptor that the key is unspendable. So, while theoretically here we should first check whether the key-spend path is available before -accounting for its weight, in practice this is always true in miniscript so we just use that as our starting worst case and update it later if necessary while iterating the tree leaves. - -``` -$ git show b4878f8 -``` - -```diff -commit b4878f816e9ede11d5ed947c06e03aa988e3e26f -Author: Alekos Filini -Date: Sat Nov 13 14:27:53 2021 +0100 - - Look for taproot stuff in psbts - -diff --git a/src/psbt/mod.rs b/src/psbt/mod.rs -index 9a8b17d..42c6ce8 100644 ---- a/src/psbt/mod.rs -+++ b/src/psbt/mod.rs -@@ -25,13 +25,14 @@ use bitcoin; - use bitcoin::hashes::{hash160, ripemd160, sha256, sha256d}; - use bitcoin::secp256k1::{self, Secp256k1}; - use bitcoin::util::psbt::PartiallySignedTransaction as Psbt; -+use bitcoin::util::taproot::TapLeafHash; - use bitcoin::Script; - - use interpreter; - use miniscript::limits::SEQUENCE_LOCKTIME_DISABLE_FLAG; - use miniscript::satisfy::{After, Older}; - use Satisfier; --use {BitcoinECSig, Preimage32}; -+use {BitcoinECSig, BitcoinSchnorrSig, Preimage32}; - use {MiniscriptKey, ToPublicKey}; - - mod finalizer; -@@ -231,6 +232,24 @@ impl<'psbt> PsbtInputSatisfier<'psbt> { - } - - impl<'psbt, Pk: MiniscriptKey + ToPublicKey> Satisfier for PsbtInputSatisfier<'psbt> { -+ fn lookup_tap_key_spend_sig(&self) -> Option { -+ if let Some((sig, hash_ty)) = self.psbt.inputs[self.index].tap_key_sig { -+ Some(BitcoinSchnorrSig { sig, hash_ty }) -+ } else { -+ None -+ } -+ } -+ -+ fn lookup_tap_leaf_script_sig(&self, pk: &Pk, lh: &TapLeafHash) -> Option { -+ let pk = pk.to_x_only_pubkey(); -+ -+ if let Some((sig, hash_ty)) = self.psbt.inputs[self.index].tap_script_sigs.get(&(pk, *lh)) { -+ Some(BitcoinSchnorrSig { sig: *sig, hash_ty: *hash_ty }) -+ } else { -+ None -+ } -+ } -+ - fn lookup_ec_sig(&self, pk: &Pk) -> Option { - if let Some(rawsig) = self.psbt.inputs[self.index] - .partial_sigs -``` - -This commit implements the Taproot-specific `Satisfier` methods on `PsbtInputSatisfier`. The code to produce a valid witness (i.e. *satisfy*) a descriptor by looking for Taproot key-spend or script-spend signatures -is already implemented, so it's just a matter of actually returning those, if they are present in a PSBT. - -``` -$ git show 80da0ba -``` - -```diff -commit 80da0ba9b742b2dee23e7302e2f95a6e96b1d6ed -Author: Alekos Filini -Date: Sat Nov 13 16:54:27 2021 +0100 - - Iter keys in `MultiA` - -diff --git a/src/miniscript/iter.rs b/src/miniscript/iter.rs -index 36c4b69..a54a371 100644 ---- a/src/miniscript/iter.rs -+++ b/src/miniscript/iter.rs -@@ -121,7 +121,7 @@ impl Miniscript { - pub fn get_leaf_pk(&self) -> Vec { - match self.node { - Terminal::PkK(ref key) => vec![key.clone()], -- Terminal::Multi(_, ref keys) => keys.clone(), -+ Terminal::Multi(_, ref keys) | Terminal::MultiA(_, ref keys) => keys.clone(), - _ => vec![], - } - } -@@ -139,7 +139,7 @@ impl Miniscript { - match self.node { - Terminal::PkH(ref hash) => vec![hash.clone()], - Terminal::PkK(ref key) => vec![key.to_pubkeyhash()], -- Terminal::Multi(_, ref keys) => keys.iter().map(Pk::to_pubkeyhash).collect(), -+ Terminal::Multi(_, ref keys) | Terminal::MultiA(_, ref keys) => keys.iter().map(Pk::to_pubkeyhash).collect(), - _ => vec![], - } - } -@@ -155,7 +155,7 @@ impl Miniscript { - match self.node { - Terminal::PkH(ref hash) => vec![PkPkh::HashedPubkey(hash.clone())], - Terminal::PkK(ref key) => vec![PkPkh::PlainPubkey(key.clone())], -- Terminal::Multi(_, ref keys) => keys -+ Terminal::Multi(_, ref keys) | Terminal::MultiA(_, ref keys) => keys - .into_iter() - .map(|key| PkPkh::PlainPubkey(key.clone())) - .collect(), -@@ -170,7 +170,7 @@ impl Miniscript { - pub fn get_nth_pk(&self, n: usize) -> Option { - match (&self.node, n) { - (&Terminal::PkK(ref key), 0) => Some(key.clone()), -- (&Terminal::Multi(_, ref keys), _) => keys.get(n).cloned(), -+ (&Terminal::Multi(_, ref keys), _) | (&Terminal::MultiA(_, ref keys), _) => keys.get(n).cloned(), - _ => None, - } - } -@@ -186,7 +186,7 @@ impl Miniscript { - match (&self.node, n) { - (&Terminal::PkH(ref hash), 0) => Some(hash.clone()), - (&Terminal::PkK(ref key), 0) => Some(key.to_pubkeyhash()), -- (&Terminal::Multi(_, ref keys), _) => keys.get(n).map(Pk::to_pubkeyhash), -+ (&Terminal::Multi(_, ref keys), _) | (&Terminal::MultiA(_, ref keys), _) => keys.get(n).map(Pk::to_pubkeyhash), - _ => None, - } - } -@@ -199,7 +199,7 @@ impl Miniscript { - match (&self.node, n) { - (&Terminal::PkH(ref hash), 0) => Some(PkPkh::HashedPubkey(hash.clone())), - (&Terminal::PkK(ref key), 0) => Some(PkPkh::PlainPubkey(key.clone())), -- (&Terminal::Multi(_, ref keys), _) => { -+ (&Terminal::Multi(_, ref keys), _) | (&Terminal::MultiA(_, ref keys), _) => { - keys.get(n).map(|key| PkPkh::PlainPubkey(key.clone())) - } - _ => None, -``` - -Taproot descriptors add a new miniscript operator called `multi_a()` which behaves like `multi()` in non-Taproot descriptors, but uses the new [`OP_CHECKSIGADD`] opcode when serialized in a script. - -When this was added, somebody forgot to update the various methods that iterate over the public keys of a descriptor to correctly return the keys contained in `multi_a()` - essentially, it was falling back in -the default case used by the operators that don't contain any key, but this one does! - -``` -$ git show 8b108c5 -``` - -```diff -commit 8b108c5c0bf50b66b7220746525742b71f6cd4b4 -Author: Alekos Filini -Date: Sat Nov 13 17:26:53 2021 +0100 - - Fix witness generation for `MultiA` - -diff --git a/src/miniscript/satisfy.rs b/src/miniscript/satisfy.rs -index 655436e..ab43707 100644 ---- a/src/miniscript/satisfy.rs -+++ b/src/miniscript/satisfy.rs -@@ -1264,7 +1264,7 @@ impl Satisfaction { - // Collect all available signatures - let mut sig_count = 0; - let mut sigs = vec![vec![vec![]]; keys.len()]; -- for (i, pk) in keys.iter().enumerate() { -+ for (i, pk) in keys.iter().rev().enumerate() { - match Witness::signature::<_, _, Ctx>(stfr, pk, leaf_hash) { - Witness::Stack(sig) => { - sigs[i] = sig; -``` - -And finally, the last little fix: the `multi_a()` operator is satisfied by pushing to the witness either a signature (if you have one available for that specific public key) or an empty vector. The problem is, -they have to be in the right order to match the order of public keys in your Taproot script. - -rust-miniscript was pushing them in reverse order, so script validation was always failing for multisigs that had more than 1 key. Adding a `.rev()` to the iterator fixed the issue. - -## Conclusion - -And that was it! We now have a fully working [rust-bitcoin] and [rust-miniscript] ready for Taproot. - -In [Part 2] I will go over the code changes in BDK, but I think it's now time for you and I to take a break :) - -[first-mainnet-tx]: https://twitter.com/afilini/status/1459763243556163584 -[first-ever-use-checksigadd]: https://twitter.com/afilini/status/1459774394054725634 -[Satoshi Spritz]: https://www.satoshispritz.com/ -[first-key-spend]: https://mempool.space/signet/tx/ba0ebb350717701ca4ea109aadfbaf3058f6cd73e5ece3927ddee653de06cf5a -[first-script-spend]: https://mempool.space/signet/tx/41d7d49f9f4edffa9ca88ad6fb887fbf1ae68f9f31def267fdb3a5949f766bf5 -[vanity-addr]: https://mempool.space/address/1Taproote7gvQGKz5g982ecSbPvqJhMUf -[no-taproot-transactions-blocks]: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-November/019598.html -[my-taproot-transaction]: https://mempool.space/tx/2eb8dbaa346d4be4e82fe444c2f0be00654d8cfd8c4a9a61b11aeaab8c00b272 -[few-other-transactions]: https://twitter.com/achow101/status/1459760452775387136?s=20 -[taproot-single-sig]: https://mempool.space/tx/37777defed8717c581b4c0509329550e344bdc14ac38f71fc050096887e535c8 -[taproot-bitgo-multisig]: https://mempool.space/tx/905ecdf95a84804b192f4dc221cfed4d77959b81ed66013a7e41a6e61e7ed530 - -[`BIP174`]: https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki -[`BIP340`]: https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki -[`BIP341`]: https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki -[`BIP371`]: https://github.com/bitcoin/bips/blob/master/bip-0371.mediawiki -[`OP_CHECKSIGADD`]: https://github.com/bitcoin/bips/blob/master/bip-0342.mediawiki#script-execution - -[sanket1729]: https://twitter.com/sanket1729 - -[taproot-builder-iter]: https://github.com/afilini/rust-miniscript/blob/taproot/src/descriptor/tr.rs#L183-L189 -[order-that-is-not-dfs]: https://github.com/afilini/rust-bitcoin/blob/taproot-testing/src/util/taproot.rs#L403-L405 - -[rust-miniscript]: https://github.com/rust-bitcoin/rust-miniscript -[rust-bitcoin]: https://github.com/rust-bitcoin/rust-bitcoin -[rust-bitcoin-taproot-testing]: https://github.com/afilini/rust-bitcoin/tree/taproot-testing -[rust-miniscript-taproot]: https://github.com/afilini/rust-miniscript/tree/taproot - -[fix-control-block-bug-pr]: https://github.com/rust-bitcoin/rust-bitcoin/pull/703 diff --git a/docs/blog/first_bdk_taproot_tx_part_2.md b/docs/blog/first_bdk_taproot_tx_part_2.md deleted file mode 100644 index fbca1c242e..0000000000 --- a/docs/blog/first_bdk_taproot_tx_part_2.md +++ /dev/null @@ -1,915 +0,0 @@ -# The first BDK Taproot TX: a look at the code (Part 2) - -:lucide-pen-tool:   [`Alekos Filini`](https://github.com/afilini) -:lucide-calendar-1:   `Dec 10, 2021` ---- - -This is the second part of a two-part blog series in which I talk through the changes made to BDK to make a Taproot transaction. If you haven't read it yet, check out [Part 1]. - -While in the first part I managed to show full raw commits, in this case I will only focus on the relevant changes, otherwise the post would get very long. You can always find the [full diff] here, if you are interested -in that. - -## Shortcuts - -As mentioned previously, the main goal of this journey for me was to find out what it really takes to support Taproot in BDK. The code shown here wasn't written to be readable and/or maintainable, so -some shortcuts were taken, in particular: - -- No support for BIP32 extended keys: this is probably very quick to add, but in the first "proof of concept" I decided to only work with WIF keys for simplicity -- No support for [`SIGHASH_DEFAULT`][`BIP341`]: this would require some minor changes to a few traits in BDK that still use the "legacy" `SigHashType` enum from [rust-bitcoin] - -## Utilities - -Let's start with some utilities: - -```rust -pub fn ecdsa_to_schnorr(pk: &ecdsa::PublicKey) -> schnorr::PublicKey { - schnorr::PublicKey::from_slice(&pk.to_bytes()[1..]).expect("Key conversion failure") -} - -pub fn compute_merkle_root( - leaf_hash: &taproot::TapLeafHash, - control_block: &taproot::ControlBlock, -) -> taproot::TapBranchHash { - taproot::TapBranchHash::from_inner( - control_block - .merkle_branch - .as_inner() - .iter() - .fold( - taproot::NodeInfo::new_hidden( - sha256::Hash::from_slice(leaf_hash.as_inner()).expect("Invalid TapLeafHash"), - ), - |acc, branch| { - taproot::NodeInfo::combine(acc, taproot::NodeInfo::new_hidden(*branch)) - .expect("Invalid tree") - }, - ) - .hash() - .into_inner(), - ) -} -``` - -The first function "converts" an ECDSA key to a Schnorr key by dropping the first byte that encodes the key parity, since Schnorr keys are "x-only". - -The second one constructs the merkle root of a taptree given a leaf hash and the corresponding control block. - -## Wrap Fallible Methods - -Many of the methods exposed by a `Descriptor` struct used to be infallible: for instance, it was always possible to "encode" a descriptor into a Bitcoin script by calling the `script_pubkey()` method. - -Unfortunately, taproot descriptors need some extra metadata to do that: they can be computed by calling the `spend_info()` method, and they will be cached inside the descriptor, but since it's not guaranteed by the -compiler that the method will be called before trying to encode it, the infallible methods had to be changed to return a `Result`, so that they can fail if the spend info is not present. - -In BDK we call the `spend_info()` method right after "deriving" the descriptor, so it's guaranteed that we will never encounter that error: for this reason, we wrap those methods and call `expect()` on them, to keep -the original code mostly unchanged. - -Here we call `spend_info()` right after deriving the descriptor, if it's a `Tr` variant: - -```diff -@@ -136,10 +133,16 @@ impl AsDerived for Descriptor { - index: u32, - secp: &'s SecpCtx, - ) -> Descriptor> { -- self.derive(index).translate_pk_infallible( -+ let mut derived = self.derive(index).translate_pk_infallible( - |key| DerivedDescriptorKey::new(key.clone(), secp), - |key| DerivedDescriptorKey::new(key.clone(), secp), -- ) -+ ); -+ -+ if let Descriptor::Tr(tr) = &mut derived { -+ tr.spend_info(secp); -+ } -+ -+ derived - } -``` - -And here we wrap the `script_pubkey()` method and call `expect()` on it. Note that we only implement it on `DerivedDescriptor`, because it's not guaranteed that "extended descriptors" will have the cached metadata inside. - -```rust -pub(crate) trait DerivedDescriptorSafeOps { - /// The [`Descriptor::script_pubkey`] method can fail on `Tr` descriptors that don't have the - /// `spend_info` inside. Since we generate those upon derivation, it's guaranteed that the - /// method will not fail on `DerivedDescriptor`s. - fn script_pubkey_derived(&self) -> Script; -} - -impl<'s> DerivedDescriptorSafeOps for Descriptor> { - fn script_pubkey_derived(&self) -> Script { - self.script_pubkey() - .expect("`spend_info` is always present in `DerivedDescriptor`s") - } -} -``` - -## Descriptor Metadata - -In BDK we have a few traits that in a way "unify" the interface of a descriptor: things like the `redeem_script` of an input has to be computed differently depending on the type of descriptor. The traits we define -are implemented on the `DerivedDescriptor` or `ExtendedDescriptor` structs and allow us to quickly get what we need without having to check the descriptor type manually. - -Internally, they are essentially large `match`es that return different things depending on the descriptor variant. Due to some renaming that had been done recently in `miniscript` (not necessarily related to taproot) -we have to update them: - -```diff -@@ -337,6 +339,7 @@ pub(crate) trait DerivedDescriptorMeta { - - pub(crate) trait DescriptorMeta { - fn is_witness(&self) -> bool; -+ fn is_tap(&self) -> bool; - fn get_extended_keys(&self) -> Result>, DescriptorError>; - fn derive_from_hd_keypaths<'s>( - &self, -@@ -358,23 +361,29 @@ pub(crate) trait DescriptorScripts { - - impl<'s> DescriptorScripts for DerivedDescriptor<'s> { - fn psbt_redeem_script(&self) -> Option