electrum_client/
batch.rs

1//! Batch utilities
2//!
3//! This module contains definitions and helper functions used when making batch calls.
4
5use bitcoin::{Script, Txid};
6
7use crate::types::{Call, Param, ToElectrumScriptHash};
8
9/// Helper structure that caches all the requests before they are actually sent to the server.
10///
11/// Calls on this function are stored and run when [`batch_call`](../client/struct.Client.html#method.batch_call)
12/// is run on a [`Client`](../client/struct.Client.html).
13///
14/// This structure can be used to make multiple *different* calls in one single run. For batch
15/// calls of the same type, there are shorthands methods defined on the
16/// [`Client`](../client/struct.Client.html), like
17/// [`batch_script_get_balance`](../client/struct.Client.html#method.batch_script_get_balance) to ask the
18/// server for the balance of multiple scripts with a single request.
19#[derive(Default)]
20pub struct Batch {
21    calls: Vec<Call>,
22}
23
24impl Batch {
25    /// Add a raw request to the batch queue
26    pub fn raw(&mut self, method: String, params: Vec<Param>) {
27        self.calls.push((method, params));
28    }
29
30    /// Add one `blockchain.scripthash.listunspent` request to the batch queue
31    pub fn script_list_unspent(&mut self, script: &Script) {
32        let params = vec![Param::String(script.to_electrum_scripthash().to_hex())];
33        self.calls
34            .push((String::from("blockchain.scripthash.listunspent"), params));
35    }
36
37    /// Add one `blockchain.scripthash.get_history` request to the batch queue
38    pub fn script_get_history(&mut self, script: &Script) {
39        let params = vec![Param::String(script.to_electrum_scripthash().to_hex())];
40        self.calls
41            .push((String::from("blockchain.scripthash.get_history"), params));
42    }
43
44    /// Add one `blockchain.scripthash.get_balance` request to the batch queue
45    pub fn script_get_balance(&mut self, script: &Script) {
46        let params = vec![Param::String(script.to_electrum_scripthash().to_hex())];
47        self.calls
48            .push((String::from("blockchain.scripthash.get_balance"), params));
49    }
50
51    /// Add one `blockchain.scripthash.listunspent` request to the batch queue
52    pub fn script_subscribe(&mut self, script: &Script) {
53        let params = vec![Param::String(script.to_electrum_scripthash().to_hex())];
54        self.calls
55            .push((String::from("blockchain.scripthash.subscribe"), params));
56    }
57
58    /// Add one `blockchain.transaction.get` request to the batch queue
59    pub fn transaction_get(&mut self, tx_hash: &Txid) {
60        let params = vec![Param::String(format!("{:x}", tx_hash))];
61        self.calls
62            .push((String::from("blockchain.transaction.get"), params));
63    }
64
65    /// Add one `blockchain.transaction.get_merkle` request to the batch queue
66    pub fn transaction_get_merkle(&mut self, tx_hash_and_height: &(Txid, usize)) {
67        let (tx_hash, height) = tx_hash_and_height;
68        let params = vec![
69            Param::String(format!("{:x}", tx_hash)),
70            Param::Usize(*height),
71        ];
72        self.calls
73            .push((String::from("blockchain.transaction.get_merkle"), params));
74    }
75
76    /// Add one `blockchain.estimatefee` request to the batch queue
77    pub fn estimate_fee(&mut self, number: usize) {
78        let params = vec![Param::Usize(number)];
79        self.calls
80            .push((String::from("blockchain.estimatefee"), params));
81    }
82
83    /// Add one `blockchain.block.get_header` request to the batch queue
84    pub fn block_header(&mut self, height: u32) {
85        let params = vec![Param::U32(height)];
86        self.calls
87            .push((String::from("blockchain.block.header"), params));
88    }
89
90    /// Returns an iterator on the batch
91    pub fn iter(&self) -> BatchIter {
92        BatchIter {
93            batch: self,
94            index: 0,
95        }
96    }
97}
98
99impl std::iter::IntoIterator for Batch {
100    type Item = (String, Vec<Param>);
101    type IntoIter = std::vec::IntoIter<Self::Item>;
102
103    fn into_iter(self) -> Self::IntoIter {
104        self.calls.into_iter()
105    }
106}
107
108pub struct BatchIter<'a> {
109    batch: &'a Batch,
110    index: usize,
111}
112
113impl<'a> std::iter::Iterator for BatchIter<'a> {
114    type Item = &'a (String, Vec<Param>);
115
116    fn next(&mut self) -> Option<Self::Item> {
117        let val = self.batch.calls.get(self.index);
118        self.index += 1;
119        val
120    }
121}