diff --git a/crates/esplora/Cargo.toml b/crates/esplora/Cargo.toml index 3ebbd59c0..71ea4e8ed 100644 --- a/crates/esplora/Cargo.toml +++ b/crates/esplora/Cargo.toml @@ -16,12 +16,13 @@ workspace = true [dependencies] bdk_core = { path = "../core", version = "0.3.0", default-features = false } -esplora-client = { version = "0.10.0", default-features = false } +esplora-client = { version = "0.11.0", default-features = false } async-trait = { version = "0.1.66", optional = true } futures = { version = "0.3.26", optional = true } miniscript = { version = "12.0.0", optional = true, default-features = false } [dev-dependencies] +esplora-client = { version = "0.11.0" } bdk_chain = { path = "../chain" } bdk_testenv = { path = "../testenv" } tokio = { version = "1", features = ["rt", "rt-multi-thread", "macros"] } @@ -29,6 +30,7 @@ tokio = { version = "1", features = ["rt", "rt-multi-thread", "macros"] } [features] default = ["std", "async-https", "blocking-https"] std = ["bdk_chain/std", "miniscript?/std"] +tokio = ["esplora-client/tokio"] async = ["async-trait", "futures", "esplora-client/async"] async-https = ["async", "esplora-client/async-https"] async-https-rustls = ["async", "esplora-client/async-https-rustls"] diff --git a/crates/esplora/README.md b/crates/esplora/README.md index d06e386cd..244deb20f 100644 --- a/crates/esplora/README.md +++ b/crates/esplora/README.md @@ -10,17 +10,24 @@ The extension traits are primarily intended to satisfy [`SyncRequest`]s with [`s For blocking-only: ```toml -bdk_esplora = { version = "0.3", features = ["blocking"] } +bdk_esplora = { version = "0.19", features = ["blocking"] } ``` For async-only: ```toml -bdk_esplora = { version = "0.3", features = ["async"] } +bdk_esplora = { version = "0.19", features = ["async"] } ``` For async-only (with https): + +You can additionally specify to use either rustls or native-tls, e.g. `async-https-native`, and this applies to both async and blocking features. +```toml +bdk_esplora = { version = "0.19", features = ["async-https"] } +``` + +For async-only (with tokio): ```toml -bdk_esplora = { version = "0.3", features = ["async-https"] } +bdk_esplora = { version = "0.19", features = ["async", "tokio"] } ``` To use the extension traits: @@ -34,7 +41,7 @@ use bdk_esplora::EsploraExt; use bdk_esplora::EsploraAsyncExt; ``` -For full examples, refer to [`example-crates/wallet_esplora_blocking`](https://github.com/bitcoindevkit/bdk/tree/master/example-crates/wallet_esplora_blocking) and [`example-crates/wallet_esplora_async`](https://github.com/bitcoindevkit/bdk/tree/master/example-crates/wallet_esplora_async). +For full examples, refer to [`example_wallet_esplora_blocking`](https://github.com/bitcoindevkit/bdk/tree/master/example-crates/example_wallet_esplora_blocking) and [`example_wallet_esplora_async`](https://github.com/bitcoindevkit/bdk/tree/master/example-crates/example_wallet_esplora_async). [`esplora-client`]: https://docs.rs/esplora-client/ [`bdk_chain`]: https://docs.rs/bdk-chain/ diff --git a/crates/esplora/src/async_ext.rs b/crates/esplora/src/async_ext.rs index b9b7fa567..4c1bd0ad7 100644 --- a/crates/esplora/src/async_ext.rs +++ b/crates/esplora/src/async_ext.rs @@ -5,6 +5,7 @@ use bdk_core::{ bitcoin::{BlockHash, OutPoint, ScriptBuf, Txid}, BlockId, CheckPoint, ConfirmationBlockTime, Indexed, TxUpdate, }; +use esplora_client::Sleeper; use futures::{stream::FuturesOrdered, TryStreamExt}; use crate::{insert_anchor_from_status, insert_prevouts}; @@ -50,7 +51,11 @@ pub trait EsploraAsyncExt { #[cfg_attr(target_arch = "wasm32", async_trait(?Send))] #[cfg_attr(not(target_arch = "wasm32"), async_trait)] -impl EsploraAsyncExt for esplora_client::AsyncClient { +impl EsploraAsyncExt for esplora_client::AsyncClient +where + S: Sleeper + Clone + Send + Sync, + S::Sleep: Send, +{ async fn full_scan> + Send>( &self, request: R, @@ -165,8 +170,8 @@ impl EsploraAsyncExt for esplora_client::AsyncClient { /// block-based chain-sources). Therefore it's better to be conservative when setting the tip (use /// an earlier tip rather than a later tip) otherwise the caller may accidentally skip blocks when /// alternating between chain-sources. -async fn fetch_latest_blocks( - client: &esplora_client::AsyncClient, +async fn fetch_latest_blocks( + client: &esplora_client::AsyncClient, ) -> Result, Error> { Ok(client .get_blocks(None) @@ -179,8 +184,8 @@ async fn fetch_latest_blocks( /// Used instead of [`esplora_client::BlockingClient::get_block_hash`]. /// /// This first checks the previously fetched `latest_blocks` before fetching from Esplora again. -async fn fetch_block( - client: &esplora_client::AsyncClient, +async fn fetch_block( + client: &esplora_client::AsyncClient, latest_blocks: &BTreeMap, height: u32, ) -> Result, Error> { @@ -205,8 +210,8 @@ async fn fetch_block( /// /// We want to have a corresponding checkpoint per anchor height. However, checkpoints fetched /// should not surpass `latest_blocks`. -async fn chain_update( - client: &esplora_client::AsyncClient, +async fn chain_update( + client: &esplora_client::AsyncClient, latest_blocks: &BTreeMap, local_tip: &CheckPoint, anchors: &BTreeSet<(ConfirmationBlockTime, Txid)>, @@ -271,13 +276,17 @@ async fn chain_update( /// script pubkey that contains a non-empty transaction history. /// /// Refer to [crate-level docs](crate) for more. -async fn fetch_txs_with_keychain_spks> + Send>( - client: &esplora_client::AsyncClient, +async fn fetch_txs_with_keychain_spks( + client: &esplora_client::AsyncClient, inserted_txs: &mut HashSet, mut keychain_spks: I, stop_gap: usize, parallel_requests: usize, -) -> Result<(TxUpdate, Option), Error> { +) -> Result<(TxUpdate, Option), Error> +where + I: Iterator> + Send, + S: Sleeper + Clone + Send + Sync, +{ type TxsOfSpkIndex = (u32, Vec); let mut update = TxUpdate::::default(); @@ -346,14 +355,16 @@ async fn fetch_txs_with_keychain_spks> + S /// HTTP requests to make in parallel. /// /// Refer to [crate-level docs](crate) for more. -async fn fetch_txs_with_spks + Send>( - client: &esplora_client::AsyncClient, +async fn fetch_txs_with_spks( + client: &esplora_client::AsyncClient, inserted_txs: &mut HashSet, spks: I, parallel_requests: usize, ) -> Result, Error> where + I: IntoIterator + Send, I::IntoIter: Send, + S: Sleeper + Clone + Send + Sync, { fetch_txs_with_keychain_spks( client, @@ -372,14 +383,16 @@ where /// `parallel_requests` specifies the maximum number of HTTP requests to make in parallel. /// /// Refer to [crate-level docs](crate) for more. -async fn fetch_txs_with_txids + Send>( - client: &esplora_client::AsyncClient, +async fn fetch_txs_with_txids( + client: &esplora_client::AsyncClient, inserted_txs: &mut HashSet, txids: I, parallel_requests: usize, ) -> Result, Error> where + I: IntoIterator + Send, I::IntoIter: Send, + S: Sleeper + Clone + Send + Sync, { let mut update = TxUpdate::::default(); // Only fetch for non-inserted txs. @@ -421,14 +434,16 @@ where /// `parallel_requests` specifies the maximum number of HTTP requests to make in parallel. /// /// Refer to [crate-level docs](crate) for more. -async fn fetch_txs_with_outpoints + Send>( - client: &esplora_client::AsyncClient, +async fn fetch_txs_with_outpoints( + client: &esplora_client::AsyncClient, inserted_txs: &mut HashSet, outpoints: I, parallel_requests: usize, ) -> Result, Error> where + I: IntoIterator + Send, I::IntoIter: Send, + S: Sleeper + Clone + Send + Sync, { let outpoints = outpoints.into_iter().collect::>(); let mut update = TxUpdate::::default(); diff --git a/example-crates/example_wallet_esplora_async/Cargo.toml b/example-crates/example_wallet_esplora_async/Cargo.toml index 2121b72e9..38458b782 100644 --- a/example-crates/example_wallet_esplora_async/Cargo.toml +++ b/example-crates/example_wallet_esplora_async/Cargo.toml @@ -7,6 +7,6 @@ edition = "2021" [dependencies] bdk_wallet = { path = "../../crates/wallet", features = ["rusqlite"] } -bdk_esplora = { path = "../../crates/esplora", features = ["async-https"] } +bdk_esplora = { path = "../../crates/esplora", features = ["async-https", "tokio"] } tokio = { version = "1", features = ["rt", "rt-multi-thread", "macros"] } anyhow = "1"