rust_mempool/api/
addresses.rs

1use std::collections::HashMap;
2
3use anyhow::Result;
4
5use crate::Utxo;
6
7impl crate::MempoolClient {
8    pub async fn get_address_utxo(&self, address: &str) -> Result<Vec<Utxo>> {
9        let url = format!("{}/address/{}/utxo", self.base_url, address);
10        let response = self.client.get(&url).send().await?.error_for_status()?;
11        Ok(response.json().await?)
12    }
13
14    pub async fn get_batch_of_addresses_utxo(
15        &self,
16        addresses: &[&str],
17    ) -> Result<HashMap<String, Vec<Utxo>>> {
18        use futures::future::join_all;
19        use tokio::time::{sleep, Duration};
20        let mut futures = Vec::with_capacity(addresses.len());
21
22        // avoid rate limit
23        const DELAY_MS: u64 = 100;
24
25        for (i, address) in addresses.iter().enumerate() {
26            if i > 0 {
27                sleep(Duration::from_millis(DELAY_MS)).await;
28            }
29            let future = async move { self.get_address_utxo(address).await };
30            futures.push(future);
31        }
32
33        let responses = join_all(futures).await;
34
35        let mut result: HashMap<String, Vec<Utxo>> = HashMap::new();
36
37        for (index, response) in responses.into_iter().enumerate() {
38            if let Ok(r) = response {
39                let address = addresses[index].to_string();
40                result.insert(address, r);
41            }
42        }
43
44        Ok(result)
45    }
46}
47
48#[cfg(test)]
49mod tests {
50    use bitcoin::Network;
51
52    use crate::client::MempoolClient;
53
54    #[tokio::test]
55    async fn test_get_address_utxo() {
56        let client = MempoolClient::new(Network::Bitcoin);
57
58        let utxos = client
59            .get_address_utxo("1KFHE7w8BhaENAswwryaoccDb6qcT6DbYY")
60            .await
61            .unwrap();
62        println!("{:?}", utxos);
63    }
64
65    #[tokio::test]
66    async fn test_get_batch_of_addresses_utxo() {
67        let client = MempoolClient::new(Network::Bitcoin);
68        let addresses = vec!["1KFHE7w8BhaENAswwryaoccDb6qcT6DbYY", "123"];
69
70        let result = client.get_batch_of_addresses_utxo(&addresses).await;
71        assert!(
72            result.is_ok(),
73            "Batch UTXO fetch failed: {:?}",
74            result.err()
75        );
76
77        let utxos = result.unwrap();
78        assert_eq!(utxos.len(), 1, "Expected UTXOs for 1 address");
79
80        for (i, address_utxos) in utxos.iter().enumerate() {
81            println!(
82                "Address {}: {} UTXOs found",
83                addresses[i],
84                address_utxos.1.len()
85            );
86        }
87    }
88}