From 699fafc7dc795a80c41e0da7c365a168761a3de3 Mon Sep 17 00:00:00 2001 From: Vihiga Tyonum Date: Tue, 3 Feb 2026 13:23:56 +0100 Subject: [PATCH 1/4] docs: Update README for the library --- README.md | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 90 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1a552d2..55c2ad2 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,92 @@ # bdk-bitcoind-client -Bitcoin Core RPC Client (experimental) +A minimal, experimental Bitcoin Core RPC client designed specifically for the Bitcoin Dev Kit (BDK). Unlike generic RPC wrappers, +`bdk-bitcoind-client` focuses on high-performance data emission and strict type safety, with built-in support for multiple Bitcoin +Core versions (v28.0 through v30.0+). + +### Features + +- _Version Pinning_: Explicit support for different Bitcoin Core RPC schemas via feature flags (28_0, 29_0, 30_0). +- _Minimal Dependencies_: Uses bitreq_http for a lightweight HTTP transport by default. +- _Wallet-Agnostic_: Focused on blockchain data emission (blocks, headers, mempool) rather than wallet management. +- _Robust Error Handling_: Specific error variants for RPC failures, deserialization issues, and transport timeouts. + +### Installation + +Add this to your `Cargo.toml`: +``` +// For the latest Bitcoin Core (v30.0+) +bdk-bitcoind-client = { version = "0.1.0" } + +// OR for older nodes (e.g., v28.x) +bdk-bitcoind-client = { version = "0.1.0", default-features = false, features = ["28_0"] } +``` + +### Quick Start + +``` +use bdk_bitcoind_client::{Auth, Client}; +use std::path::PathBuf; +fn main() -> anyhow::Result<()> { + // 1. Setup authentication (Cookie file is recommended for security) + let auth = Auth::CookieFile(PathBuf::from("/path/to/regtest/.cookie")); + + // 2. Initialize the client + let client = Client::with_auth("http://127.0.0.1:18443", auth)?; + + // 3. Query the blockchain + let block_count = client.get_block_count()?; + let best_hash = client.get_block_hash(block_count)?; + + // 4. Get verbose headers (handles schema differences automatically) + let header = client.get_block_header_verbose(&best_hash)?; + + println!("Chain tip: {} at height {}", header.hash, header.height); + + Ok(()) +} +``` + +### Version Compatibility + +Bitcoin Core often changes its JSON-RPC response fields (e.g., adding the target field in `v29/v30`). This client manages these differences through compile-time features. + +| Feature | Bitcoin Core Version | Notes | +| ----------------- | --------------------- | -------------------------------------------- | +| 30_0 (default) | v30.x and newer | Supports latest target and difficulty fields.| +| 29_0 | v29.x | Aligned with v29 schema. | +| 28_0v | 28.x and older | Omits newer fields | + + +### Development and Testing +To run tests against a specific Bitcoin Core version, use the corresponding feature flag: + +``` +cargo test --no-default-features --features 28_0 +``` + +### Minimum Supported Rust Version (MSRV) + +The library maintain a MSRV of 1.85.0. + +## Just + +This project has a [`justfile`](/justfile) for easy command running. You must have [`just`](https://github.com/casey/just) installed. + +To see a list of available recipes: `just` + +## License + +Licensed under either of + +* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or ) +* MIT license ([LICENSE-MIT](LICENSE-MIT) or ) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally +submitted for inclusion in the work by you, as defined in the Apache-2.0 +license, shall be dual licensed as above, without any additional terms or +conditions. From 1da987ea4eb8c2d0a6069778a2142a234cd0b00c Mon Sep 17 00:00:00 2001 From: Vihiga Tyonum Date: Thu, 12 Feb 2026 22:06:21 +0100 Subject: [PATCH 2/4] docs: Update API documentation - Add syntax highlighting for code blocks in README --- README.md | 14 ++++++-------- src/client.rs | 28 ++++++++++++++-------------- 2 files changed, 20 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 55c2ad2..0088f74 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,6 @@ # bdk-bitcoind-client -A minimal, experimental Bitcoin Core RPC client designed specifically for the Bitcoin Dev Kit (BDK). Unlike generic RPC wrappers, -`bdk-bitcoind-client` focuses on high-performance data emission and strict type safety, with built-in support for multiple Bitcoin -Core versions (v28.0 through v30.0+). +A minimal Bitcoin Core RPC client designed specifically for the Bitcoin Dev Kit (BDK). It retrieves blockchain data from `bitcoind` over JSON-RPC and supports multiple versions of Bitcoin Core (v28.0 through v30.0+). ### Features @@ -14,17 +12,17 @@ Core versions (v28.0 through v30.0+). ### Installation Add this to your `Cargo.toml`: -``` -// For the latest Bitcoin Core (v30.0+) +```toml +# For the latest Bitcoin Core (v30.0+) bdk-bitcoind-client = { version = "0.1.0" } -// OR for older nodes (e.g., v28.x) +# OR for older nodes (e.g., v28.x) bdk-bitcoind-client = { version = "0.1.0", default-features = false, features = ["28_0"] } ``` ### Quick Start -``` +```rust use bdk_bitcoind_client::{Auth, Client}; use std::path::PathBuf; fn main() -> anyhow::Result<()> { @@ -55,7 +53,7 @@ Bitcoin Core often changes its JSON-RPC response fields (e.g., adding the target | ----------------- | --------------------- | -------------------------------------------- | | 30_0 (default) | v30.x and newer | Supports latest target and difficulty fields.| | 29_0 | v29.x | Aligned with v29 schema. | -| 28_0v | 28.x and older | Omits newer fields | +| 28_0 | v28.x and older | Omits newer fields | ### Development and Testing diff --git a/src/client.rs b/src/client.rs index 3f7201b..28348e6 100644 --- a/src/client.rs +++ b/src/client.rs @@ -63,7 +63,7 @@ pub struct Client { } impl Client { - /// Creates a client connection to a bitcoind JSON-RPC server with authentication + /// Creates a client connection to a bitcoind JSON-RPC server with authentication. /// /// Requires authentication via username/password or cookie file. /// For connections without authentication, use `with_transport` instead. @@ -71,7 +71,7 @@ impl Client { /// # Arguments /// /// * `url` - URL of the RPC server - /// * `auth` - authentication method (`UserPass` or `CookieFile`). + /// * `auth` - authentication method (`UserPass` or `CookieFile`) /// /// # Errors /// @@ -109,7 +109,7 @@ impl Client { } } - /// Calls the underlying RPC `method` with given `args` list + /// Calls the underlying RPC `method` with the given `args`. /// /// This is the generic function used by all specific RPC methods. pub fn call(&self, method: &str, args: &[serde_json::Value]) -> Result @@ -124,9 +124,9 @@ impl Client { } } -/// `Bitcoind` RPC methods implementation for `Client` +/// `bitcoind` RPC methods implementation for `Client`. impl Client { - /// Retrieves the raw block data for a given block hash (verbosity 0) + /// Retrieves the raw block data for a given block hash (verbosity 0). /// /// # Arguments /// @@ -140,7 +140,7 @@ impl Client { .and_then(|block_hex| deserialize_hex(&block_hex).map_err(Error::DecodeHex)) } - /// Retrieves the hash of the tip of the best block chain. + /// Retrieves the hash of the best chain's block. /// /// # Returns /// @@ -150,7 +150,7 @@ impl Client { .and_then(|blockhash_hex| blockhash_hex.parse().map_err(Error::HexToArray)) } - /// Retrieves the number of blocks in the longest chain + /// Retrieves the number of blocks in the longest chain. /// /// # Returns /// @@ -162,7 +162,7 @@ impl Client { .map_err(Error::TryFromInt) } - /// Retrieves the block hash at a given height + /// Retrieves the [`BlockHash`] of the block at `height`. /// /// # Arguments /// @@ -170,13 +170,13 @@ impl Client { /// /// # Returns /// - /// The `BlockHash` for the given height + /// The [`BlockHash`] of the block at `height` pub fn get_block_hash(&self, height: u32) -> Result { self.call::("getblockhash", &[json!(height)]) .and_then(|blockhash_hex| blockhash_hex.parse().map_err(Error::HexToArray)) } - /// Retrieve the `basic` BIP 157 content filter for a particular block + /// Retrieve the Compact Block Filter (BIP-0158) with type `basic` for the block given its `Blockhash`. /// /// # Arguments /// @@ -184,14 +184,14 @@ impl Client { /// /// # Returns /// - /// The `GetBlockFilter` structure containing the filter data + /// The `GetBlockFilter` structure containing the filter data for the block pub fn get_block_filter(&self, block_hash: &BlockHash) -> Result { let block_filter: v30::GetBlockFilter = self.call("getblockfilter", &[json!(block_hash)])?; block_filter.into_model().map_err(Error::GetBlockFilter) } - /// Retrieves the raw block header for a given block hash. + /// Retrieves the `Header` for a `Block` given its `BlockHash`. /// /// # Arguments /// @@ -205,7 +205,7 @@ impl Client { .and_then(|header_hex: String| deserialize_hex(&header_hex).map_err(Error::DecodeHex)) } - /// Retrieves the transaction IDs of all transactions currently in the mempool + /// Retrieves the `Txid`s for all transactions in the mempool. /// /// # Returns /// @@ -215,7 +215,7 @@ impl Client { .map(|txids| txids.0) } - /// Retrieves the raw transaction data for a given transaction ID + /// Retrieves the raw transaction data for a given transaction ID. /// /// # Arguments /// From 1d89d3cdf224a1230e83bb84c2e8864854e0c46f Mon Sep 17 00:00:00 2001 From: valued mammal Date: Wed, 1 Apr 2026 20:38:47 -0400 Subject: [PATCH 3/4] docs: Fix link to licenses in README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0088f74..b756a23 100644 --- a/README.md +++ b/README.md @@ -77,8 +77,8 @@ To see a list of available recipes: `just` Licensed under either of -* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or ) -* MIT license ([LICENSE-MIT](LICENSE-MIT) or ) +* Apache License, Version 2.0 () +* MIT license ([LICENSE](LICENSE) or ) at your option. From 8bf074a59bc911a6e7ee92ce60eccc3d3c144784 Mon Sep 17 00:00:00 2001 From: Vihiga Tyonum Date: Thu, 2 Apr 2026 04:29:53 +0100 Subject: [PATCH 4/4] docs: Add Apache 2.0 LICENSE and LICENSE.md files --- LICENSE-APACHE | 201 +++++++++++++++++++++++++++++++++++++++++ LICENSE => LICENSE-MIT | 0 LICENSE.md | 14 +++ README.md | 4 +- 4 files changed, 217 insertions(+), 2 deletions(-) create mode 100644 LICENSE-APACHE rename LICENSE => LICENSE-MIT (100%) create mode 100644 LICENSE.md diff --git a/LICENSE-APACHE b/LICENSE-APACHE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/LICENSE b/LICENSE-MIT similarity index 100% rename from LICENSE rename to LICENSE-MIT diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..cbbfca4 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,14 @@ +This software is licensed under [Apache 2.0](LICENSE-APACHE) or +[MIT](LICENSE-MIT), at your option. + +Some files retain their own copyright notice, however, for full authorship +information, see version control history. + +Except as otherwise noted in individual files, all files in this repository are +licensed under the Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or +) or the MIT License ([LICENSE-MIT](LICENSE-MIT) or +), at your option. + +You may not use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of this software or any files in this repository except in +accordance with one or both of these licenses. diff --git a/README.md b/README.md index b756a23..5ae6204 100644 --- a/README.md +++ b/README.md @@ -77,8 +77,8 @@ To see a list of available recipes: `just` Licensed under either of -* Apache License, Version 2.0 () -* MIT license ([LICENSE](LICENSE) or ) +* Apache License, Version 2.0 ([Apache 2.0](LICENSE-APACHE) or ) +* MIT License ([MIT](LICENSE-MIT) or ) at your option.