Skip to content

Commit dc4e009

Browse files
committed
refactor: replace examples with focused rustdoc examples
Removed /examples folder containing CLI-heavy examples Added focused rustdoc examples to key functions: - IndexedTxGraph::new() - graph initialization - BdkElectrumClient::new() - client creation - BdkElectrumClient::sync() - blockchain sync - BdkElectrumClient::full_scan() - wallet restoration - TxGraph::insert_tx() - transaction insertion - TxGraph::balance() - balance calculation - TxGraph::filter_chain_unspents() - UTXO retrieval - KeychainTxOutIndex::reveal_next_spk() - address generation - KeychainTxOutIndex::insert_descriptor() - descriptor setup - IndexedTxGraph::apply_block_relevant() - block processing - EsploraExt::full_scan() - Esplora wallet scanning Updated Cargo.toml workspace members Rationale: The previous examples contained 300+ lines of CLI boilerplate that obscured the core BDK functionality. The new rustdoc examples are 10-15 lines each and focus purely on API usage, making them much easier for developers to understand and follow. The maintained bdk-cli tool serves as the comprehensive CLI example.
1 parent 3c57999 commit dc4e009

File tree

16 files changed

+200
-2115
lines changed

16 files changed

+200
-2115
lines changed

.github/workflows/cont_integration.yml

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -166,30 +166,3 @@ jobs:
166166
name: Clippy Results
167167
args: --all-features --all-targets -- -D warnings
168168

169-
build-examples:
170-
needs: prepare
171-
name: Build & Test Examples
172-
runs-on: ubuntu-latest
173-
strategy:
174-
matrix:
175-
example-dir:
176-
- example_cli
177-
- example_bitcoind_rpc_polling
178-
- example_electrum
179-
- example_esplora
180-
steps:
181-
- name: checkout
182-
uses: actions/checkout@v4
183-
with:
184-
persist-credentials: false
185-
- name: Install Rust toolchain
186-
uses: actions-rs/toolchain@v1
187-
with:
188-
toolchain: ${{ needs.prepare.outputs.rust_version }}
189-
override: true
190-
profile: minimal
191-
- name: Rust Cache
192-
uses: Swatinem/[email protected]
193-
- name: Build
194-
working-directory: examples/${{ matrix.example-dir }}
195-
run: cargo build

Cargo.toml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,6 @@ members = [
88
"crates/esplora",
99
"crates/bitcoind_rpc",
1010
"crates/testenv",
11-
"examples/example_cli",
12-
"examples/example_electrum",
13-
"examples/example_esplora",
14-
"examples/example_bitcoind_rpc_polling",
1511
]
1612

1713
[workspace.package]

