Skip to content

Commit 8d6a3c6

Browse files
committed
refactor: replace examples with focused rustdoc examples
Remove standalone examples in favor of focused, contextual rustdoc examples that are easier to maintain and provide better documentation. This makes the codebase more maintainable while improving the developer experience with examples that are tested alongside the code they document.
1 parent 3c57999 commit 8d6a3c6

File tree

16 files changed

+203
-2120
lines changed

16 files changed

+203
-2120
lines changed

.github/workflows/cont_integration.yml

Lines changed: 4 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,11 @@ jobs:
6262
MATRIX_RUST_VERSION: ${{ matrix.rust.version }}
6363
run: |
6464
if [ $MATRIX_RUST_VERSION = '1.63.0' ]; then
65-
cargo build --workspace --exclude 'example_*' --exclude 'bdk_electrum' ${{ matrix.features }}
66-
cargo test --workspace --exclude 'example_*' --exclude 'bdk_electrum' ${{ matrix.features }}
65+
cargo build --workspace --exclude 'bdk_electrum' ${{ matrix.features }}
66+
cargo test --workspace --exclude 'bdk_electrum' ${{ matrix.features }}
6767
else
68-
cargo build --workspace --exclude 'example_*' ${{ matrix.features }}
69-
cargo test --workspace --exclude 'example_*' ${{ matrix.features }}
68+
cargo build --workspace ${{ matrix.features }}
69+
cargo test --workspace ${{ matrix.features }}
7070
fi
7171
7272
check-no-std:
@@ -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/rust-cache@v2.7.8
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: 23 additions & 1 deletion
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,
@@ -350,7 +359,20 @@ where
350359
/// Each inserted transaction's anchor will be constructed using [`TxPosInBlock`].
351360
///
352361
/// Relevancy is determined by the internal [`Indexer::is_tx_relevant`] implementation of `I`.
353-
/// Irrelevant transactions in `txs` will be ignored.
362+
/// A transaction that conflicts with a relevant transaction is also considered relevant.
363+
/// Irrelevant transactions in `block` will be ignored.
364+
///
365+
/// # Example
366+
///
367+
/// ```no_run
368+
/// use bdk_chain::{IndexedTxGraph, keychain_txout::KeychainTxOutIndex, BlockId};
369+
/// use bitcoin::Block;
370+
///
371+
/// let mut graph = IndexedTxGraph::<BlockId, _>::new(KeychainTxOutIndex::<&str>::new(10, true));
372+
/// # let block = Block { header: bitcoin::block::Header::from(bitcoin::constants::genesis_block(bitcoin::Network::Bitcoin).header), txdata: vec![] };
373+
///
374+
/// let changeset = graph.apply_block_relevant(&block, 100);
375+
/// ```
354376
pub fn apply_block_relevant(
355377
&mut self,
356378
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: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,15 @@ 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+
/// ```no_run
34+
/// use bdk_electrum::{electrum_client, BdkElectrumClient};
35+
///
36+
/// let client = electrum_client::Client::new("ssl://electrum.blockstream.info:50002")?;
37+
/// let bdk_client = BdkElectrumClient::new(client);
38+
/// # Ok::<_, electrum_client::Error>(())
39+
/// ```
3140
pub fn new(client: E) -> Self {
3241
Self {
3342
inner: client,
@@ -90,6 +99,26 @@ impl<E: ElectrumApi> BdkElectrumClient<E> {
9099
/// [`CalculateFeeError::MissingTxOut`] error if those `TxOut`s are not present in the
91100
/// transaction graph.
92101
///
102+
/// # Example
103+
/// ```no_run
104+
/// use bdk_core::{spk_client::FullScanRequest, BlockId, CheckPoint};
105+
/// use bdk_electrum::BdkElectrumClient;
106+
/// # use bdk_electrum::electrum_client;
107+
/// # use electrum_client::bitcoin::{constants, Network};
108+
///
109+
/// # let client = electrum_client::Client::new("ssl://electrum.blockstream.info:50002")?;
110+
/// # let bdk_client = BdkElectrumClient::new(client);
111+
/// let request = FullScanRequest::<&str>::builder()
112+
/// .chain_tip(CheckPoint::new(BlockId {
113+
/// height: 0,
114+
/// hash: constants::genesis_block(Network::Bitcoin).block_hash(),
115+
/// }))
116+
/// .build();
117+
///
118+
/// let response = bdk_client.full_scan(request, 10, 50, false)?;
119+
/// # Ok::<_, electrum_client::Error>(())
120+
/// ```
121+
///
93122
/// [`bdk_chain`]: ../bdk_chain/index.html
94123
/// [`CalculateFeeError::MissingTxOut`]: ../bdk_chain/tx_graph/enum.CalculateFeeError.html#variant.MissingTxOut
95124
/// [`Wallet.calculate_fee`]: ../bdk_wallet/struct.Wallet.html#method.calculate_fee
@@ -173,6 +202,23 @@ impl<E: ElectrumApi> BdkElectrumClient<E> {
173202
/// If the scripts to sync are unknown, such as when restoring or importing a keychain that
174203
/// may include scripts that have been used, use [`full_scan`] with the keychain.
175204
///
205+
/// # Example
206+
/// ```no_run
207+
/// use bdk_core::bitcoin::ScriptBuf;
208+
/// use bdk_core::spk_client::SyncRequest;
209+
/// use bdk_electrum::BdkElectrumClient;
210+
/// # use bdk_electrum::electrum_client;
211+
///
212+
/// # let client = electrum_client::Client::new("ssl://electrum.blockstream.info:50002")?;
213+
/// # let bdk_client = BdkElectrumClient::new(client);
214+
/// let request = SyncRequest::builder()
215+
/// .spks([ScriptBuf::new_op_return(&[0x00; 20])])
216+
/// .build();
217+
///
218+
/// let response = bdk_client.sync(request, 50, false)?;
219+
/// # Ok::<_, electrum_client::Error>(())
220+
/// ```
221+
///
176222
/// [`full_scan`]: Self::full_scan
177223
/// [`bdk_chain`]: ../bdk_chain/index.html
178224
/// [`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)