diff --git a/src/api.rs b/src/api.rs index 7287614..b0c19b6 100644 --- a/src/api.rs +++ b/src/api.rs @@ -33,6 +33,9 @@ pub trait ElectrumApi { Ok(deserialize(&self.transaction_get_raw(txid)?)?) } + /// Gets the verbose transaction with `txid`. Returns an error if not found. + fn transaction_get_verbose(&self, txid: &Txid) -> Result; + /// Batch version of [`transaction_get`](#method.transaction_get). /// /// Takes a list of `txids` and returns a list of transactions. diff --git a/src/client.rs b/src/client.rs index d7bc127..c242023 100644 --- a/src/client.rs +++ b/src/client.rs @@ -252,6 +252,11 @@ impl ElectrumApi for Client { impl_inner_call!(self, batch_script_list_unspent, scripts.clone()) } + #[inline] + fn transaction_get_verbose(&self, txid: &Txid) -> Result { + impl_inner_call!(self, transaction_get_verbose, txid) + } + #[inline] fn transaction_get_raw(&self, txid: &Txid) -> Result, Error> { impl_inner_call!(self, transaction_get_raw, txid) diff --git a/src/raw_client.rs b/src/raw_client.rs index 509aa68..a43eab8 100644 --- a/src/raw_client.rs +++ b/src/raw_client.rs @@ -891,6 +891,18 @@ impl ElectrumApi for RawClient { impl_batch_call!(self, scripts, script_list_unspent) } + fn transaction_get_verbose(&self, txid: &Txid) -> Result { + let params = vec![Param::String(txid.to_hex()), Param::Bool(true)]; + let req = Request::new_id( + self.last_id.fetch_add(1, Ordering::SeqCst), + "blockchain.transaction.get", + params, + ); + let result = self.call(req)?; + let res = serde_json::from_value(result).unwrap(); + Ok(res) + } + fn transaction_get_raw(&self, txid: &Txid) -> Result, Error> { let params = vec![Param::String(txid.to_hex())]; let req = Request::new_id( @@ -1166,6 +1178,27 @@ mod test { assert_eq!(resp.lock_time, 0); } + #[test] + fn test_transaction_get_verbose() { + use bitcoin::hashes::hex::FromHex; + use bitcoin::Txid; + + let client = RawClient::new(get_test_server(), None).unwrap(); + + let resp = client.transaction_get_verbose( + &Txid::from_hex("5b867a8468518450d78a4f60dc21e11248db87ceb3eeec634e7c5af7e8b909a1") + .unwrap(), + ); + + match resp { + Err(e) => assert_eq!( + e.to_string(), + "Electrum server error: \"verbose transactions are currently unsupported\"", + ), + Ok(v) => assert_eq!(v.time.unwrap(), 1626901917), + } + } + #[test] fn test_transaction_get_raw() { use bitcoin::hashes::hex::FromHex; diff --git a/src/types.rs b/src/types.rs index 2facf13..bc5dd23 100644 --- a/src/types.rs +++ b/src/types.rs @@ -2,6 +2,7 @@ //! //! This module contains definitions of all the complex data structures that are returned by calls +use bitcoin::BlockHash; use std::convert::TryFrom; use std::fmt::{self, Display, Formatter}; use std::ops::Deref; @@ -213,6 +214,40 @@ pub struct GetBalanceRes { pub unconfirmed: i64, } +// TODO: Implement transaction serialization for inputs and outputs, for +// example with pub vin: Vec and pub vout: Vec + +/// Response to a [`transaction_get`](../client/struct.Client.html#method.transaction_get) request +/// with the verbose true flag set +#[derive(Debug, Deserialize, Serialize)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +pub struct GetTransactionVerboseRes { + /// Block hash of the block containing the transaction. + #[serde(default)] + pub blockhash: Option, + /// Block time of the block containing the transaction. + #[serde(default)] + pub blocktime: Option, + /// Confirmations of the transaction + #[serde(default)] + pub confirmations: Option, + /// Same as blocktime + #[serde(default)] + pub time: Option, + /// The transaction hash (differs from txid for witness transactions) + pub hash: Txid, + /// The serialized, hex-encoded data for 'txid' + pub hex: String, + /// nLocktime of the transaction + pub locktime: u32, + /// Size of the serialized transaction + pub size: usize, + /// Id of the transaction + pub txid: Txid, + /// Version of the transaction + pub version: i32, +} + /// Response to a [`transaction_get_merkle`](../client/struct.Client.html#method.transaction_get_merkle) request. #[derive(Debug, Deserialize)] pub struct GetMerkleRes {