Skip to content

Commit 5fd22fd

Browse files
committed
docs: add example for EsploraClient with timeout configuration
Add a new example demonstrating how to configure EsploraClient with custom timeout and retry settings. This is useful for developers working with slow or unreliable network connections. The example shows: - Setting socket timeout using Builder::timeout() - Configuring max retries using Builder::max_retries() - Handling timeout-related errors gracefully Closes #260 Signed-off-by: Eeshu-Yadav <eeshuyadav123@gmail.com>
1 parent 8f8a8e9 commit 5fd22fd

3 files changed

Lines changed: 116 additions & 4 deletions

File tree

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,5 +72,8 @@ name = "esplora_async"
7272
[[example]]
7373
name = "esplora_blocking"
7474

75+
[[example]]
76+
name = "esplora_with_timeout"
77+
7578
[[example]]
7679
name = "bitcoind_rpc"

README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,11 @@ that the `Wallet` can use to update its view of the chain.
6161

6262
**Examples**
6363

64-
* [`examples/esplora_async`](https://github.com/bitcoindevkit/bdk_wallet/blob/master/examples/esplora_async.rs)
65-
* [`examples/esplora_blocking`](https://github.com/bitcoindevkit/bdk_wallet/blob/master/examples/esplora_blocking.rs)
66-
* [`examples/electrum`](https://github.com/bitcoindevkit/bdk_wallet/blob/master/examples/electrum.rs)
67-
* [`examples/bitcoind_rpc`](https://github.com/bitcoindevkit/bdk_wallet/blob/master/examples/bitcoind_rpc.rs)
64+
* [`examples/esplora_async`](https://github.com/bitcoindevkit/bdk_wallet/tree/master/examples/esplora_async)
65+
* [`examples/esplora_blocking`](https://github.com/bitcoindevkit/bdk_wallet/tree/master/examples/esplora_blocking)
66+
* [`examples/esplora_with_timeout`](https://github.com/bitcoindevkit/bdk_wallet/tree/master/examples/esplora_with_timeout)
67+
* [`examples/electrum`](https://github.com/bitcoindevkit/bdk_wallet/tree/master/examples/electrum)
68+
* [`examples/bitcoind_rpc`](https://github.com/bitcoindevkit/bdk_wallet/tree/master/examples/bitcoind_rpc)
6869

6970
## Persistence
7071

examples/esplora_with_timeout.rs

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
//! Example demonstrating how to configure EsploraClient with custom timeout settings.
2+
3+
use bdk_esplora::{esplora_client, EsploraExt};
4+
use bdk_wallet::{bitcoin::Network, rusqlite::Connection, KeychainKind, Wallet};
5+
use std::{collections::BTreeSet, io::Write};
6+
7+
const STOP_GAP: usize = 5;
8+
const PARALLEL_REQUESTS: usize = 5;
9+
10+
const DB_PATH: &str = "bdk-example-esplora-timeout.sqlite";
11+
const NETWORK: Network = Network::Testnet4;
12+
const EXTERNAL_DESC: &str = "wpkh(tprv8ZgxMBicQKsPdy6LMhUtFHAgpocR8GC6QmwMSFpZs7h6Eziw3SpThFfczTDh5rW2krkqffa11UpX3XkeTTB2FvzZKWXqPY54Y6Rq4AQ5R8L/84'/1'/0'/0/*)";
13+
const INTERNAL_DESC: &str = "wpkh(tprv8ZgxMBicQKsPdy6LMhUtFHAgpocR8GC6QmwMSFpZs7h6Eziw3SpThFfczTDh5rW2krkqffa11UpX3XkeTTB2FvzZKWXqPY54Y6Rq4AQ5R8L/84'/1'/0'/1/*)";
14+
const ESPLORA_URL: &str = "https://mempool.space/testnet4/api";
15+
16+
const TIMEOUT_SECS: u64 = 30;
17+
const MAX_RETRIES: usize = 3;
18+
19+
fn main() -> Result<(), anyhow::Error> {
20+
let mut db = Connection::open(DB_PATH)?;
21+
let wallet_opt = Wallet::load()
22+
.descriptor(KeychainKind::External, Some(EXTERNAL_DESC))
23+
.descriptor(KeychainKind::Internal, Some(INTERNAL_DESC))
24+
.extract_keys()
25+
.check_network(NETWORK)
26+
.load_wallet(&mut db)?;
27+
let mut wallet = match wallet_opt {
28+
Some(wallet) => wallet,
29+
None => Wallet::create(EXTERNAL_DESC, INTERNAL_DESC)
30+
.network(NETWORK)
31+
.create_wallet(&mut db)?,
32+
};
33+
34+
let address = wallet.next_unused_address(KeychainKind::External);
35+
wallet.persist(&mut db)?;
36+
println!(
37+
"Next unused address: ({}) {}",
38+
address.index, address.address
39+
);
40+
41+
let balance = wallet.balance();
42+
println!("Wallet balance before syncing: {}", balance.total());
43+
44+
// Configure EsploraClient with custom timeout and retry settings.
45+
// Available builder options:
46+
// - timeout(secs): Socket timeout in seconds
47+
// - max_retries(count): Retries on HTTP codes 408, 425, 429, 500, 502, 503, 504
48+
// - proxy(url): Proxy server URL
49+
// - header(key, value): Custom HTTP header
50+
println!(
51+
"Creating Esplora client with {TIMEOUT_SECS}s timeout and {MAX_RETRIES} max retries..."
52+
);
53+
let client = esplora_client::Builder::new(ESPLORA_URL)
54+
.timeout(TIMEOUT_SECS)
55+
.max_retries(MAX_RETRIES)
56+
.build_blocking();
57+
58+
println!("Starting full sync...");
59+
let request = wallet.start_full_scan().inspect({
60+
let mut stdout = std::io::stdout();
61+
let mut once = BTreeSet::<KeychainKind>::new();
62+
move |keychain, spk_i, _| {
63+
if once.insert(keychain) {
64+
print!("\nScanning keychain [{keychain:?}] ");
65+
}
66+
print!(" {spk_i:<3}");
67+
stdout.flush().expect("must flush")
68+
}
69+
});
70+
71+
match client.full_scan(request, STOP_GAP, PARALLEL_REQUESTS) {
72+
Ok(update) => {
73+
wallet.apply_update(update)?;
74+
wallet.persist(&mut db)?;
75+
76+
let balance = wallet.balance();
77+
println!("\nWallet balance after syncing: {}", balance.total());
78+
}
79+
Err(e) => {
80+
eprintln!("\nSync failed: {e}");
81+
eprintln!(
82+
"Tips: increase timeout/max_retries, check connectivity, or try another server"
83+
);
84+
return Err(e.into());
85+
}
86+
}
87+
88+
println!("\nFetching current block height...");
89+
match client.get_height() {
90+
Ok(height) => println!("Current block height: {height}"),
91+
Err(e) => eprintln!("Failed to get block height: {e}"),
92+
}
93+
94+
println!("\nFetching fee estimates...");
95+
match client.get_fee_estimates() {
96+
Ok(estimates) => {
97+
println!("Fee estimates (sat/vB):");
98+
for (target, rate) in estimates.iter().take(5) {
99+
println!(" {} blocks: {:.1} sat/vB", target, rate);
100+
}
101+
}
102+
Err(e) => {
103+
eprintln!("Failed to get fee estimates: {e}");
104+
}
105+
}
106+
107+
Ok(())
108+
}

0 commit comments

Comments
 (0)