Skip to content

Commit d2c1128

Browse files
committed
feat(client): add get_scripthash_stats method
1 parent 35f6a04 commit d2c1128

File tree

3 files changed

+153
-2
lines changed

3 files changed

+153
-2
lines changed

src/async.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,14 @@ impl<S: Sleeper> AsyncClient<S> {
395395
self.get_response_json(&path).await
396396
}
397397

398-
/// Get transaction history for the specified address/scripthash, sorted with newest first.
398+
/// Get statistics about a particular [`Script`] hash's confirmed and mempool transactions.
399+
pub async fn get_scripthash_stats(&self, script: &Script) -> Result<ScriptHashStats, Error> {
400+
let script_hash = sha256::Hash::hash(script.as_bytes());
401+
let path = format!("/scripthash/{script_hash}");
402+
self.get_response_json(&path).await
403+
}
404+
405+
/// Get transaction history for the specified address, sorted with newest first.
399406
///
400407
/// Returns up to 50 mempool transactions plus the first 25 confirmed transactions.
401408
/// More can be requested by specifying the last txid seen by the previous query.

src/blocking.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,15 @@ impl BlockingClient {
329329
self.get_response_json(&path)
330330
}
331331

332-
/// Get transaction history for the specified address/scripthash, sorted with newest first.
332+
/// Get statistics about a particular [`Script`] hash's confirmed and mempool transactions.
333+
pub fn get_scripthash_stats(&self, script: &Script) -> Result<ScriptHashStats, Error> {
334+
let script_hash = sha256::Hash::hash(script.as_bytes());
335+
let path = format!("/scripthash/{script_hash}");
336+
self.get_response_json(&path)
337+
}
338+
339+
/// Get transaction history for the specified address, sorted with newest
340+
/// first.
333341
///
334342
/// Returns up to 50 mempool transactions plus the first 25 confirmed transactions.
335343
/// More can be requested by specifying the last txid seen by the previous query.

src/lib.rs

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1011,6 +1011,142 @@ mod test {
10111011
assert_eq!(address_stats_async.chain_stats.funded_txo_sum, 1000);
10121012
}
10131013