crates/chain/src/indexed_tx_graph.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,15 @@ where
7777
///
7878
/// The underlying `TxGraph` is initialized with `TxGraph::default()`, and the provided
7979
/// `index`er is used as‐is (since there are no existing transactions to process).
80+
///
81+
/// # Example
82+
///
83+
/// ```
84+
/// use bdk_chain::{keychain_txout::KeychainTxOutIndex, BlockId, IndexedTxGraph};
85+
///
86+
/// let index = KeychainTxOutIndex::<&str>::new(10, true);
87+
/// let graph = IndexedTxGraph::<BlockId, _>::new(index);
88+
/// ```
8089
pub fn new(index: I) -> Self {
8190
Self {
8291
index,
@@ -351,6 +360,18 @@ where
351360
///
352361
/// Relevancy is determined by the internal [`Indexer::is_tx_relevant`] implementation of `I`.
353362
/// Irrelevant transactions in `txs` will be ignored.
363+
///
364+
/// # Example
365+
///
366+
/// ```no_run
367+
/// use bdk_chain::{IndexedTxGraph, keychain_txout::KeychainTxOutIndex, BlockId};
368+
/// use bitcoin::Block;
369+
///
370+
/// let mut graph = IndexedTxGraph::<BlockId, _>::new(KeychainTxOutIndex::<&str>::new(10, true));
371+
/// # let block = Block { header: bitcoin::block::Header::from(bitcoin::constants::genesis_block(bitcoin::Network::Bitcoin).header), txdata: vec![] };
372+
///
373+
/// let changeset = graph.apply_block_relevant(&block, 100);
374+
/// ```
354375
pub fn apply_block_relevant(
355376
&mut self,
356377
block: &Block,

crates/chain/src/indexer/keychain_txout.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,22 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
453453
/// (one keychain just becomes the defacto owner of that spk arbitrarily) but this may have
454454
/// subtle implications up the application stack like one UTXO being missing from one keychain
455455
/// because it has been assigned to another which produces the same script pubkey.
456+
///
457+
/// # Example
458+
///
459+
/// ```
460+
/// use bdk_chain::keychain_txout::KeychainTxOutIndex;
461+
/// use bdk_chain::miniscript::{Descriptor, DescriptorPublicKey};
462+
/// # use std::str::FromStr;
463+
///
464+
/// let mut index = KeychainTxOutIndex::<&str>::new(10, true);
465+
/// let desc = Descriptor::<DescriptorPublicKey>::from_str(
466+
/// "wpkh([d34db33f/84h/0h/0h]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/0/*)"
467+
/// )?;
468+
///
469+
/// index.insert_descriptor("external", desc)?;
470+
/// # Ok::<_, Box<dyn std::error::Error>>(())
471+
/// ```
456472
pub fn insert_descriptor(
457473
&mut self,
458474
keychain: K,
@@ -834,6 +850,22 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
834850
/// 1. The descriptor has no wildcard and already has one script revealed.
835851
/// 2. The descriptor has already revealed scripts up to the numeric bound.
836852
/// 3. There is no descriptor associated with the given keychain.
853+
///
854+
/// # Example
855+
///
856+
/// ```
857+
/// use bdk_chain::keychain_txout::KeychainTxOutIndex;
858+
/// use bdk_chain::miniscript::{Descriptor, DescriptorPublicKey};
859+
/// # use std::str::FromStr;
860+
///
861+
/// let mut index = KeychainTxOutIndex::<&str>::new(10, true);
862+
/// let desc = Descriptor::<DescriptorPublicKey>::from_str(
863+
/// "wpkh([d34db33f/84h/0h/0h]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/0/*)"
864+
/// ).unwrap();
865+
/// index.insert_descriptor("external", desc).unwrap();
866+
/// let (spk, changeset) = index.reveal_next_spk("external").unwrap();
867+
/// assert_eq!(spk.0, 0);
868+
/// ```
837869
pub fn reveal_next_spk(&mut self, keychain: K) -> Option<(Indexed<ScriptBuf>, ChangeSet)> {
838870
let mut changeset = ChangeSet::default();
839871
let indexed_spk = self._reveal_next_spk(&mut changeset, keychain)?;

crates/chain/src/tx_graph.rs

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,24 @@ impl<A: Anchor> TxGraph<A> {
655655
/// * A smaller witness has precedence over a larger witness.
656656
/// * If the witness sizes are the same, we prioritize the two witnesses with lexicographical
657657
/// order.
658+
///
659+
/// # Example
660+
///
661+
/// ```
662+
/// use bdk_chain::{tx_graph::TxGraph, BlockId};
663+
/// use bitcoin::Transaction;
664+
///
665+
/// let mut graph = TxGraph::<BlockId>::default();
666+
/// let tx = Transaction {
667+
/// version: bitcoin::transaction::Version::ONE,
668+
/// lock_time: bitcoin::locktime::absolute::LockTime::ZERO,
669+
/// input: vec![],
670+
/// output: vec![],
671+
/// };
672+
///
673+
/// let changeset = graph.insert_tx(tx.clone());
674+
/// assert_eq!(changeset.txs.len(), 1);
675+
/// ```
658676
pub fn insert_tx<T: Into<Arc<Transaction>>>(&mut self, tx: T) -> ChangeSet<A> {
659677
// This returns `Some` only if the merged tx is different to the `original_tx`.
660678
fn _merge_tx_witnesses(
@@ -1247,6 +1265,37 @@ impl<A: Anchor> TxGraph<A> {
12471265
///
12481266
/// This is the infallible version of [`try_filter_chain_unspents`].
12491267
///
1268+
/// # Example
1269+
///
1270+
/// ```
1271+
/// use bdk_chain::local_chain::LocalChain;
1272+
/// use bdk_chain::{tx_graph::TxGraph, BlockId, CanonicalizationParams};
1273+
/// use bitcoin::{Amount, OutPoint, TxOut};
1274+
/// use std::sync::Arc;
1275+
///
1276+
/// let mut graph = TxGraph::<BlockId>::default();
1277+
/// let chain = LocalChain::from_blocks(
1278+
/// [(
1279+
/// 0,
1280+
/// bitcoin::constants::genesis_block(bitcoin::Network::Bitcoin).block_hash(),
1281+
/// )]
1282+
/// .into_iter()
1283+
/// .collect(),
1284+
/// )
1285+
/// .unwrap();
1286+
///
1287+
/// // Get unspent outputs
1288+
/// let outpoints = vec![(0, OutPoint::default())];
1289+
/// let utxos: Vec<_> = graph
1290+
/// .filter_chain_unspents(
1291+
/// &chain,
1292+
/// chain.tip().block_id(),
1293+
/// CanonicalizationParams::default(),
1294+
/// outpoints,
1295+
/// )
1296+
/// .collect();
1297+
/// ```
1298+
///
12501299
/// [`try_filter_chain_unspents`]: Self::try_filter_chain_unspents
12511300
pub fn filter_chain_unspents<'a, C: ChainOracle<Error = Infallible> + 'a, OI: Clone + 'a>(
12521301
&'a self,
@@ -1315,6 +1364,34 @@ impl<A: Anchor> TxGraph<A> {
13151364
///
13161365
/// This is the infallible version of [`try_balance`].
13171366
///
1367+
/// # Example
1368+
///
1369+
/// ```
1370+
/// use bdk_chain::local_chain::LocalChain;
1371+
/// use bdk_chain::{tx_graph::TxGraph, Balance, BlockId, CanonicalizationParams};
1372+
/// use bitcoin::OutPoint;
1373+
///
1374+
/// let graph = TxGraph::<BlockId>::default();
1375+
/// let chain = LocalChain::from_blocks(
1376+
/// [(
1377+
/// 0,
1378+
/// bitcoin::constants::genesis_block(bitcoin::Network::Bitcoin).block_hash(),
1379+
/// )]
1380+
/// .into_iter()
1381+
/// .collect(),
1382+
/// )
1383+
/// .unwrap();
1384+
///
1385+
/// let outpoints = vec![(0, OutPoint::default())];
1386+
/// let balance = graph.balance(
1387+
/// &chain,
1388+
/// chain.tip().block_id(),
1389+
/// CanonicalizationParams::default(),
1390+
/// outpoints,
1391+
/// |_, _| true,
1392+
/// );
1393+
/// ```
1394+
///
13181395
/// [`try_balance`]: Self::try_balance
13191396
pub fn balance<C: ChainOracle<Error = Infallible>, OI: Clone>(
13201397
&self,

crates/electrum/src/bdk_electrum_client.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,16 @@ pub struct BdkElectrumClient<E> {
2828

2929
impl<E: ElectrumApi> BdkElectrumClient<E> {
3030
/// Creates a new bdk client from a [`electrum_client::ElectrumApi`]
31+
///
32+
/// # Example
33+
///
34+
/// ```no_run
35+
/// use bdk_electrum::{electrum_client, BdkElectrumClient};
36+
///
37+
/// let client = electrum_client::Client::new("ssl://electrum.blockstream.info:50002")?;
38+
/// let bdk_client = BdkElectrumClient::new(client);
39+
/// # Ok::<_, electrum_client::Error>(())
40+
/// ```
3141
pub fn new(client: E) -> Self {
3242
Self {
3343
inner: client,
@@ -90,6 +100,27 @@ impl<E: ElectrumApi> BdkElectrumClient<E> {
90100
/// [`CalculateFeeError::MissingTxOut`] error if those `TxOut`s are not present in the
91101
/// transaction graph.
92102
///
103+
/// # Example
104+
///
105+
/// ```no_run
106+
/// use bdk_core::{spk_client::FullScanRequest, BlockId, CheckPoint};
107+
/// use bdk_electrum::BdkElectrumClient;
108+
/// # use bdk_electrum::electrum_client;
109+
/// # use electrum_client::bitcoin::{constants, Network};
110+
///
111+
/// # let client = electrum_client::Client::new("ssl://electrum.blockstream.info:50002")?;
112+
/// # let bdk_client = BdkElectrumClient::new(client);
113+
/// let request = FullScanRequest::<&str>::builder()
114+
/// .chain_tip(CheckPoint::new(BlockId {
115+
/// height: 0,
116+
/// hash: constants::genesis_block(Network::Bitcoin).block_hash(),
117+
/// }))
118+
/// .build();
119+
///
120+
/// let response = bdk_client.full_scan(request, 10, 50, false)?;
121+
/// # Ok::<_, electrum_client::Error>(())
122+
/// ```
123+
///
93124
/// [`bdk_chain`]: ../bdk_chain/index.html
94125
/// [`CalculateFeeError::MissingTxOut`]: ../bdk_chain/tx_graph/enum.CalculateFeeError.html#variant.MissingTxOut
95126
/// [`Wallet.calculate_fee`]: ../bdk_wallet/struct.Wallet.html#method.calculate_fee
@@ -173,6 +204,24 @@ impl<E: ElectrumApi> BdkElectrumClient<E> {
173204
/// If the scripts to sync are unknown, such as when restoring or importing a keychain that
174205
/// may include scripts that have been used, use [`full_scan`] with the keychain.
175206
///
207+
/// # Example
208+
///
209+
/// ```no_run
210+
/// use bdk_core::bitcoin::ScriptBuf;
211+
/// use bdk_core::spk_client::SyncRequest;
212+
/// use bdk_electrum::BdkElectrumClient;
213+
/// # use bdk_electrum::electrum_client;
214+
///
215+
/// # let client = electrum_client::Client::new("ssl://electrum.blockstream.info:50002")?;
216+
/// # let bdk_client = BdkElectrumClient::new(client);
217+
/// let request = SyncRequest::builder()
218+
/// .spks([ScriptBuf::new_op_return(&[0x00; 20])])
219+
/// .build();
220+
///
221+
/// let response = bdk_client.sync(request, 50, false)?;
222+
/// # Ok::<_, electrum_client::Error>(())
223+
/// ```
224+
///
176225
/// [`full_scan`]: Self::full_scan
177226
/// [`bdk_chain`]: ../bdk_chain/index.html
178227
/// [`CalculateFeeError::MissingTxOut`]: ../bdk_chain/tx_graph/enum.CalculateFeeError.html#variant.MissingTxOut

crates/esplora/src/blocking_ext.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,27 @@ pub trait EsploraExt {
2626
/// `stop_gap` script pubkeys with no associated transactions. `parallel_requests` specifies
2727
/// the maximum number of HTTP requests to make in parallel.
2828
///
29+
/// # Example
30+
///
31+
/// ```no_run
32+
/// use bdk_core::bitcoin::{constants, Network};
33+
/// use bdk_core::spk_client::FullScanRequest;
34+
/// use bdk_core::{BlockId, CheckPoint};
35+
/// use bdk_esplora::{esplora_client, EsploraExt};
36+
///
37+
/// let client = esplora_client::Builder::new("https://blockstream.info/api").build_blocking();
38+
///
39+
/// let request = FullScanRequest::<&str>::builder()
40+
/// .chain_tip(CheckPoint::new(BlockId {
41+
/// height: 0,
42+
/// hash: constants::genesis_block(Network::Bitcoin).block_hash(),
43+
/// }))
44+
/// .build();
45+
///
46+
/// let response = client.full_scan(request, 10, 5)?;
47+
/// # Ok::<_, Box<dyn std::error::Error>>(())
48+
/// ```
49+
///
2950
/// Refer to [crate-level docs](crate) for more.
3051
fn full_scan<K: Ord + Clone, R: Into<FullScanRequest<K>>>(
3152
&self,

examples/example_bitcoind_rpc_polling/Cargo.toml

Lines changed: 0 additions & 12 deletions
This file was deleted.

0 commit comments

Comments
 (0)