diff --git a/src/api.rs b/src/api.rs index 78ec784..f84a4d3 100644 --- a/src/api.rs +++ b/src/api.rs @@ -18,7 +18,6 @@ use serde::Deserialize; use std::collections::HashMap; pub use bitcoin::consensus::{deserialize, serialize}; -use bitcoin::hash_types::TxMerkleNode; pub use bitcoin::hex::FromHex; pub use bitcoin::{ absolute, block, transaction, Address, Amount, Block, BlockHash, CompactTarget, FeeRate, @@ -26,15 +25,6 @@ pub use bitcoin::{ Wtxid, }; -/// Information about a previous output. -#[derive(Deserialize, Clone, Debug, PartialEq, Eq)] -pub struct PrevOut { - /// The value of the previous output, in satoshis. - pub value: u64, - /// The ScriptPubKey that the previous output is locked to, as a [`ScriptBuf`]. - pub scriptpubkey: ScriptBuf, -} - /// Information about an input from a [`Transaction`]. #[derive(Deserialize, Clone, Debug, PartialEq, Eq)] pub struct Vin { @@ -44,7 +34,7 @@ pub struct Vin { pub vout: u32, /// The previous output amount and ScriptPubKey. /// `None` if this is a coinbase input. - pub prevout: Option, + pub prevout: Option, /// The ScriptSig authorizes spending this input. pub scriptsig: ScriptBuf, /// The Witness that authorizes spending this input, if this is a SegWit spend. @@ -60,7 +50,8 @@ pub struct Vin { #[derive(Deserialize, Clone, Debug, PartialEq, Eq)] pub struct Vout { /// The value of the output, in satoshis. - pub value: u64, + #[serde(with = "bitcoin::amount::serde::as_sat")] + pub value: Amount, /// The ScriptPubKey that the output is locked to, as a [`ScriptBuf`]. pub scriptpubkey: ScriptBuf, } @@ -135,11 +126,12 @@ pub struct Tx { /// The [`Transaction`] size in raw bytes (NOT virtual bytes). pub size: usize, /// The [`Transaction`]'s weight units. - pub weight: u64, + pub weight: Weight, /// The confirmation status of the [`Transaction`]. pub status: TxStatus, /// The fee amount paid by the [`Transaction`], in satoshis. - pub fee: u64, + #[serde(with = "bitcoin::amount::serde::as_sat")] + pub fee: Amount, } /// Information about a bitcoin [`Block`]. @@ -204,20 +196,6 @@ pub struct BlockTime { pub height: u32, } -/// Summary about a [`Block`]. -#[derive(Debug, Clone, Deserialize, PartialEq, Eq)] -pub struct BlockSummary { - /// The [`Block`]'s hash. - pub id: BlockHash, - /// The [`Block`]'s timestamp and height. - #[serde(flatten)] - pub time: BlockTime, - /// The [`BlockHash`] of the previous [`Block`] (`None` for the genesis [`Block`]). - pub previousblockhash: Option, - /// The Merkle root of the [`Block`]'s [`Transaction`]s. - pub merkle_root: TxMerkleNode, -} - /// Statistics about an [`Address`]. #[derive(Debug, Clone, Deserialize, PartialEq, Eq)] pub struct AddressStats { @@ -235,11 +213,13 @@ pub struct AddressTxsSummary { /// The number of funded [`TxOut`]s. pub funded_txo_count: u32, /// The sum of the funded [`TxOut`]s, in satoshis. - pub funded_txo_sum: u64, + #[serde(with = "bitcoin::amount::serde::as_sat")] + pub funded_txo_sum: Amount, /// The number of spent [`TxOut`]s. pub spent_txo_count: u32, /// The sum of the spent [`TxOut`]s, in satoshis. - pub spent_txo_sum: u64, + #[serde(with = "bitcoin::amount::serde::as_sat")] + pub spent_txo_sum: Amount, /// The total number of [`Transaction`]s. pub tx_count: u32, } @@ -280,6 +260,7 @@ pub struct Utxo { /// The confirmation status of the [`TxOut`]. pub status: UtxoStatus, /// The value of the [`TxOut`] as an [`Amount`]. + #[serde(with = "bitcoin::amount::serde::as_sat")] pub value: Amount, } @@ -291,7 +272,8 @@ pub struct MempoolStats { /// The total size of mempool [`Transaction`]s, in virtual bytes. pub vsize: usize, /// The total fee paid by mempool [`Transaction`]s, in satoshis. - pub total_fee: u64, + #[serde(with = "bitcoin::amount::serde::as_sat")] + pub total_fee: Amount, /// The mempool's fee rate distribution histogram. /// /// An array of `(feerate, vsize)` tuples, where each entry's `vsize` is the total vsize @@ -306,11 +288,13 @@ pub struct MempoolRecentTx { /// The [`Transaction`]'s ID, as a [`Txid`]. pub txid: Txid, /// The [`Amount`] of fees paid by the transaction, in satoshis. - pub fee: u64, + #[serde(with = "bitcoin::amount::serde::as_sat")] + pub fee: Amount, /// The [`Transaction`]'s size, in virtual bytes. pub vsize: usize, /// Combined [`Amount`] of the [`Transaction`], in satoshis. - pub value: u64, + #[serde(with = "bitcoin::amount::serde::as_sat")] + pub value: Amount, } /// The result for a broadcasted package of [`Transaction`]s. @@ -394,7 +378,7 @@ impl Tx { .iter() .cloned() .map(|vout| TxOut { - value: Amount::from_sat(vout.value), + value: vout.value, script_pubkey: vout.scriptpubkey, }) .collect(), @@ -422,21 +406,11 @@ impl Tx { .map(|vin| { vin.prevout.map(|po| TxOut { script_pubkey: po.scriptpubkey, - value: Amount::from_sat(po.value), + value: po.value, }) }) .collect() } - - /// Get the weight of a [`Tx`]. - pub fn weight(&self) -> Weight { - Weight::from_wu(self.weight) - } - - /// Get the fee paid by a [`Tx`]. - pub fn fee(&self) -> Amount { - Amount::from_sat(self.fee) - } } fn deserialize_witness<'de, D>(d: D) -> Result>, D::Error> diff --git a/src/async.rs b/src/async.rs index 2a6cf52..a5190e0 100644 --- a/src/async.rs +++ b/src/async.rs @@ -29,9 +29,9 @@ use log::{debug, error, info, trace}; use reqwest::{header, Body, Client, Response}; use crate::{ - AddressStats, BlockInfo, BlockStatus, BlockSummary, Builder, Error, MempoolRecentTx, - MempoolStats, MerkleProof, OutputStatus, ScriptHashStats, SubmitPackageResult, Tx, TxStatus, - Utxo, BASE_BACKOFF_MILLIS, RETRYABLE_ERROR_CODES, + AddressStats, BlockInfo, BlockStatus, Builder, Error, MempoolRecentTx, MempoolStats, + MerkleProof, OutputStatus, ScriptHashStats, SubmitPackageResult, Tx, TxStatus, Utxo, + BASE_BACKOFF_MILLIS, RETRYABLE_ERROR_CODES, }; /// An async client for interacting with an Esplora API server. @@ -477,11 +477,11 @@ impl AsyncClient { self.get_response_json(&path).await } - /// Get transaction history for the specified address/scripthash, - /// sorted with newest first. Returns 25 transactions per page. - /// More can be requested by specifying the last txid seen by the previous - /// query. - pub async fn scripthash_txs( + /// Get transaction history for the specified [`Script`] hash, + /// sorted by newest first. Returns 25 transactions per page. + /// More can be requested by specifying + /// the last [`Txid`] seen by the previous query. + pub async fn get_scripthash_txs( &self, script: &Script, last_seen: Option, @@ -564,12 +564,12 @@ impl AsyncClient { /// /// The maximum number of summaries returned depends on the backend itself: /// esplora returns `10` while [mempool.space](https://mempool.space/docs/api) returns `15`. - pub async fn get_blocks(&self, height: Option) -> Result, Error> { + pub async fn get_blocks(&self, height: Option) -> Result, Error> { let path = match height { Some(height) => format!("/blocks/{height}"), None => "/blocks".to_string(), }; - let blocks: Vec = self.get_response_json(&path).await?; + let blocks: Vec = self.get_response_json(&path).await?; if blocks.is_empty() { return Err(Error::InvalidResponse); } diff --git a/src/blocking.rs b/src/blocking.rs index 23425a4..a208869 100644 --- a/src/blocking.rs +++ b/src/blocking.rs @@ -29,9 +29,9 @@ use bitcoin::hex::{DisplayHex, FromHex}; use bitcoin::{Address, Block, BlockHash, MerkleBlock, Script, Transaction, Txid}; use crate::{ - AddressStats, BlockInfo, BlockStatus, BlockSummary, Builder, Error, MempoolRecentTx, - MempoolStats, MerkleProof, OutputStatus, ScriptHashStats, SubmitPackageResult, Tx, TxStatus, - Utxo, BASE_BACKOFF_MILLIS, RETRYABLE_ERROR_CODES, + AddressStats, BlockInfo, BlockStatus, Builder, Error, MempoolRecentTx, MempoolStats, + MerkleProof, OutputStatus, ScriptHashStats, SubmitPackageResult, Tx, TxStatus, Utxo, + BASE_BACKOFF_MILLIS, RETRYABLE_ERROR_CODES, }; /// A blocking client for interacting with an Esplora API server. @@ -436,11 +436,11 @@ impl BlockingClient { self.get_response_json(&path) } - /// Get transaction history for the specified scripthash, - /// sorted with newest first. Returns 25 transactions per page. - /// More can be requested by specifying the last txid seen by the previous - /// query. - pub fn scripthash_txs( + /// Get transaction history for the specified [`Script`] hash, + /// sorted by newest first. Returns 25 transactions per page. + /// More can be requested by specifying + /// the last [`Txid`] seen by the previous query. + pub fn get_scripthash_txs( &self, script: &Script, last_seen: Option, @@ -494,17 +494,17 @@ impl BlockingClient { self.get_response_json(&path) } - /// Gets some recent block summaries starting at the tip or at `height` if - /// provided. + /// Get recent block summaries starting at the tip, + /// or at `height` if provided. /// /// The maximum number of summaries returned depends on the backend itself: /// esplora returns `10` while [mempool.space](https://mempool.space/docs/api) returns `15`. - pub fn get_blocks(&self, height: Option) -> Result, Error> { + pub fn get_blocks(&self, height: Option) -> Result, Error> { let path = match height { Some(height) => format!("/blocks/{height}"), None => "/blocks".to_string(), }; - let blocks: Vec = self.get_response_json(&path)?; + let blocks: Vec = self.get_response_json(&path)?; if blocks.is_empty() { return Err(Error::InvalidResponse); } diff --git a/src/lib.rs b/src/lib.rs index d5bb38c..637e3ba 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -574,8 +574,8 @@ mod test { assert_eq!(tx_info.txid, txid); assert_eq!(tx_info.to_tx(), tx_exp); assert_eq!(tx_info.size, tx_exp.total_size()); - assert_eq!(tx_info.weight(), tx_exp.weight()); - assert_eq!(tx_info.fee(), tx_res.fee.unwrap().unsigned_abs()); + assert_eq!(tx_info.weight, tx_exp.weight()); + assert_eq!(tx_info.fee, tx_res.fee.unwrap().unsigned_abs()); assert!(tx_info.status.confirmed); assert_eq!(tx_info.status.block_height, Some(tx_block_height)); assert_eq!(tx_info.status.block_hash, tx_res.block_hash); @@ -915,13 +915,13 @@ mod test { .tx; let script = &expected_tx.output[0].script_pubkey; let scripthash_txs_txids: Vec = blocking_client - .scripthash_txs(script, None) + .get_scripthash_txs(script, None) .unwrap() .iter() .map(|tx| tx.txid) .collect(); let scripthash_txs_txids_async: Vec = async_client - .scripthash_txs(script, None) + .get_scripthash_txs(script, None) .await .unwrap() .iter() @@ -1013,7 +1013,7 @@ mod test { let start_height = BITCOIND.client.get_block_count().unwrap().0; let blocks1 = blocking_client.get_blocks(None).unwrap(); let blocks_async1 = async_client.get_blocks(None).await.unwrap(); - assert_eq!(blocks1[0].time.height, start_height as u32); + assert_eq!(blocks1[0].height, start_height as u32); assert_eq!(blocks1, blocks_async1); generate_blocks_and_wait(10); let blocks2 = blocking_client.get_blocks(None).unwrap(); @@ -1028,7 +1028,7 @@ mod test { .await .unwrap(); assert_eq!(blocks3, blocks_async3); - assert_eq!(blocks3[0].time.height, start_height as u32); + assert_eq!(blocks3[0].height, start_height as u32); assert_eq!(blocks3, blocks1); let blocks_genesis = blocking_client.get_blocks(Some(0)).unwrap(); let blocks_genesis_async = async_client.get_blocks(Some(0)).await.unwrap(); @@ -1092,7 +1092,10 @@ mod test { let address_stats_async = async_client.get_address_stats(&address).await.unwrap(); assert_eq!(address_stats_blocking, address_stats_async); assert_eq!(address_stats_async.chain_stats.funded_txo_count, 1); - assert_eq!(address_stats_async.chain_stats.funded_txo_sum, 1000); + assert_eq!( + address_stats_async.chain_stats.funded_txo_sum, + Amount::from_sat(1000) + ); } #[cfg(all(feature = "blocking", feature = "async"))] @@ -1167,7 +1170,7 @@ mod test { ); assert_eq!( scripthash_stats_blocking_legacy.chain_stats.funded_txo_sum, - 1000 + Amount::from_sat(1000) ); assert_eq!(scripthash_stats_blocking_legacy.chain_stats.tx_count, 1); @@ -1187,7 +1190,7 @@ mod test { scripthash_stats_blocking_p2sh_segwit .chain_stats .funded_txo_sum, - 1000 + Amount::from_sat(1000) ); assert_eq!( scripthash_stats_blocking_p2sh_segwit.chain_stats.tx_count, @@ -1208,7 +1211,7 @@ mod test { ); assert_eq!( scripthash_stats_blocking_bech32.chain_stats.funded_txo_sum, - 1000 + Amount::from_sat(1000) ); assert_eq!(scripthash_stats_blocking_bech32.chain_stats.tx_count, 1); @@ -1226,7 +1229,7 @@ mod test { ); assert_eq!( scripthash_stats_blocking_bech32m.chain_stats.funded_txo_sum, - 1000 + Amount::from_sat(1000) ); assert_eq!(scripthash_stats_blocking_bech32m.chain_stats.tx_count, 1); }