1014+
#[cfg(all(feature = "blocking", feature = "async"))]
1015+
#[tokio::test]
1016+
async fn test_get_scripthash_stats() {
1017+
let (blocking_client, async_client) = setup_clients().await;
1018+
1019+
// Create an address of each type.
1020+
let address_legacy = BITCOIND
1021+
.client
1022+
.new_address_with_type(AddressType::Legacy)
1023+
.unwrap();
1024+
let address_p2sh_segwit = BITCOIND
1025+
.client
1026+
.new_address_with_type(AddressType::P2shSegwit)
1027+
.unwrap();
1028+
let address_bech32 = BITCOIND
1029+
.client
1030+
.new_address_with_type(AddressType::Bech32)
1031+
.unwrap();
1032+
let address_bech32m = BITCOIND
1033+
.client
1034+
.new_address_with_type(AddressType::Bech32m)
1035+
.unwrap();
1036+
1037+
// Send a transaction to each address.
1038+
let _txid = BITCOIND
1039+
.client
1040+
.send_to_address(&address_legacy, Amount::from_sat(1000))
1041+
.unwrap()
1042+
.txid()
1043+
.unwrap();
1044+
let _txid = BITCOIND
1045+
.client
1046+
.send_to_address(&address_p2sh_segwit, Amount::from_sat(1000))
1047+
.unwrap()
1048+
.txid()
1049+
.unwrap();
1050+
let _txid = BITCOIND
1051+
.client
1052+
.send_to_address(&address_bech32, Amount::from_sat(1000))
1053+
.unwrap()
1054+
.txid()
1055+
.unwrap();
1056+
let _txid = BITCOIND
1057+
.client
1058+
.send_to_address(&address_bech32m, Amount::from_sat(1000))
1059+
.unwrap()
1060+
.txid()
1061+
.unwrap();
1062+
1063+
let _miner = MINER.lock().await;
1064+
generate_blocks_and_wait(1);
1065+
1066+
// Derive each addresses script.
1067+
let script_legacy = address_legacy.script_pubkey();
1068+
let script_p2sh_segwit = address_p2sh_segwit.script_pubkey();
1069+
let script_bech32 = address_bech32.script_pubkey();
1070+
let script_bech32m = address_bech32m.script_pubkey();
1071+
1072+
// P2PKH
1073+
let scripthash_stats_blocking_legacy = blocking_client
1074+
.get_scripthash_stats(&script_legacy)
1075+
.unwrap();
1076+
let scripthash_stats_async_legacy = async_client
1077+
.get_scripthash_stats(&script_legacy)
1078+
.await
1079+
.unwrap();
1080+
assert_eq!(
1081+
scripthash_stats_blocking_legacy,
1082+
scripthash_stats_async_legacy
1083+
);
1084+
assert_eq!(
1085+
scripthash_stats_blocking_legacy.chain_stats.funded_txo_sum,
1086+
1000
1087+
);
1088+
assert_eq!(scripthash_stats_blocking_legacy.chain_stats.tx_count, 1);
1089+
1090+
// P2SH-P2WSH
1091+
let scripthash_stats_blocking_p2sh_segwit = blocking_client
1092+
.get_scripthash_stats(&script_p2sh_segwit)
1093+
.unwrap();
1094+
let scripthash_stats_async_p2sh_segwit = async_client
1095+
.get_scripthash_stats(&script_p2sh_segwit)
1096+
.await
1097+
.unwrap();
1098+
assert_eq!(
1099+
scripthash_stats_blocking_p2sh_segwit,
1100+
scripthash_stats_async_p2sh_segwit
1101+
);
1102+
assert_eq!(
1103+
scripthash_stats_blocking_p2sh_segwit
1104+
.chain_stats
1105+
.funded_txo_sum,
1106+
1000
1107+
);
1108+
assert_eq!(
1109+
scripthash_stats_blocking_p2sh_segwit.chain_stats.tx_count,
1110+
1
1111+
);
1112+
1113+
// P2WPKH / P2WSH
1114+
let scripthash_stats_blocking_bech32 = blocking_client
1115+
.get_scripthash_stats(&script_bech32)
1116+
.unwrap();
1117+
let scripthash_stats_async_bech32 = async_client
1118+
.get_scripthash_stats(&script_bech32)
1119+
.await
1120+
.unwrap();
1121+
assert_eq!(
1122+
scripthash_stats_blocking_bech32,
1123+
scripthash_stats_async_bech32
1124+
);
1125+
assert_eq!(
1126+
scripthash_stats_blocking_bech32.chain_stats.funded_txo_sum,
1127+
1000
1128+
);
1129+
assert_eq!(scripthash_stats_blocking_bech32.chain_stats.tx_count, 1);
1130+
1131+
// P2TR
1132+
let scripthash_stats_blocking_bech32m = blocking_client
1133+
.get_scripthash_stats(&script_bech32m)
1134+
.unwrap();
1135+
let scripthash_stats_async_bech32m = async_client
1136+
.get_scripthash_stats(&script_bech32m)
1137+
.await
1138+
.unwrap();
1139+
assert_eq!(
1140+
scripthash_stats_blocking_bech32m,
1141+
scripthash_stats_async_bech32m
1142+
);
1143+
assert_eq!(
1144+
scripthash_stats_blocking_bech32m.chain_stats.funded_txo_sum,
1145+
1000
1146+
);
1147+
assert_eq!(scripthash_stats_blocking_bech32m.chain_stats.tx_count, 1);
1148+
}
1149+
10141150
#[cfg(all(feature = "blocking", feature = "async"))]
10151151
#[tokio::test]
10161152
async fn test_get_address_txs() {

0 commit comments

Comments
 (0)