Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/cont_integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ jobs:
cargo update -p parking_lot --precise "0.12.3"
cargo update -p parking_lot_core --precise "0.9.10"
cargo update -p lock_api --precise "0.4.12"
cargo update -p socket2@0.6.1 --precise "0.5.10"
cargo update -p socket2@0.6.2 --precise "0.5.10"
cargo update -p webpki-roots@1.0.5 --precise "1.0.1"
cargo update -p openssl --precise "0.10.73"
cargo update -p openssl-sys --precise "0.9.109"
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Bitcoin Esplora API client library. Supports plaintext, TLS and Onion servers. B
<p>
<a href="https://crates.io/crates/esplora-client"><img alt="Crate Info" src="https://img.shields.io/crates/v/esplora-client.svg"/></a>
<a href="https://github.com/bitcoindevkit/rust-esplora-client/blob/master/LICENSE"><img alt="MIT Licensed" src="https://img.shields.io/badge/license-MIT-blue.svg"/></a>
<a href="https://github.com/bitcoindevkit/rust-esplora-client/actions/workflows/cont_integration.yml"><img alt="CI Status" src="https://github.com/bitcoindevkit/rust-esplora-client/workflows/Rust/badge.svg"></a>
<a href="https://github.com/bitcoindevkit/rust-esplora-client/actions/workflows/cont_integration.yml"><img alt="CI Status" src="https://github.com/bitcoindevkit/rust-esplora-client/actions/workflows/cont_integration.yml/badge.svg?branch=release/0.12.x"></a>
<a href='https://coveralls.io/github/bitcoindevkit/rust-esplora-client?branch=master'><img src='https://coveralls.io/repos/github/bitcoindevkit/rust-esplora-client/badge.svg?branch=master' alt='Coverage Status' /></a>
<a href="https://docs.rs/esplora-client"><img alt="API Docs" src="https://img.shields.io/badge/docs.rs-esplora--client-green"/></a>
<a href="https://blog.rust-lang.org/2022/08/11/Rust-1.63.0.html"><img alt="Rustc Version 1.63.0+" src="https://img.shields.io/badge/rustc-1.63.0%2B-lightgrey.svg"/></a>
Expand Down Expand Up @@ -34,7 +34,7 @@ cargo update -p tracing-core --precise "0.1.33"
cargo update -p parking_lot --precise "0.12.3"
cargo update -p parking_lot_core --precise "0.9.10"
cargo update -p lock_api --precise "0.4.12"
cargo update -p socket2@0.6.1 --precise "0.5.10"
cargo update -p socket2@0.6.2 --precise "0.5.10"
cargo update -p webpki-roots@1.0.5 --precise "1.0.1"
cargo update -p openssl --precise "0.10.73"
cargo update -p openssl-sys --precise "0.9.109"
Expand Down
19 changes: 19 additions & 0 deletions src/async.rs
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,7 @@ impl<S: Sleeper> AsyncClient<S> {
///
/// The maximum number of summaries returned depends on the backend itself:
/// esplora returns `10` while [mempool.space](https://mempool.space/docs/api) returns `15`.
#[deprecated(since = "0.12.3", note = "use `get_block_infos` instead")]
pub async fn get_blocks(&self, height: Option<u32>) -> Result<Vec<BlockSummary>, Error> {
let path = match height {
Some(height) => format!("/blocks/{height}"),
Expand All @@ -576,6 +577,24 @@ impl<S: Sleeper> AsyncClient<S> {
Ok(blocks)
}

/// Get summaries about recent blocks as [`BlockInfo`]s,
/// starting at the tip, or at `height`, if provided.
///
/// The maximum number of elements returned depends on the backend itself:
/// - Esplora returns `10`
/// - [mempool.space](https://mempool.space/docs/api) returns `15`
pub async fn get_block_infos(&self, height: Option<u32>) -> Result<Vec<BlockInfo>, Error> {
let path = match height {
Some(height) => format!("/blocks/{height}"),
None => "/blocks".to_string(),
};
let blocks: Vec<BlockInfo> = self.get_response_json(&path).await?;
if blocks.is_empty() {
return Err(Error::InvalidResponse);
}
Ok(blocks)
}

/// Get all UTXOs locked to an address.
pub async fn get_address_utxos(&self, address: &Address) -> Result<Vec<Utxo>, Error> {
let path = format!("/address/{address}/utxo");
Expand Down
19 changes: 19 additions & 0 deletions src/blocking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,7 @@ impl BlockingClient {
///
/// The maximum number of summaries returned depends on the backend itself:
/// esplora returns `10` while [mempool.space](https://mempool.space/docs/api) returns `15`.
#[deprecated(since = "0.12.3", note = "use `get_block_infos` instead")]
pub fn get_blocks(&self, height: Option<u32>) -> Result<Vec<BlockSummary>, Error> {
let path = match height {
Some(height) => format!("/blocks/{height}"),
Expand All @@ -510,6 +511,24 @@ impl BlockingClient {
Ok(blocks)
}

/// Get summaries about recent blocks as [`BlockInfo`]s,
/// starting at the tip, or at `height`, if provided.
///
/// The maximum number of elements returned depends on the backend itself:
/// - Esplora returns `10`
/// - [mempool.space](https://mempool.space/docs/api) returns `15`
pub fn get_block_infos(&self, height: Option<u32>) -> Result<Vec<BlockInfo>, Error> {
let path = match height {
Some(height) => format!("/blocks/{height}"),
None => "/blocks".to_string(),
};
let blocks: Vec<BlockInfo> = self.get_response_json(&path)?;
if blocks.is_empty() {
return Err(Error::InvalidResponse);
}
Ok(blocks)
}

/// Get all UTXOs locked to an address.
pub fn get_address_utxos(&self, address: &Address) -> Result<Vec<Utxo>, Error> {
let path = format!("/address/{address}/utxo");
Expand Down
36 changes: 36 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1006,6 +1006,7 @@ mod test {
assert_eq!(txs_blocking.len(), txs_async.len());
}

#[allow(deprecated)]
#[cfg(all(feature = "blocking", feature = "async"))]
#[tokio::test]
async fn test_get_blocks() {
Expand Down Expand Up @@ -1035,6 +1036,41 @@ mod test {
assert_eq!(blocks_genesis, blocks_genesis_async);
}

#[cfg(all(feature = "blocking", feature = "async"))]
#[tokio::test]
async fn test_get_block_infos() {
let (blocking_client, async_client) = setup_clients().await;

let start_height = BITCOIND.client.get_block_count().unwrap().0;

let blocks_blocking_0 = blocking_client.get_block_infos(None).unwrap();
let blocks_async_0 = async_client.get_block_infos(None).await.unwrap();
assert_eq!(blocks_blocking_0[0].height, start_height as u32);
assert_eq!(blocks_blocking_0, blocks_async_0);

generate_blocks_and_wait(10);

let blocks_blocking_1 = blocking_client.get_block_infos(None).unwrap();
let blocks_async_1 = async_client.get_block_infos(None).await.unwrap();
assert_eq!(blocks_blocking_1, blocks_async_1);
assert_ne!(blocks_blocking_0, blocks_blocking_1);

let blocks_blocking_2 = blocking_client
.get_block_infos(Some(start_height as u32))
.unwrap();
let blocks_async_3 = async_client
.get_block_infos(Some(start_height as u32))
.await
.unwrap();
assert_eq!(blocks_blocking_2, blocks_async_3);
assert_eq!(blocks_blocking_2[0].height, start_height as u32);
assert_eq!(blocks_blocking_2, blocks_blocking_0);

let blocks_blocking_genesis = blocking_client.get_block_infos(Some(0)).unwrap();
let blocks_async_genesis = async_client.get_block_infos(Some(0)).await.unwrap();
assert_eq!(blocks_blocking_genesis, blocks_async_genesis);
}

#[cfg(all(feature = "blocking", feature = "async"))]
#[tokio::test]
async fn test_get_tx_with_http_header() {
Expand Down
Loading