bitcoin_rpc_midas/test_node/
client.rs

1use std::sync::Arc;
2
3use anyhow::Result;
4use bitcoin::{Amount, Network};
5use bitcoin_rpc_types::HashOrHeight;
6use serde_json::Value;
7
8use crate::node::{BitcoinNodeManager, NodeManager as NodeManagerTrait};
9use crate::responses::v30_responses::*;
10use crate::test_config::TestConfig;
11use crate::transport::core::{TransportError, TransportExt};
12use crate::transport::{BatchBuilder, DefaultTransport, RpcClient};
13#[derive(Debug)]
14pub struct BitcoinTestClient {
15    transport: Arc<DefaultTransport>,
16    node_manager: Option<Box<dyn NodeManagerTrait>>,
17    /// A thin RPC wrapper around the transport, with batching built in
18    rpc: RpcClient,
19}
20
21/// Options for creating or loading a Bitcoin Core wallet
22#[derive(Debug, Clone)]
23pub struct WalletOptions {
24    pub disable_private_keys: bool,
25    pub blank: bool,
26    pub passphrase: String,
27    pub avoid_reuse: bool,
28    pub descriptors: bool,
29    pub load_on_startup: bool,
30    pub external_signer: bool,
31}
32
33impl Default for WalletOptions {
34    fn default() -> Self {
35        WalletOptions {
36            disable_private_keys: false,
37            blank: false,
38            passphrase: "".to_string(),
39            avoid_reuse: false,
40            descriptors: false,
41            load_on_startup: false,
42            external_signer: false,
43        }
44    }
45}
46
47impl WalletOptions {
48    pub fn with_descriptors(mut self) -> Self {
49        self.descriptors = true;
50        self
51    }
52}
53
54impl BitcoinTestClient {
55    /// Creates a new Bitcoin test client with default configuration (regtest network).
56    /// ```no_run
57    /// use bitcoin_rpc_midas::test_node::client::BitcoinTestClient;
58    ///
59    /// async fn example() -> Result<(), Box<dyn std::error::Error>> {
60    ///     let client = BitcoinTestClient::new().await?;
61    ///     Ok(())
62    /// }
63    /// ```
64    pub async fn new() -> Result<Self, TransportError> {
65        tracing::debug!("BitcoinTestClient::new() called");
66        let config = TestConfig::default();
67        let node_manager = BitcoinNodeManager::new_with_config(&config)?;
68        Self::new_with_manager(node_manager).await
69    }
70
71    /// Creates a new Bitcoin test client with a specific network.
72    /// ```no_run
73    /// use bitcoin_rpc_midas::test_node::client::BitcoinTestClient;
74    /// use bitcoin::Network;
75    ///
76    /// async fn example() -> Result<(), Box<dyn std::error::Error>> {
77    ///     let client = BitcoinTestClient::new_with_network(Network::Bitcoin).await?;
78    ///     Ok(())
79    /// }
80    /// ```
81    pub async fn new_with_network(network: Network) -> Result<Self, TransportError> {
82        tracing::debug!("BitcoinTestClient::new_with_network({:?}) called", network);
83        let config = TestConfig { network, ..Default::default() };
84        let node_manager = BitcoinNodeManager::new_with_config(&config)?;
85        Self::new_with_manager(node_manager).await
86    }
87
88    /// Creates a new Bitcoin test client with a specific node manager.
89    /// This allows for custom node configuration and lifecycle management.
90    /// The node manager must implement the `NodeManager` trait.
91    /// ```no_run
92    /// use bitcoin_rpc_midas::test_node::client::BitcoinTestClient;
93    /// use bitcoin_rpc_midas::node::BitcoinNodeManager;
94    /// use bitcoin_rpc_midas::test_config::TestConfig;
95    ///
96    /// async fn example() -> Result<(), Box<dyn std::error::Error>> {
97    ///     let config = TestConfig::default();
98    ///     let node_manager = BitcoinNodeManager::new_with_config(&config)?;
99    ///     let client = BitcoinTestClient::new_with_manager(node_manager).await?;
100    ///     Ok(())
101    /// }
102    /// ```
103    pub async fn new_with_manager<M: NodeManagerTrait + 'static>(
104        node_manager: M,
105    ) -> Result<Self, TransportError> {
106        tracing::debug!("BitcoinTestClient::new_with_manager called");
107        // Start the node
108        tracing::debug!("Calling node_manager.start()");
109        node_manager.start().await?;
110        tracing::debug!("node_manager.start() completed successfully");
111
112        // Wait for node to be ready for RPC
113        tracing::debug!("Creating transport with port {}", node_manager.rpc_port());
114        let transport = Arc::new(DefaultTransport::new(
115            format!("http://127.0.0.1:{}", node_manager.rpc_port()),
116            Some(("rpcuser".to_string(), "rpcpassword".to_string())),
117        ));
118
119        // Create RPC client for batching support
120        let rpc = RpcClient::from_transport(transport.clone());
121
122        // Wait for node to be ready for RPC
123        // Core initialization states that require waiting:
124        // -28: RPC in warmup
125        // -4:  RPC in warmup (alternative code)
126        let init_states = ["\"code\":-28", "\"code\":-4"];
127
128        let max_retries = 30;
129        let mut retries = 0;
130
131        loop {
132            match transport.call::<serde_json::Value>("getblockchaininfo", &[]).await {
133                Ok(_) => break,
134                Err(TransportError::Rpc(e)) => {
135                    // Check if the error matches any known initialization state
136                    let is_init_state = init_states.iter().any(|state| e.contains(state));
137                    if is_init_state && retries < max_retries {
138                        tracing::debug!(
139                            "Waiting for initialization: {} (attempt {}/{})",
140                            e,
141                            retries + 1,
142                            max_retries
143                        );
144                        tokio::time::sleep(std::time::Duration::from_secs(1)).await;
145                        retries += 1;
146                        continue;
147                    }
148                    return Err(TransportError::Rpc(e));
149                }
150                Err(e) => return Err(e),
151            }
152        }
153
154        if retries > 0 {
155            tracing::debug!("Node initialization completed after {} attempts", retries);
156        }
157
158        Ok(Self { transport, node_manager: Some(Box::new(node_manager)), rpc })
159    }
160
161    /// Ensures a wallet exists using the given options.
162    /// Loads the wallet if it already exists. Returns the wallet name.
163    pub async fn ensure_wallet_with_options(
164        &mut self,
165        wallet_name: impl Into<String>,
166        opts: WalletOptions,
167    ) -> Result<String, TransportError> {
168        let wallet_name = wallet_name.into();
169
170        // Check if wallet is currently loaded
171        let mut params = Vec::new();
172        let wallets: ListwalletsResponse = self.transport.call("listwallets", &params).await?;
173        if wallets.0.iter().any(|w| w == &wallet_name) {
174            params.clear();
175            params.push(serde_json::to_value(wallet_name.clone())?);
176            params.push(serde_json::to_value(false)?);
177            let _: serde_json::Value = self.transport.call("unloadwallet", &params).await?;
178        }
179
180        // Try to create wallet
181        params.clear();
182        params.push(serde_json::to_value(wallet_name.clone())?);
183        params.push(serde_json::to_value(opts.disable_private_keys)?);
184        params.push(serde_json::to_value(opts.blank)?);
185        params.push(serde_json::to_value(opts.passphrase.clone())?);
186        params.push(serde_json::to_value(opts.avoid_reuse)?);
187        params.push(serde_json::to_value(opts.descriptors)?);
188        params.push(serde_json::to_value(opts.load_on_startup)?);
189        params.push(serde_json::to_value(opts.external_signer)?);
190
191        match self.transport.call::<CreatewalletResponse>("createwallet", &params).await {
192            Ok(_) => Ok(wallet_name),
193            Err(TransportError::Rpc(err)) if err.contains("\"code\":-4") => {
194                // Try loading instead
195                params.clear();
196                params.push(serde_json::to_value(wallet_name.clone())?);
197                params.push(serde_json::to_value(false)?);
198                let _: LoadwalletResponse = self.transport.call("loadwallet", &params).await?;
199
200                // Update transport to use wallet endpoint
201                let _new_transport = Arc::new(
202                    DefaultTransport::new(
203                        format!(
204                            "http://127.0.0.1:{}",
205                            self.node_manager.as_ref().unwrap().rpc_port()
206                        ),
207                        Some(("rpcuser".to_string(), "rpcpassword".to_string())),
208                    )
209                    .with_wallet(wallet_name.clone()),
210                );
211
212                // Note: In a real implementation, we'd need to update self.transport here
213                // For now, this is a limitation of the current design
214
215                Ok(wallet_name)
216            }
217            Err(e) => Err(e),
218        }
219    }
220
221    /// Shortcut for `ensure_wallet_with_options("test_wallet", WalletOptions::default().with_descriptors())`
222    pub async fn ensure_default_wallet(
223        &mut self,
224        name: impl Into<String>,
225    ) -> Result<String, TransportError> {
226        self.ensure_wallet_with_options(name, WalletOptions::default().with_descriptors()).await
227    }
228
229    /// Helper method to mine blocks to a new address
230    pub async fn mine_blocks(
231        &mut self,
232        num_blocks: u64,
233        maxtries: u64,
234    ) -> Result<(String, Value), TransportError> {
235        // Ensure we have a wallet with default settings
236        let _wallet_name = self.ensure_default_wallet("test_wallet").await?;
237
238        tracing::debug!("Getting new address");
239        let address = self.getnewaddress("".to_string(), "bech32m".to_string()).await?;
240        tracing::debug!("Generated address: {:?}", address);
241        tracing::debug!("Generating blocks");
242        let blocks = self.generatetoaddress(num_blocks, address.0.clone(), maxtries).await?;
243        tracing::debug!("Generated blocks: {:?}", blocks);
244        Ok((address.0, serde_json::to_value(blocks)?))
245    }
246
247    /// Resets the blockchain to a clean state.
248    /// This method:
249    /// 1. First attempts to prune the blockchain to height 0
250    /// 2. If blocks remain, invalidates all blocks except genesis
251    /// 3. Reconsiders the genesis block to maintain a valid chain
252    pub async fn reset_chain(&mut self) -> Result<(), TransportError> {
253        // First try pruning to height 0
254        self.pruneblockchain(0).await?;
255        // Check if we still have blocks
256        let info = self.getblockchaininfo().await?;
257        let current_height = info.blocks;
258        if current_height > 1 {
259            // Invalidate all blocks except genesis
260            for height in (1..=current_height).rev() {
261                let block_hash = self.getblockhash(height).await?.0;
262                self.invalidateblock(block_hash).await?;
263            }
264            // Reconsider genesis block
265            let genesis_hash = self.getblockhash(0).await?.0;
266            self.reconsiderblock(genesis_hash).await?;
267        }
268        Ok(())
269    }
270
271    /// Stops the Bitcoin node if one is running.
272    /// This is automatically called when the client is dropped.
273    pub async fn stop_node(&mut self) -> Result<(), TransportError> {
274        if let Some(mut manager) = self.node_manager.take() {
275            manager.stop().await?;
276        }
277        Ok(())
278    }
279
280    /// Returns a reference to the node manager if one exists.
281    /// This can be used to access node configuration and control the node lifecycle.
282    pub fn node_manager(&self) -> Option<&dyn NodeManagerTrait> { self.node_manager.as_deref() }
283
284    /// Give callers the full RPC client (incl. `.batch()`)
285    pub fn rpc(&self) -> &RpcClient { &self.rpc }
286
287    /// Begin a JSON-RPC batch against this test node
288    pub fn batch(&self) -> BatchBuilder { self.rpc.batch() }
289
290    /// Mark in-wallet transaction <txid> as abandoned
291    /// This will mark this transaction and all its in-wallet descendants as abandoned which will allow
292    /// for their inputs to be respent.  It can be used to replace "stuck" or evicted transactions.
293    /// It only works on transactions which are not included in a block and are not currently in the mempool.
294    /// It has no effect on transactions which are already abandoned.
295    pub async fn abandontransaction(&self, txid: bitcoin::Txid) -> Result<(), TransportError> {
296        let mut params = Vec::new();
297        params.push(serde_json::to_value(txid)?);
298        self.transport.call("abandontransaction", &params).await
299    }
300
301    /// Stops current wallet rescan triggered by an RPC call, e.g. by a rescanblockchain call.
302    /// Note: Use "getwalletinfo" to query the scanning progress.
303    pub async fn abortrescan(&self) -> Result<AbortrescanResponse, TransportError> {
304        self.transport.call("abortrescan", &[]).await
305    }
306
307    /// Open an outbound connection to a specified node. This RPC is for testing only.
308    pub async fn addconnection(
309        &self,
310        address: String,
311        connection_type: String,
312        v2transport: bool,
313    ) -> Result<AddconnectionResponse, TransportError> {
314        let mut params = Vec::new();
315        params.push(serde_json::to_value(address)?);
316        params.push(serde_json::to_value(connection_type)?);
317        params.push(serde_json::to_value(v2transport)?);
318        self.transport.call("addconnection", &params).await
319    }
320
321    /// Attempts to add or remove a node from the addnode list.
322    /// Or try a connection to a node once.
323    /// Nodes added using addnode (or -connect) are protected from DoS disconnection and are not required to be
324    /// full nodes/support SegWit as other outbound peers are (though such peers will not be synced from).
325    /// Addnode connections are limited to 8 at a time and are counted separately from the -maxconnections limit.
326    pub async fn addnode(
327        &self,
328        node: String,
329        command: String,
330        v2transport: bool,
331    ) -> Result<(), TransportError> {
332        let mut params = Vec::new();
333        params.push(serde_json::to_value(node)?);
334        params.push(serde_json::to_value(command)?);
335        params.push(serde_json::to_value(v2transport)?);
336        self.transport.call("addnode", &params).await
337    }
338
339    /// Add the address of a potential peer to an address manager table. This RPC is for testing only.
340    pub async fn addpeeraddress(
341        &self,
342        address: String,
343        port: u16,
344        tried: bool,
345    ) -> Result<AddpeeraddressResponse, TransportError> {
346        let mut params = Vec::new();
347        params.push(serde_json::to_value(address)?);
348        params.push(serde_json::to_value(port)?);
349        params.push(serde_json::to_value(tried)?);
350        self.transport.call("addpeeraddress", &params).await
351    }
352
353    /// Analyzes and provides information about the current status of a PSBT and its inputs
354    pub async fn analyzepsbt(&self, psbt: String) -> Result<AnalyzepsbtResponse, TransportError> {
355        let mut params = Vec::new();
356        params.push(serde_json::to_value(psbt)?);
357        self.transport.call("analyzepsbt", &params).await
358    }
359
360    /// Safely copies the current wallet file to the specified destination, which can either be a directory or a path with a filename.
361    pub async fn backupwallet(&self, destination: String) -> Result<(), TransportError> {
362        let mut params = Vec::new();
363        params.push(serde_json::to_value(destination)?);
364        self.transport.call("backupwallet", &params).await
365    }
366
367    /// Bumps the fee of a transaction T, replacing it with a new transaction B.
368    /// A transaction with the given txid must be in the wallet.
369    /// The command will pay the additional fee by reducing change outputs or adding inputs when necessary.
370    /// It may add a new change output if one does not already exist.
371    /// All inputs in the original transaction will be included in the replacement transaction.
372    /// The command will fail if the wallet or mempool contains a transaction that spends one of T"s outputs.
373    /// By default, the new fee will be calculated automatically using the estimatesmartfee RPC.
374    /// The user can specify a confirmation target for estimatesmartfee.
375    /// Alternatively, the user can specify a fee rate in sat/vB for the new transaction.
376    /// At a minimum, the new fee rate must be high enough to pay an additional new relay fee (incrementalfee
377    /// returned by getnetworkinfo) to enter the node"s mempool.
378    /// * WARNING: before version 0.21, fee_rate was in BTC/kvB. As of 0.21, fee_rate is in sat/vB. *
379    pub async fn bumpfee(
380        &self,
381        txid: bitcoin::Txid,
382        options: serde_json::Value,
383    ) -> Result<BumpfeeResponse, TransportError> {
384        let mut params = Vec::new();
385        params.push(serde_json::to_value(txid)?);
386        params.push(serde_json::to_value(options)?);
387        self.transport.call("bumpfee", &params).await
388    }
389
390    /// Clear all banned IPs.
391    pub async fn clearbanned(&self) -> Result<(), TransportError> {
392        self.transport.call("clearbanned", &[]).await
393    }
394
395    /// Combine multiple partially signed Bitcoin transactions into one transaction.
396    /// Implements the Combiner role.
397    pub async fn combinepsbt(
398        &self,
399        txs: Vec<serde_json::Value>,
400    ) -> Result<CombinepsbtResponse, TransportError> {
401        let mut params = Vec::new();
402        params.push(serde_json::to_value(txs)?);
403        self.transport.call("combinepsbt", &params).await
404    }
405
406    /// Combine multiple partially signed transactions into one transaction.
407    /// The combined transaction may be another partially signed transaction or a
408    /// fully signed transaction.
409    pub async fn combinerawtransaction(
410        &self,
411        txs: Vec<serde_json::Value>,
412    ) -> Result<CombinerawtransactionResponse, TransportError> {
413        let mut params = Vec::new();
414        params.push(serde_json::to_value(txs)?);
415        self.transport.call("combinerawtransaction", &params).await
416    }
417
418    /// Converts a network serialized transaction to a PSBT. This should be used only with createrawtransaction and fundrawtransaction
419    /// createpsbt and walletcreatefundedpsbt should be used for new applications.
420    pub async fn converttopsbt(
421        &self,
422        hexstring: String,
423        permitsigdata: bool,
424        iswitness: bool,
425    ) -> Result<ConverttopsbtResponse, TransportError> {
426        let mut params = Vec::new();
427        params.push(serde_json::to_value(hexstring)?);
428        params.push(serde_json::to_value(permitsigdata)?);
429        params.push(serde_json::to_value(iswitness)?);
430        self.transport.call("converttopsbt", &params).await
431    }
432
433    /// Creates a multi-signature address with n signatures of m keys required.
434    /// It returns a json object with the address and redeemScript.
435    pub async fn createmultisig(
436        &self,
437        nrequired: u32,
438        keys: Vec<String>,
439        address_type: String,
440    ) -> Result<CreatemultisigResponse, TransportError> {
441        let mut params = Vec::new();
442        params.push(serde_json::to_value(nrequired)?);
443        params.push(serde_json::to_value(keys)?);
444        params.push(serde_json::to_value(address_type)?);
445        self.transport.call("createmultisig", &params).await
446    }
447
448    /// Creates a transaction in the Partially Signed Transaction format.
449    /// Implements the Creator role.
450    /// Note that the transaction"s inputs are not signed, and
451    /// it is not stored in the wallet or transmitted to the network.
452    pub async fn createpsbt(
453        &self,
454        inputs: Vec<serde_json::Value>,
455        outputs: Vec<serde_json::Value>,
456        locktime: u32,
457        replaceable: bool,
458        version: u32,
459    ) -> Result<CreatepsbtResponse, TransportError> {
460        let mut params = Vec::new();
461        params.push(serde_json::to_value(inputs)?);
462        params.push(serde_json::to_value(outputs)?);
463        params.push(serde_json::to_value(locktime)?);
464        params.push(serde_json::to_value(replaceable)?);
465        params.push(serde_json::to_value(version)?);
466        self.transport.call("createpsbt", &params).await
467    }
468
469    /// Create a transaction spending the given inputs and creating new outputs.
470    /// Outputs can be addresses or data.
471    /// Returns hex-encoded raw transaction.
472    /// Note that the transaction"s inputs are not signed, and
473    /// it is not stored in the wallet or transmitted to the network.
474    pub async fn createrawtransaction(
475        &self,
476        inputs: Vec<serde_json::Value>,
477        outputs: Vec<serde_json::Value>,
478        locktime: u32,
479        replaceable: bool,
480        version: u32,
481    ) -> Result<CreaterawtransactionResponse, TransportError> {
482        let mut params = Vec::new();
483        params.push(serde_json::to_value(inputs)?);
484        params.push(serde_json::to_value(outputs)?);
485        params.push(serde_json::to_value(locktime)?);
486        params.push(serde_json::to_value(replaceable)?);
487        params.push(serde_json::to_value(version)?);
488        self.transport.call("createrawtransaction", &params).await
489    }
490
491    /// Creates and loads a new wallet.
492    #[allow(clippy::too_many_arguments)]
493    pub async fn createwallet(
494        &self,
495        wallet_name: String,
496        disable_private_keys: bool,
497        blank: bool,
498        passphrase: String,
499        avoid_reuse: bool,
500        descriptors: bool,
501        load_on_startup: bool,
502        external_signer: bool,
503    ) -> Result<CreatewalletResponse, TransportError> {
504        let mut params = Vec::new();
505        params.push(serde_json::to_value(wallet_name)?);
506        params.push(serde_json::to_value(disable_private_keys)?);
507        params.push(serde_json::to_value(blank)?);
508        params.push(serde_json::to_value(passphrase)?);
509        params.push(serde_json::to_value(avoid_reuse)?);
510        params.push(serde_json::to_value(descriptors)?);
511        params.push(serde_json::to_value(load_on_startup)?);
512        params.push(serde_json::to_value(external_signer)?);
513        self.transport.call("createwallet", &params).await
514    }
515
516    /// Creates the wallet"s descriptor for the given address type. The address type must be one that the wallet does not already have a descriptor for.
517    /// Requires wallet passphrase to be set with walletpassphrase call if wallet is encrypted.
518    pub async fn createwalletdescriptor(
519        &self,
520        _type: String,
521        options: serde_json::Value,
522    ) -> Result<CreatewalletdescriptorResponse, TransportError> {
523        let mut params = Vec::new();
524        params.push(serde_json::to_value(_type)?);
525        params.push(serde_json::to_value(options)?);
526        self.transport.call("createwalletdescriptor", &params).await
527    }
528
529    /// Return a JSON object representing the serialized, base64-encoded partially signed Bitcoin transaction.
530    pub async fn decodepsbt(&self, psbt: String) -> Result<DecodepsbtResponse, TransportError> {
531        let mut params = Vec::new();
532        params.push(serde_json::to_value(psbt)?);
533        self.transport.call("decodepsbt", &params).await
534    }
535
536    /// Return a JSON object representing the serialized, hex-encoded transaction.
537    pub async fn decoderawtransaction(
538        &self,
539        hexstring: String,
540        iswitness: bool,
541    ) -> Result<DecoderawtransactionResponse, TransportError> {
542        let mut params = Vec::new();
543        params.push(serde_json::to_value(hexstring)?);
544        params.push(serde_json::to_value(iswitness)?);
545        self.transport.call("decoderawtransaction", &params).await
546    }
547
548    /// Decode a hex-encoded script.
549    pub async fn decodescript(
550        &self,
551        hexstring: String,
552    ) -> Result<DecodescriptResponse, TransportError> {
553        let mut params = Vec::new();
554        params.push(serde_json::to_value(hexstring)?);
555        self.transport.call("decodescript", &params).await
556    }
557
558    /// Derives one or more addresses corresponding to an output descriptor.
559    /// Examples of output descriptors are:
560    /// pkh(<pubkey>)                                     P2PKH outputs for the given pubkey
561    /// wpkh(<pubkey>)                                    Native segwit P2PKH outputs for the given pubkey
562    /// sh(multi(<n>,<pubkey>,<pubkey>,...))              P2SH-multisig outputs for the given threshold and pubkeys
563    /// raw(<hex script>)                                 Outputs whose output script equals the specified hex-encoded bytes
564    /// tr(<pubkey>,multi_a(<n>,<pubkey>,<pubkey>,...))   P2TR-multisig outputs for the given threshold and pubkeys
565    ///
566    /// In the above, <pubkey> either refers to a fixed public key in hexadecimal notation, or to an xpub/xprv optionally followed by one
567    /// or more path elements separated by "/", where "h" represents a hardened child key.
568    /// For more information on output descriptors, see the documentation in the doc/descriptors.md file.
569    pub async fn deriveaddresses(
570        &self,
571        descriptor: String,
572        range: serde_json::Value,
573    ) -> Result<DeriveaddressesResponse, TransportError> {
574        let mut params = Vec::new();
575        params.push(serde_json::to_value(descriptor)?);
576        params.push(serde_json::to_value(range)?);
577        self.transport.call("deriveaddresses", &params).await
578    }
579
580    /// Update all segwit inputs in a PSBT with information from output descriptors, the UTXO set or the mempool.
581    /// Then, sign the inputs we are able to with information from the output descriptors.
582    pub async fn descriptorprocesspsbt(
583        &self,
584        psbt: String,
585        descriptors: Vec<serde_json::Value>,
586        sighashtype: String,
587        bip32derivs: bool,
588        finalize: bool,
589    ) -> Result<DescriptorprocesspsbtResponse, TransportError> {
590        let mut params = Vec::new();
591        params.push(serde_json::to_value(psbt)?);
592        params.push(serde_json::to_value(descriptors)?);
593        params.push(serde_json::to_value(sighashtype)?);
594        params.push(serde_json::to_value(bip32derivs)?);
595        params.push(serde_json::to_value(finalize)?);
596        self.transport.call("descriptorprocesspsbt", &params).await
597    }
598
599    /// Immediately disconnects from the specified peer node.
600    ///
601    /// Strictly one out of "address" and "nodeid" can be provided to identify the node.
602    ///
603    /// To disconnect by nodeid, either set "address" to the empty string, or call using the named "nodeid" argument only.
604    pub async fn disconnectnode(&self, address: String, nodeid: u64) -> Result<(), TransportError> {
605        let mut params = Vec::new();
606        params.push(serde_json::to_value(address)?);
607        params.push(serde_json::to_value(nodeid)?);
608        self.transport.call("disconnectnode", &params).await
609    }
610
611    /// Write the serialized UTXO set to a file. This can be used in loadtxoutset afterwards if this snapshot height is supported in the chainparams as well.
612    ///
613    /// Unless the "latest" type is requested, the node will roll back to the requested height and network activity will be suspended during this process. Because of this it is discouraged to interact with the node in any other way during the execution of this call to avoid inconsistent results and race conditions, particularly RPCs that interact with blockstorage.
614    ///
615    /// This call may take several minutes. Make sure to use no RPC timeout (bitcoin-cli -rpcclienttimeout=0)
616    pub async fn dumptxoutset(
617        &self,
618        path: String,
619        _type: String,
620        options: serde_json::Value,
621    ) -> Result<DumptxoutsetResponse, TransportError> {
622        let mut params = Vec::new();
623        params.push(serde_json::to_value(path)?);
624        params.push(serde_json::to_value(_type)?);
625        params.push(serde_json::to_value(options)?);
626        self.transport.call("dumptxoutset", &params).await
627    }
628
629    /// Simply echo back the input arguments. This command is for testing.
630    ///
631    /// It will return an internal bug report when arg9="trigger_internal_bug" is passed.
632    ///
633    /// The difference between echo and echojson is that echojson has argument conversion enabled in the client-side table in bitcoin-cli and the GUI. There is no server-side difference.
634    #[allow(clippy::too_many_arguments)]
635    pub async fn echo(
636        &self,
637        arg0: String,
638        arg1: String,
639        arg2: String,
640        arg3: String,
641        arg4: String,
642        arg5: String,
643        arg6: String,
644        arg7: String,
645        arg8: String,
646        arg9: String,
647    ) -> Result<EchoResponse, TransportError> {
648        let mut params = Vec::new();
649        params.push(serde_json::to_value(arg0)?);
650        params.push(serde_json::to_value(arg1)?);
651        params.push(serde_json::to_value(arg2)?);
652        params.push(serde_json::to_value(arg3)?);
653        params.push(serde_json::to_value(arg4)?);
654        params.push(serde_json::to_value(arg5)?);
655        params.push(serde_json::to_value(arg6)?);
656        params.push(serde_json::to_value(arg7)?);
657        params.push(serde_json::to_value(arg8)?);
658        params.push(serde_json::to_value(arg9)?);
659        self.transport.call("echo", &params).await
660    }
661
662    /// Echo back the input argument, passing it through a spawned process in a multiprocess build.
663    /// This command is for testing.
664    pub async fn echoipc(&self, arg: String) -> Result<EchoipcResponse, TransportError> {
665        let mut params = Vec::new();
666        params.push(serde_json::to_value(arg)?);
667        self.transport.call("echoipc", &params).await
668    }
669
670    /// Simply echo back the input arguments. This command is for testing.
671    ///
672    /// It will return an internal bug report when arg9="trigger_internal_bug" is passed.
673    ///
674    /// The difference between echo and echojson is that echojson has argument conversion enabled in the client-side table in bitcoin-cli and the GUI. There is no server-side difference.
675    #[allow(clippy::too_many_arguments)]
676    pub async fn echojson(
677        &self,
678        arg0: String,
679        arg1: String,
680        arg2: String,
681        arg3: String,
682        arg4: String,
683        arg5: String,
684        arg6: String,
685        arg7: String,
686        arg8: String,
687        arg9: String,
688    ) -> Result<EchojsonResponse, TransportError> {
689        let mut params = Vec::new();
690        params.push(serde_json::to_value(arg0)?);
691        params.push(serde_json::to_value(arg1)?);
692        params.push(serde_json::to_value(arg2)?);
693        params.push(serde_json::to_value(arg3)?);
694        params.push(serde_json::to_value(arg4)?);
695        params.push(serde_json::to_value(arg5)?);
696        params.push(serde_json::to_value(arg6)?);
697        params.push(serde_json::to_value(arg7)?);
698        params.push(serde_json::to_value(arg8)?);
699        params.push(serde_json::to_value(arg9)?);
700        self.transport.call("echojson", &params).await
701    }
702
703    /// Encrypts the wallet with "passphrase". This is for first time encryption.
704    /// After this, any calls that interact with private keys such as sending or signing
705    /// will require the passphrase to be set prior to making these calls.
706    /// Use the walletpassphrase call for this, and then walletlock call.
707    /// If the wallet is already encrypted, use the walletpassphrasechange call.
708    /// ** IMPORTANT **
709    /// For security reasons, the encryption process will generate a new HD seed, resulting
710    /// in the creation of a fresh set of active descriptors. Therefore, it is crucial to
711    /// securely back up the newly generated wallet file using the backupwallet RPC.
712    pub async fn encryptwallet(
713        &self,
714        passphrase: String,
715    ) -> Result<EncryptwalletResponse, TransportError> {
716        let mut params = Vec::new();
717        params.push(serde_json::to_value(passphrase)?);
718        self.transport.call("encryptwallet", &params).await
719    }
720
721    /// Returns a list of external signers from -signer.
722    pub async fn enumeratesigners(&self) -> Result<EnumeratesignersResponse, TransportError> {
723        self.transport.call("enumeratesigners", &[]).await
724    }
725
726    /// WARNING: This interface is unstable and may disappear or change!
727    ///
728    /// WARNING: This is an advanced API call that is tightly coupled to the specific
729    /// implementation of fee estimation. The parameters it can be called with
730    /// and the results it returns will change if the internal implementation changes.
731    ///
732    /// Estimates the approximate fee per kilobyte needed for a transaction to begin
733    /// confirmation within conf_target blocks if possible. Uses virtual transaction size as
734    /// defined in BIP 141 (witness data is discounted).
735    pub async fn estimaterawfee(
736        &self,
737        conf_target: u64,
738        threshold: u64,
739    ) -> Result<EstimaterawfeeResponse, TransportError> {
740        let mut params = Vec::new();
741        params.push(serde_json::to_value(conf_target)?);
742        params.push(serde_json::to_value(threshold)?);
743        self.transport.call("estimaterawfee", &params).await
744    }
745
746    /// Estimates the approximate fee per kilobyte needed for a transaction to begin
747    /// confirmation within conf_target blocks if possible and return the number of blocks
748    /// for which the estimate is valid. Uses virtual transaction size as defined
749    /// in BIP 141 (witness data is discounted).
750    pub async fn estimatesmartfee(
751        &self,
752        conf_target: u64,
753        estimate_mode: String,
754    ) -> Result<EstimatesmartfeeResponse, TransportError> {
755        let mut params = Vec::new();
756        params.push(serde_json::to_value(conf_target)?);
757        params.push(serde_json::to_value(estimate_mode)?);
758        self.transport.call("estimatesmartfee", &params).await
759    }
760
761    /// Finalize the inputs of a PSBT. If the transaction is fully signed, it will produce a
762    /// network serialized transaction which can be broadcast with sendrawtransaction. Otherwise a PSBT will be
763    /// created which has the final_scriptSig and final_scriptwitness fields filled for inputs that are complete.
764    /// Implements the Finalizer and Extractor roles.
765    pub async fn finalizepsbt(
766        &self,
767        psbt: String,
768        extract: bool,
769    ) -> Result<FinalizepsbtResponse, TransportError> {
770        let mut params = Vec::new();
771        params.push(serde_json::to_value(psbt)?);
772        params.push(serde_json::to_value(extract)?);
773        self.transport.call("finalizepsbt", &params).await
774    }
775
776    /// If the transaction has no inputs, they will be automatically selected to meet its out value.
777    /// It will add at most one change output to the outputs.
778    /// No existing outputs will be modified unless "subtractFeeFromOutputs" is specified.
779    /// Note that inputs which were signed may need to be resigned after completion since in/outputs have been added.
780    /// The inputs added will not be signed, use signrawtransactionwithkey
781    /// or signrawtransactionwithwallet for that.
782    /// All existing inputs must either have their previous output transaction be in the wallet
783    /// or be in the UTXO set. Solving data must be provided for non-wallet inputs.
784    /// Note that all inputs selected must be of standard form and P2SH scripts must be
785    /// in the wallet using importdescriptors (to calculate fees).
786    /// You can see whether this is the case by checking the "solvable" field in the listunspent output.
787    /// Note that if specifying an exact fee rate, the resulting transaction may have a higher fee rate
788    /// if the transaction has unconfirmed inputs. This is because the wallet will attempt to make the
789    /// entire package have the given fee rate, not the resulting transaction.
790    pub async fn fundrawtransaction(
791        &self,
792        hexstring: String,
793        options: serde_json::Value,
794        iswitness: bool,
795    ) -> Result<FundrawtransactionResponse, TransportError> {
796        let mut params = Vec::new();
797        params.push(serde_json::to_value(hexstring)?);
798        params.push(serde_json::to_value(options)?);
799        params.push(serde_json::to_value(iswitness)?);
800        self.transport.call("fundrawtransaction", &params).await
801    }
802
803    /// has been replaced by the -generate cli option. Refer to -help for more information.
804    pub async fn generate(&self) -> Result<(), TransportError> {
805        self.transport.call("generate", &[]).await
806    }
807
808    /// Mine a set of ordered transactions to a specified address or descriptor and return the block hash.
809    pub async fn generateblock(
810        &self,
811        output: String,
812        transactions: Vec<serde_json::Value>,
813        submit: bool,
814    ) -> Result<GenerateblockResponse, TransportError> {
815        let mut params = Vec::new();
816        params.push(serde_json::to_value(output)?);
817        params.push(serde_json::to_value(transactions)?);
818        params.push(serde_json::to_value(submit)?);
819        self.transport.call("generateblock", &params).await
820    }
821
822    /// Mine to a specified address and return the block hashes.
823    pub async fn generatetoaddress(
824        &self,
825        nblocks: u64,
826        address: String,
827        maxtries: u64,
828    ) -> Result<GeneratetoaddressResponse, TransportError> {
829        let mut params = Vec::new();
830        params.push(serde_json::to_value(nblocks)?);
831        params.push(serde_json::to_value(address)?);
832        params.push(serde_json::to_value(maxtries)?);
833        self.transport.call("generatetoaddress", &params).await
834    }
835
836    /// Mine to a specified descriptor and return the block hashes.
837    pub async fn generatetodescriptor(
838        &self,
839        num_blocks: u64,
840        descriptor: String,
841        maxtries: u64,
842    ) -> Result<GeneratetodescriptorResponse, TransportError> {
843        let mut params = Vec::new();
844        params.push(serde_json::to_value(num_blocks)?);
845        params.push(serde_json::to_value(descriptor)?);
846        params.push(serde_json::to_value(maxtries)?);
847        self.transport.call("generatetodescriptor", &params).await
848    }
849
850    /// Returns information about the given added node, or all added nodes
851    /// (note that onetry addnodes are not listed here)
852    pub async fn getaddednodeinfo(
853        &self,
854        node: String,
855    ) -> Result<GetaddednodeinfoResponse, TransportError> {
856        let mut params = Vec::new();
857        params.push(serde_json::to_value(node)?);
858        self.transport.call("getaddednodeinfo", &params).await
859    }
860
861    /// Returns the list of addresses assigned the specified label.
862    pub async fn getaddressesbylabel(
863        &self,
864        label: String,
865    ) -> Result<GetaddressesbylabelResponse, TransportError> {
866        let mut params = Vec::new();
867        params.push(serde_json::to_value(label)?);
868        self.transport.call("getaddressesbylabel", &params).await
869    }
870
871    /// Return information about the given bitcoin address.
872    /// Some of the information will only be present if the address is in the active wallet.
873    pub async fn getaddressinfo(
874        &self,
875        address: String,
876    ) -> Result<GetaddressinfoResponse, TransportError> {
877        let mut params = Vec::new();
878        params.push(serde_json::to_value(address)?);
879        self.transport.call("getaddressinfo", &params).await
880    }
881
882    /// Provides information about the node"s address manager by returning the number of addresses in the ``new`` and ``tried`` tables and their sum for all networks.
883    pub async fn getaddrmaninfo(&self) -> Result<GetaddrmaninfoResponse, TransportError> {
884        self.transport.call("getaddrmaninfo", &[]).await
885    }
886
887    /// Returns the total available balance.
888    /// The available balance is what the wallet considers currently spendable, and is
889    /// thus affected by options which limit spendability such as -spendzeroconfchange.
890    pub async fn getbalance(
891        &self,
892        dummy: Option<String>,
893        minconf: u32,
894        include_watchonly: bool,
895        avoid_reuse: bool,
896    ) -> Result<GetbalanceResponse, TransportError> {
897        let mut params = Vec::new();
898        params.push(serde_json::to_value(dummy)?);
899        params.push(serde_json::to_value(minconf)?);
900        params.push(serde_json::to_value(include_watchonly)?);
901        params.push(serde_json::to_value(avoid_reuse)?);
902        self.transport.call("getbalance", &params).await
903    }
904
905    /// Returns an object with all balances in BTC.
906    pub async fn getbalances(&self) -> Result<GetbalancesResponse, TransportError> {
907        self.transport.call("getbalances", &[]).await
908    }
909
910    /// Returns the hash of the best (tip) block in the most-work fully-validated chain.
911    pub async fn getbestblockhash(&self) -> Result<GetbestblockhashResponse, TransportError> {
912        self.transport.call("getbestblockhash", &[]).await
913    }
914
915    /// If verbosity is 0, returns a string that is serialized, hex-encoded data for block "hash".
916    /// If verbosity is 1, returns an Object with information about block <hash>.
917    /// If verbosity is 2, returns an Object with information about block <hash> and information about each transaction.
918    /// If verbosity is 3, returns an Object with information about block <hash> and information about each transaction, including prevout information for inputs (only for unpruned blocks in the current best chain).
919    pub async fn getblock(
920        &self,
921        blockhash: bitcoin::BlockHash,
922        verbosity: u32,
923    ) -> Result<GetblockResponse, TransportError> {
924        let mut params = Vec::new();
925        params.push(serde_json::to_value(blockhash)?);
926        params.push(serde_json::to_value(verbosity)?);
927        self.transport.call("getblock", &params).await
928    }
929
930    /// Returns an object containing various state info regarding blockchain processing.
931    pub async fn getblockchaininfo(&self) -> Result<GetblockchaininfoResponse, TransportError> {
932        self.transport.call("getblockchaininfo", &[]).await
933    }
934
935    /// Returns the height of the most-work fully-validated chain.
936    /// The genesis block has height 0.
937    pub async fn getblockcount(&self) -> Result<GetblockcountResponse, TransportError> {
938        self.transport.call("getblockcount", &[]).await
939    }
940
941    /// Retrieve a BIP 157 content filter for a particular block.
942    pub async fn getblockfilter(
943        &self,
944        blockhash: bitcoin::BlockHash,
945        filtertype: String,
946    ) -> Result<GetblockfilterResponse, TransportError> {
947        let mut params = Vec::new();
948        params.push(serde_json::to_value(blockhash)?);
949        params.push(serde_json::to_value(filtertype)?);
950        self.transport.call("getblockfilter", &params).await
951    }
952
953    /// Attempt to fetch block from a given peer.
954    ///
955    /// We must have the header for this block, e.g. using submitheader.
956    /// The block will not have any undo data which can limit the usage of the block data in a context where the undo data is needed.
957    /// Subsequent calls for the same block may cause the response from the previous peer to be ignored.
958    /// Peers generally ignore requests for a stale block that they never fully verified, or one that is more than a month old.
959    /// When a peer does not respond with a block, we will disconnect.
960    /// Note: The block could be re-pruned as soon as it is received.
961    ///
962    /// Returns an empty JSON object if the request was successfully scheduled.
963    pub async fn getblockfrompeer(
964        &self,
965        blockhash: bitcoin::BlockHash,
966        peer_id: u64,
967    ) -> Result<GetblockfrompeerResponse, TransportError> {
968        let mut params = Vec::new();
969        params.push(serde_json::to_value(blockhash)?);
970        params.push(serde_json::to_value(peer_id)?);
971        self.transport.call("getblockfrompeer", &params).await
972    }
973
974    /// Returns hash of block in best-block-chain at height provided.
975    pub async fn getblockhash(&self, height: u64) -> Result<GetblockhashResponse, TransportError> {
976        let mut params = Vec::new();
977        params.push(serde_json::to_value(height)?);
978        self.transport.call("getblockhash", &params).await
979    }
980
981    /// If verbose is false, returns a string that is serialized, hex-encoded data for blockheader "hash".
982    /// If verbose is true, returns an Object with information about blockheader <hash>.
983    pub async fn getblockheader(
984        &self,
985        blockhash: bitcoin::BlockHash,
986        verbose: bool,
987    ) -> Result<GetblockheaderResponse, TransportError> {
988        let mut params = Vec::new();
989        params.push(serde_json::to_value(blockhash)?);
990        params.push(serde_json::to_value(verbose)?);
991        self.transport.call("getblockheader", &params).await
992    }
993
994    /// Compute per block statistics for a given window. All amounts are in satoshis.
995    /// It won"t work for some heights with pruning.
996    pub async fn getblockstats(
997        &self,
998        hash_or_height: HashOrHeight,
999        stats: Vec<String>,
1000    ) -> Result<GetblockstatsResponse, TransportError> {
1001        let mut params = Vec::new();
1002        params.push(serde_json::to_value(hash_or_height)?);
1003        params.push(serde_json::to_value(stats)?);
1004        self.transport.call("getblockstats", &params).await
1005    }
1006
1007    /// If the request parameters include a "mode" key, that is used to explicitly select between the default "template" request or a "proposal".
1008    /// It returns data needed to construct a block to work on.
1009    /// For full specification, see BIPs 22, 23, 9, and 145:
1010    /// https://github.com/bitcoin/bips/blob/master/bip-0022.mediawiki
1011    /// https://github.com/bitcoin/bips/blob/master/bip-0023.mediawiki
1012    /// https://github.com/bitcoin/bips/blob/master/bip-0009.mediawiki#getblocktemplate_changes
1013    /// https://github.com/bitcoin/bips/blob/master/bip-0145.mediawiki
1014    pub async fn getblocktemplate(
1015        &self,
1016        template_request: serde_json::Value,
1017    ) -> Result<(), TransportError> {
1018        let mut params = Vec::new();
1019        params.push(serde_json::to_value(template_request)?);
1020        self.transport.call("getblocktemplate", &params).await
1021    }
1022
1023    /// Return information about chainstates.
1024    pub async fn getchainstates(&self) -> Result<GetchainstatesResponse, TransportError> {
1025        self.transport.call("getchainstates", &[]).await
1026    }
1027
1028    /// Return information about all known tips in the block tree, including the main chain as well as orphaned branches.
1029    pub async fn getchaintips(&self) -> Result<GetchaintipsResponse, TransportError> {
1030        self.transport.call("getchaintips", &[]).await
1031    }
1032
1033    /// Compute statistics about the total number and rate of transactions in the chain.
1034    pub async fn getchaintxstats(
1035        &self,
1036        nblocks: u64,
1037        blockhash: bitcoin::BlockHash,
1038    ) -> Result<GetchaintxstatsResponse, TransportError> {
1039        let mut params = Vec::new();
1040        params.push(serde_json::to_value(nblocks)?);
1041        params.push(serde_json::to_value(blockhash)?);
1042        self.transport.call("getchaintxstats", &params).await
1043    }
1044
1045    /// Returns the number of connections to other nodes.
1046    pub async fn getconnectioncount(&self) -> Result<GetconnectioncountResponse, TransportError> {
1047        self.transport.call("getconnectioncount", &[]).await
1048    }
1049
1050    /// Returns an object containing various state info regarding deployments of consensus changes.
1051    pub async fn getdeploymentinfo(
1052        &self,
1053        blockhash: bitcoin::BlockHash,
1054    ) -> Result<GetdeploymentinfoResponse, TransportError> {
1055        let mut params = Vec::new();
1056        params.push(serde_json::to_value(blockhash)?);
1057        self.transport.call("getdeploymentinfo", &params).await
1058    }
1059
1060    /// Get spend and receive activity associated with a set of descriptors for a set of blocks. This command pairs well with the ``relevant_blocks`` output of ``scanblocks()``.
1061    /// This call may take several minutes. If you encounter timeouts, try specifying no RPC timeout (bitcoin-cli -rpcclienttimeout=0)
1062    pub async fn getdescriptoractivity(
1063        &self,
1064        blockhashes: Vec<serde_json::Value>,
1065        scanobjects: Vec<serde_json::Value>,
1066        include_mempool: bool,
1067    ) -> Result<GetdescriptoractivityResponse, TransportError> {
1068        let mut params = Vec::new();
1069        params.push(serde_json::to_value(blockhashes)?);
1070        params.push(serde_json::to_value(scanobjects)?);
1071        params.push(serde_json::to_value(include_mempool)?);
1072        self.transport.call("getdescriptoractivity", &params).await
1073    }
1074
1075    /// Analyses a descriptor.
1076    pub async fn getdescriptorinfo(
1077        &self,
1078        descriptor: String,
1079    ) -> Result<GetdescriptorinfoResponse, TransportError> {
1080        let mut params = Vec::new();
1081        params.push(serde_json::to_value(descriptor)?);
1082        self.transport.call("getdescriptorinfo", &params).await
1083    }
1084
1085    /// Returns the proof-of-work difficulty as a multiple of the minimum difficulty.
1086    pub async fn getdifficulty(&self) -> Result<GetdifficultyResponse, TransportError> {
1087        self.transport.call("getdifficulty", &[]).await
1088    }
1089
1090    /// List all BIP 32 HD keys in the wallet and which descriptors use them.
1091    pub async fn gethdkeys(
1092        &self,
1093        options: serde_json::Value,
1094    ) -> Result<GethdkeysResponse, TransportError> {
1095        let mut params = Vec::new();
1096        params.push(serde_json::to_value(options)?);
1097        self.transport.call("gethdkeys", &params).await
1098    }
1099
1100    /// Returns the status of one or all available indices currently running in the node.
1101    pub async fn getindexinfo(
1102        &self,
1103        index_name: String,
1104    ) -> Result<GetindexinfoResponse, TransportError> {
1105        let mut params = Vec::new();
1106        params.push(serde_json::to_value(index_name)?);
1107        self.transport.call("getindexinfo", &params).await
1108    }
1109
1110    /// Returns an object containing information about memory usage.
1111    pub async fn getmemoryinfo(
1112        &self,
1113        mode: String,
1114    ) -> Result<GetmemoryinfoResponse, TransportError> {
1115        let mut params = Vec::new();
1116        params.push(serde_json::to_value(mode)?);
1117        self.transport.call("getmemoryinfo", &params).await
1118    }
1119
1120    /// If txid is in the mempool, returns all in-mempool ancestors.
1121    pub async fn getmempoolancestors(
1122        &self,
1123        txid: bitcoin::Txid,
1124        verbose: bool,
1125    ) -> Result<GetmempoolancestorsResponse, TransportError> {
1126        let mut params = Vec::new();
1127        params.push(serde_json::to_value(txid)?);
1128        params.push(serde_json::to_value(verbose)?);
1129        self.transport.call("getmempoolancestors", &params).await
1130    }
1131
1132    /// If txid is in the mempool, returns all in-mempool descendants.
1133    pub async fn getmempooldescendants(
1134        &self,
1135        txid: bitcoin::Txid,
1136        verbose: bool,
1137    ) -> Result<GetmempooldescendantsResponse, TransportError> {
1138        let mut params = Vec::new();
1139        params.push(serde_json::to_value(txid)?);
1140        params.push(serde_json::to_value(verbose)?);
1141        self.transport.call("getmempooldescendants", &params).await
1142    }
1143
1144    /// Returns mempool data for given transaction
1145    pub async fn getmempoolentry(
1146        &self,
1147        txid: bitcoin::Txid,
1148    ) -> Result<GetmempoolentryResponse, TransportError> {
1149        let mut params = Vec::new();
1150        params.push(serde_json::to_value(txid)?);
1151        self.transport.call("getmempoolentry", &params).await
1152    }
1153
1154    /// Returns details on the active state of the TX memory pool.
1155    pub async fn getmempoolinfo(&self) -> Result<GetmempoolinfoResponse, TransportError> {
1156        self.transport.call("getmempoolinfo", &[]).await
1157    }
1158
1159    /// Returns a json object containing mining-related information.
1160    pub async fn getmininginfo(&self) -> Result<GetmininginfoResponse, TransportError> {
1161        self.transport.call("getmininginfo", &[]).await
1162    }
1163
1164    /// Returns information about network traffic, including bytes in, bytes out,
1165    /// and current system time.
1166    pub async fn getnettotals(&self) -> Result<GetnettotalsResponse, TransportError> {
1167        self.transport.call("getnettotals", &[]).await
1168    }
1169
1170    /// Returns the estimated network hashes per second based on the last n blocks.
1171    /// Pass in [blocks] to override # of blocks, -1 specifies since last difficulty change.
1172    /// Pass in [height] to estimate the network speed at the time when a certain block was found.
1173    pub async fn getnetworkhashps(
1174        &self,
1175        nblocks: u64,
1176        height: u64,
1177    ) -> Result<GetnetworkhashpsResponse, TransportError> {
1178        let mut params = Vec::new();
1179        params.push(serde_json::to_value(nblocks)?);
1180        params.push(serde_json::to_value(height)?);
1181        self.transport.call("getnetworkhashps", &params).await
1182    }
1183
1184    /// Returns an object containing various state info regarding P2P networking.
1185    pub async fn getnetworkinfo(&self) -> Result<GetnetworkinfoResponse, TransportError> {
1186        self.transport.call("getnetworkinfo", &[]).await
1187    }
1188
1189    /// Returns a new Bitcoin address for receiving payments.
1190    /// If "label" is specified, it is added to the address book
1191    /// so payments received with the address will be associated with "label".
1192    pub async fn getnewaddress(
1193        &self,
1194        label: String,
1195        address_type: String,
1196    ) -> Result<GetnewaddressResponse, TransportError> {
1197        let mut params = Vec::new();
1198        params.push(serde_json::to_value(label)?);
1199        params.push(serde_json::to_value(address_type)?);
1200        self.transport.call("getnewaddress", &params).await
1201    }
1202
1203    /// Return known addresses, after filtering for quality and recency.
1204    /// These can potentially be used to find new peers in the network.
1205    /// The total number of addresses known to the node may be higher.
1206    pub async fn getnodeaddresses(
1207        &self,
1208        count: u64,
1209        network: String,
1210    ) -> Result<GetnodeaddressesResponse, TransportError> {
1211        let mut params = Vec::new();
1212        params.push(serde_json::to_value(count)?);
1213        params.push(serde_json::to_value(network)?);
1214        self.transport.call("getnodeaddresses", &params).await
1215    }
1216
1217    /// Shows transactions in the tx orphanage.
1218    ///
1219    /// EXPERIMENTAL warning: this call may be changed in future releases.
1220    pub async fn getorphantxs(
1221        &self,
1222        verbosity: u32,
1223    ) -> Result<GetorphantxsResponse, TransportError> {
1224        let mut params = Vec::new();
1225        params.push(serde_json::to_value(verbosity)?);
1226        self.transport.call("getorphantxs", &params).await
1227    }
1228
1229    /// Returns data about each connected network peer as a json array of objects.
1230    pub async fn getpeerinfo(&self) -> Result<GetpeerinfoResponse, TransportError> {
1231        self.transport.call("getpeerinfo", &[]).await
1232    }
1233
1234    /// Returns a map of all user-created (see prioritisetransaction) fee deltas by txid, and whether the tx is present in mempool.
1235    pub async fn getprioritisedtransactions(
1236        &self,
1237    ) -> Result<GetprioritisedtransactionsResponse, TransportError> {
1238        self.transport.call("getprioritisedtransactions", &[]).await
1239    }
1240
1241    /// EXPERIMENTAL warning: this call may be changed in future releases.
1242    ///
1243    /// Returns information on all address manager entries for the new and tried tables.
1244    pub async fn getrawaddrman(&self) -> Result<GetrawaddrmanResponse, TransportError> {
1245        self.transport.call("getrawaddrman", &[]).await
1246    }
1247
1248    /// Returns a new Bitcoin address, for receiving change.
1249    /// This is for use with raw transactions, NOT normal use.
1250    pub async fn getrawchangeaddress(
1251        &self,
1252        address_type: String,
1253    ) -> Result<GetrawchangeaddressResponse, TransportError> {
1254        let mut params = Vec::new();
1255        params.push(serde_json::to_value(address_type)?);
1256        self.transport.call("getrawchangeaddress", &params).await
1257    }
1258
1259    /// Returns all transaction ids in memory pool as a json array of string transaction ids.
1260    ///
1261    /// Hint: use getmempoolentry to fetch a specific transaction from the mempool.
1262    pub async fn getrawmempool(
1263        &self,
1264        verbose: bool,
1265        mempool_sequence: bool,
1266    ) -> Result<GetrawmempoolResponse, TransportError> {
1267        let mut params = Vec::new();
1268        params.push(serde_json::to_value(verbose)?);
1269        params.push(serde_json::to_value(mempool_sequence)?);
1270        self.transport.call("getrawmempool", &params).await
1271    }
1272
1273    /// By default, this call only returns a transaction if it is in the mempool. If -txindex is enabled
1274    /// and no blockhash argument is passed, it will return the transaction if it is in the mempool or any block.
1275    /// If a blockhash argument is passed, it will return the transaction if
1276    /// the specified block is available and the transaction is in that block.
1277    ///
1278    /// Hint: Use gettransaction for wallet transactions.
1279    ///
1280    /// If verbosity is 0 or omitted, returns the serialized transaction as a hex-encoded string.
1281    /// If verbosity is 1, returns a JSON Object with information about the transaction.
1282    /// If verbosity is 2, returns a JSON Object with information about the transaction, including fee and prevout information.
1283    pub async fn getrawtransaction(
1284        &self,
1285        txid: bitcoin::Txid,
1286        verbosity: u32,
1287        blockhash: bitcoin::BlockHash,
1288    ) -> Result<GetrawtransactionResponse, TransportError> {
1289        let mut params = Vec::new();
1290        params.push(serde_json::to_value(txid)?);
1291        params.push(serde_json::to_value(verbosity)?);
1292        params.push(serde_json::to_value(blockhash)?);
1293        self.transport.call("getrawtransaction", &params).await
1294    }
1295
1296    /// Returns the total amount received by the given address in transactions with at least minconf confirmations.
1297    pub async fn getreceivedbyaddress(
1298        &self,
1299        address: String,
1300        minconf: u32,
1301        include_immature_coinbase: bool,
1302    ) -> Result<GetreceivedbyaddressResponse, TransportError> {
1303        let mut params = Vec::new();
1304        params.push(serde_json::to_value(address)?);
1305        params.push(serde_json::to_value(minconf)?);
1306        params.push(serde_json::to_value(include_immature_coinbase)?);
1307        self.transport.call("getreceivedbyaddress", &params).await
1308    }
1309
1310    /// Returns the total amount received by addresses with <label> in transactions with at least [minconf] confirmations.
1311    pub async fn getreceivedbylabel(
1312        &self,
1313        label: String,
1314        minconf: u32,
1315        include_immature_coinbase: bool,
1316    ) -> Result<GetreceivedbylabelResponse, TransportError> {
1317        let mut params = Vec::new();
1318        params.push(serde_json::to_value(label)?);
1319        params.push(serde_json::to_value(minconf)?);
1320        params.push(serde_json::to_value(include_immature_coinbase)?);
1321        self.transport.call("getreceivedbylabel", &params).await
1322    }
1323
1324    /// Returns details of the RPC server.
1325    pub async fn getrpcinfo(&self) -> Result<GetrpcinfoResponse, TransportError> {
1326        self.transport.call("getrpcinfo", &[]).await
1327    }
1328
1329    /// Get detailed information about in-wallet transaction <txid>
1330    pub async fn gettransaction(
1331        &self,
1332        txid: bitcoin::Txid,
1333        include_watchonly: bool,
1334        verbose: bool,
1335    ) -> Result<GettransactionResponse, TransportError> {
1336        let mut params = Vec::new();
1337        params.push(serde_json::to_value(txid)?);
1338        params.push(serde_json::to_value(include_watchonly)?);
1339        params.push(serde_json::to_value(verbose)?);
1340        self.transport.call("gettransaction", &params).await
1341    }
1342
1343    /// Returns details about an unspent transaction output.
1344    pub async fn gettxout(
1345        &self,
1346        txid: bitcoin::Txid,
1347        n: u32,
1348        include_mempool: bool,
1349    ) -> Result<(), TransportError> {
1350        let mut params = Vec::new();
1351        params.push(serde_json::to_value(txid)?);
1352        params.push(serde_json::to_value(n)?);
1353        params.push(serde_json::to_value(include_mempool)?);
1354        self.transport.call("gettxout", &params).await
1355    }
1356
1357    /// Returns a hex-encoded proof that "txid" was included in a block.
1358    ///
1359    /// NOTE: By default this function only works sometimes. This is when there is an
1360    /// unspent output in the utxo for this transaction. To make it always work,
1361    /// you need to maintain a transaction index, using the -txindex command line option or
1362    /// specify the block in which the transaction is included manually (by blockhash).
1363    pub async fn gettxoutproof(
1364        &self,
1365        txids: Vec<bitcoin::Txid>,
1366        blockhash: bitcoin::BlockHash,
1367    ) -> Result<GettxoutproofResponse, TransportError> {
1368        let mut params = Vec::new();
1369        params.push(serde_json::to_value(txids)?);
1370        params.push(serde_json::to_value(blockhash)?);
1371        self.transport.call("gettxoutproof", &params).await
1372    }
1373
1374    /// Returns statistics about the unspent transaction output set.
1375    /// Note this call may take some time if you are not using coinstatsindex.
1376    pub async fn gettxoutsetinfo(
1377        &self,
1378        hash_type: String,
1379        hash_or_height: HashOrHeight,
1380        use_index: bool,
1381    ) -> Result<GettxoutsetinfoResponse, TransportError> {
1382        let mut params = Vec::new();
1383        params.push(serde_json::to_value(hash_type)?);
1384        params.push(serde_json::to_value(hash_or_height)?);
1385        params.push(serde_json::to_value(use_index)?);
1386        self.transport.call("gettxoutsetinfo", &params).await
1387    }
1388
1389    /// Scans the mempool to find transactions spending any of the given outputs
1390    pub async fn gettxspendingprevout(
1391        &self,
1392        outputs: Vec<serde_json::Value>,
1393    ) -> Result<GettxspendingprevoutResponse, TransportError> {
1394        let mut params = Vec::new();
1395        params.push(serde_json::to_value(outputs)?);
1396        self.transport.call("gettxspendingprevout", &params).await
1397    }
1398
1399    /// Returns an object containing various wallet state info.
1400    pub async fn getwalletinfo(&self) -> Result<GetwalletinfoResponse, TransportError> {
1401        self.transport.call("getwalletinfo", &[]).await
1402    }
1403
1404    /// Returns information about the active ZeroMQ notifications.
1405    pub async fn getzmqnotifications(&self) -> Result<GetzmqnotificationsResponse, TransportError> {
1406        self.transport.call("getzmqnotifications", &[]).await
1407    }
1408
1409    /// List all commands, or get help for a specified command.
1410    pub async fn help(&self, command: String) -> Result<HelpResponse, TransportError> {
1411        let mut params = Vec::new();
1412        params.push(serde_json::to_value(command)?);
1413        self.transport.call("help", &params).await
1414    }
1415
1416    /// Import descriptors. This will trigger a rescan of the blockchain based on the earliest timestamp of all descriptors being imported. Requires a new wallet backup.
1417    /// When importing descriptors with multipath key expressions, if the multipath specifier contains exactly two elements, the descriptor produced from the second element will be imported as an internal descriptor.
1418    ///
1419    /// Note: This call can take over an hour to complete if using an early timestamp; during that time, other rpc calls
1420    /// may report that the imported keys, addresses or scripts exist but related transactions are still missing.
1421    /// The rescan is significantly faster if block filters are available (using startup option "-blockfilterindex=1").
1422    pub async fn importdescriptors(
1423        &self,
1424        requests: Vec<serde_json::Value>,
1425    ) -> Result<ImportdescriptorsResponse, TransportError> {
1426        let mut params = Vec::new();
1427        params.push(serde_json::to_value(requests)?);
1428        self.transport.call("importdescriptors", &params).await
1429    }
1430
1431    /// Import a mempool.dat file and attempt to add its contents to the mempool.
1432    /// Warning: Importing untrusted files is dangerous, especially if metadata from the file is taken over.
1433    pub async fn importmempool(
1434        &self,
1435        filepath: String,
1436        options: serde_json::Value,
1437    ) -> Result<ImportmempoolResponse, TransportError> {
1438        let mut params = Vec::new();
1439        params.push(serde_json::to_value(filepath)?);
1440        params.push(serde_json::to_value(options)?);
1441        self.transport.call("importmempool", &params).await
1442    }
1443
1444    /// Imports funds without rescan. Corresponding address or script must previously be included in wallet. Aimed towards pruned wallets. The end-user is responsible to import additional transactions that subsequently spend the imported outputs or rescan after the point in the blockchain the transaction is included.
1445    pub async fn importprunedfunds(
1446        &self,
1447        rawtransaction: String,
1448        txoutproof: String,
1449    ) -> Result<(), TransportError> {
1450        let mut params = Vec::new();
1451        params.push(serde_json::to_value(rawtransaction)?);
1452        params.push(serde_json::to_value(txoutproof)?);
1453        self.transport.call("importprunedfunds", &params).await
1454    }
1455
1456    /// Permanently marks a block as invalid, as if it violated a consensus rule.
1457    pub async fn invalidateblock(
1458        &self,
1459        blockhash: bitcoin::BlockHash,
1460    ) -> Result<(), TransportError> {
1461        let mut params = Vec::new();
1462        params.push(serde_json::to_value(blockhash)?);
1463        self.transport.call("invalidateblock", &params).await
1464    }
1465
1466    /// Joins multiple distinct PSBTs with different inputs and outputs into one PSBT with inputs and outputs from all of the PSBTs
1467    /// No input in any of the PSBTs can be in more than one of the PSBTs.
1468    pub async fn joinpsbts(
1469        &self,
1470        txs: Vec<serde_json::Value>,
1471    ) -> Result<JoinpsbtsResponse, TransportError> {
1472        let mut params = Vec::new();
1473        params.push(serde_json::to_value(txs)?);
1474        self.transport.call("joinpsbts", &params).await
1475    }
1476
1477    /// Refills each descriptor keypool in the wallet up to the specified number of new keys.
1478    /// By default, descriptor wallets have 4 active ranged descriptors ("legacy", "p2sh-segwit", "bech32", "bech32m"), each with 1000 entries.
1479    ///
1480    /// Requires wallet passphrase to be set with walletpassphrase call if wallet is encrypted.
1481    pub async fn keypoolrefill(&self, newsize: u64) -> Result<(), TransportError> {
1482        let mut params = Vec::new();
1483        params.push(serde_json::to_value(newsize)?);
1484        self.transport.call("keypoolrefill", &params).await
1485    }
1486
1487    /// Lists groups of addresses which have had their common ownership
1488    /// made public by common use as inputs or as the resulting change
1489    /// in past transactions
1490    pub async fn listaddressgroupings(
1491        &self,
1492    ) -> Result<ListaddressgroupingsResponse, TransportError> {
1493        self.transport.call("listaddressgroupings", &[]).await
1494    }
1495
1496    /// List all manually banned IPs/Subnets.
1497    pub async fn listbanned(&self) -> Result<ListbannedResponse, TransportError> {
1498        self.transport.call("listbanned", &[]).await
1499    }
1500
1501    /// List all descriptors present in a wallet.
1502    pub async fn listdescriptors(
1503        &self,
1504        private: bool,
1505    ) -> Result<ListdescriptorsResponse, TransportError> {
1506        let mut params = Vec::new();
1507        params.push(serde_json::to_value(private)?);
1508        self.transport.call("listdescriptors", &params).await
1509    }
1510
1511    /// Returns the list of all labels, or labels that are assigned to addresses with a specific purpose.
1512    pub async fn listlabels(&self, purpose: String) -> Result<ListlabelsResponse, TransportError> {
1513        let mut params = Vec::new();
1514        params.push(serde_json::to_value(purpose)?);
1515        self.transport.call("listlabels", &params).await
1516    }
1517
1518    /// Returns list of temporarily unspendable outputs.
1519    /// See the lockunspent call to lock and unlock transactions for spending.
1520    pub async fn listlockunspent(&self) -> Result<ListlockunspentResponse, TransportError> {
1521        self.transport.call("listlockunspent", &[]).await
1522    }
1523
1524    /// List balances by receiving address.
1525    pub async fn listreceivedbyaddress(
1526        &self,
1527        minconf: u32,
1528        include_empty: bool,
1529        include_watchonly: bool,
1530        address_filter: String,
1531        include_immature_coinbase: bool,
1532    ) -> Result<ListreceivedbyaddressResponse, TransportError> {
1533        let mut params = Vec::new();
1534        params.push(serde_json::to_value(minconf)?);
1535        params.push(serde_json::to_value(include_empty)?);
1536        params.push(serde_json::to_value(include_watchonly)?);
1537        params.push(serde_json::to_value(address_filter)?);
1538        params.push(serde_json::to_value(include_immature_coinbase)?);
1539        self.transport.call("listreceivedbyaddress", &params).await
1540    }
1541
1542    /// List received transactions by label.
1543    pub async fn listreceivedbylabel(
1544        &self,
1545        minconf: u32,
1546        include_empty: bool,
1547        include_watchonly: bool,
1548        include_immature_coinbase: bool,
1549    ) -> Result<ListreceivedbylabelResponse, TransportError> {
1550        let mut params = Vec::new();
1551        params.push(serde_json::to_value(minconf)?);
1552        params.push(serde_json::to_value(include_empty)?);
1553        params.push(serde_json::to_value(include_watchonly)?);
1554        params.push(serde_json::to_value(include_immature_coinbase)?);
1555        self.transport.call("listreceivedbylabel", &params).await
1556    }
1557
1558    /// Get all transactions in blocks since block [blockhash], or all transactions if omitted.
1559    /// If "blockhash" is no longer a part of the main chain, transactions from the fork point onward are included.
1560    /// Additionally, if include_removed is set, transactions affecting the wallet which were removed are returned in the "removed" array.
1561    pub async fn listsinceblock(
1562        &self,
1563        blockhash: bitcoin::BlockHash,
1564        target_confirmations: u64,
1565        include_watchonly: bool,
1566        include_removed: bool,
1567        include_change: bool,
1568        label: String,
1569    ) -> Result<ListsinceblockResponse, TransportError> {
1570        let mut params = Vec::new();
1571        params.push(serde_json::to_value(blockhash)?);
1572        params.push(serde_json::to_value(target_confirmations)?);
1573        params.push(serde_json::to_value(include_watchonly)?);
1574        params.push(serde_json::to_value(include_removed)?);
1575        params.push(serde_json::to_value(include_change)?);
1576        params.push(serde_json::to_value(label)?);
1577        self.transport.call("listsinceblock", &params).await
1578    }
1579
1580    /// If a label name is provided, this will return only incoming transactions paying to addresses with the specified label.
1581    ///
1582    /// Returns up to "count" most recent transactions skipping the first "from" transactions.
1583    pub async fn listtransactions(
1584        &self,
1585        label: String,
1586        count: u64,
1587        skip: u64,
1588        include_watchonly: bool,
1589    ) -> Result<ListtransactionsResponse, TransportError> {
1590        let mut params = Vec::new();
1591        params.push(serde_json::to_value(label)?);
1592        params.push(serde_json::to_value(count)?);
1593        params.push(serde_json::to_value(skip)?);
1594        params.push(serde_json::to_value(include_watchonly)?);
1595        self.transport.call("listtransactions", &params).await
1596    }
1597
1598    /// Returns array of unspent transaction outputs
1599    /// with between minconf and maxconf (inclusive) confirmations.
1600    /// Optionally filter to only include txouts paid to specified addresses.
1601    pub async fn listunspent(
1602        &self,
1603        minconf: u32,
1604        maxconf: u32,
1605        addresses: Vec<String>,
1606        include_unsafe: bool,
1607        query_options: serde_json::Value,
1608    ) -> Result<ListunspentResponse, TransportError> {
1609        let mut params = Vec::new();
1610        params.push(serde_json::to_value(minconf)?);
1611        params.push(serde_json::to_value(maxconf)?);
1612        params.push(serde_json::to_value(addresses)?);
1613        params.push(serde_json::to_value(include_unsafe)?);
1614        params.push(serde_json::to_value(query_options)?);
1615        self.transport.call("listunspent", &params).await
1616    }
1617
1618    /// Returns a list of wallets in the wallet directory.
1619    pub async fn listwalletdir(&self) -> Result<ListwalletdirResponse, TransportError> {
1620        self.transport.call("listwalletdir", &[]).await
1621    }
1622
1623    /// Returns a list of currently loaded wallets.
1624    /// For full information on the wallet, use "getwalletinfo"
1625    pub async fn listwallets(&self) -> Result<ListwalletsResponse, TransportError> {
1626        self.transport.call("listwallets", &[]).await
1627    }
1628
1629    /// Load the serialized UTXO set from a file.
1630    /// Once this snapshot is loaded, its contents will be deserialized into a second chainstate data structure, which is then used to sync to the network"s tip. Meanwhile, the original chainstate will complete the initial block download process in the background, eventually validating up to the block that the snapshot is based upon.
1631    ///
1632    /// The result is a usable bitcoind instance that is current with the network tip in a matter of minutes rather than hours. UTXO snapshot are typically obtained from third-party sources (HTTP, torrent, etc.) which is reasonable since their contents are always checked by hash.
1633    ///
1634    /// You can find more information on this process in the ``assumeutxo`` design document (<https://github.com/bitcoin/bitcoin/blob/master/doc/design/assumeutxo.md>).
1635    pub async fn loadtxoutset(&self, path: String) -> Result<LoadtxoutsetResponse, TransportError> {
1636        let mut params = Vec::new();
1637        params.push(serde_json::to_value(path)?);
1638        self.transport.call("loadtxoutset", &params).await
1639    }
1640
1641    /// Loads a wallet from a wallet file or directory.
1642    /// Note that all wallet command-line options used when starting bitcoind will be
1643    /// applied to the new wallet.
1644    pub async fn loadwallet(
1645        &self,
1646        filename: String,
1647        load_on_startup: bool,
1648    ) -> Result<LoadwalletResponse, TransportError> {
1649        let mut params = Vec::new();
1650        params.push(serde_json::to_value(filename)?);
1651        params.push(serde_json::to_value(load_on_startup)?);
1652        self.transport.call("loadwallet", &params).await
1653    }
1654
1655    /// Updates list of temporarily unspendable outputs.
1656    /// Temporarily lock (unlock=false) or unlock (unlock=true) specified transaction outputs.
1657    /// If no transaction outputs are specified when unlocking then all current locked transaction outputs are unlocked.
1658    /// A locked transaction output will not be chosen by automatic coin selection, when spending bitcoins.
1659    /// Manually selected coins are automatically unlocked.
1660    /// Locks are stored in memory only, unless persistent=true, in which case they will be written to the
1661    /// wallet database and loaded on node start. Unwritten (persistent=false) locks are always cleared
1662    /// (by virtue of process exit) when a node stops or fails. Unlocking will clear both persistent and not.
1663    /// Also see the listunspent call
1664    pub async fn lockunspent(
1665        &self,
1666        unlock: bool,
1667        transactions: Vec<serde_json::Value>,
1668        persistent: bool,
1669    ) -> Result<LockunspentResponse, TransportError> {
1670        let mut params = Vec::new();
1671        params.push(serde_json::to_value(unlock)?);
1672        params.push(serde_json::to_value(transactions)?);
1673        params.push(serde_json::to_value(persistent)?);
1674        self.transport.call("lockunspent", &params).await
1675    }
1676
1677    /// Gets and sets the logging configuration.
1678    /// When called without an argument, returns the list of categories with status that are currently being debug logged or not.
1679    /// When called with arguments, adds or removes categories from debug logging and return the lists above.
1680    /// The arguments are evaluated in order "include", "exclude".
1681    /// If an item is both included and excluded, it will thus end up being excluded.
1682    /// The valid logging categories are: addrman, bench, blockstorage, cmpctblock, coindb, estimatefee, http, i2p, ipc, leveldb, libevent, mempool, mempoolrej, net, proxy, prune, qt, rand, reindex, rpc, scan, selectcoins, tor, txpackages, txreconciliation, validation, walletdb, zmq
1683    /// In addition, the following are available as category names with special meanings:
1684    /// - "all",  "1" : represent all logging categories.
1685    pub async fn logging(
1686        &self,
1687        include: Vec<serde_json::Value>,
1688        exclude: Vec<serde_json::Value>,
1689    ) -> Result<LoggingResponse, TransportError> {
1690        let mut params = Vec::new();
1691        params.push(serde_json::to_value(include)?);
1692        params.push(serde_json::to_value(exclude)?);
1693        self.transport.call("logging", &params).await
1694    }
1695
1696    /// Migrate the wallet to a descriptor wallet.
1697    /// A new wallet backup will need to be made.
1698    ///
1699    /// The migration process will create a backup of the wallet before migrating. This backup
1700    /// file will be named <wallet name>-<timestamp>.legacy.bak and can be found in the directory
1701    /// for this wallet. In the event of an incorrect migration, the backup can be restored using restorewallet.
1702    /// Encrypted wallets must have the passphrase provided as an argument to this call.
1703    ///
1704    /// This RPC may take a long time to complete. Increasing the RPC client timeout is recommended.
1705    pub async fn migratewallet(
1706        &self,
1707        wallet_name: String,
1708        passphrase: String,
1709    ) -> Result<MigratewalletResponse, TransportError> {
1710        let mut params = Vec::new();
1711        params.push(serde_json::to_value(wallet_name)?);
1712        params.push(serde_json::to_value(passphrase)?);
1713        self.transport.call("migratewallet", &params).await
1714    }
1715
1716    /// Bump the scheduler into the future (-regtest only)
1717    pub async fn mockscheduler(&self, delta_time: u64) -> Result<(), TransportError> {
1718        let mut params = Vec::new();
1719        params.push(serde_json::to_value(delta_time)?);
1720        self.transport.call("mockscheduler", &params).await
1721    }
1722
1723    /// Requests that a ping be sent to all other nodes, to measure ping time.
1724    /// Results are provided in getpeerinfo.
1725    /// Ping command is handled in queue with all other commands, so it measures processing backlog, not just network ping.
1726    pub async fn ping(&self) -> Result<(), TransportError> {
1727        self.transport.call("ping", &[]).await
1728    }
1729
1730    /// Treats a block as if it were received before others with the same work.
1731    ///
1732    /// A later preciousblock call can override the effect of an earlier one.
1733    ///
1734    /// The effects of preciousblock are not retained across restarts.
1735    pub async fn preciousblock(&self, blockhash: bitcoin::BlockHash) -> Result<(), TransportError> {
1736        let mut params = Vec::new();
1737        params.push(serde_json::to_value(blockhash)?);
1738        self.transport.call("preciousblock", &params).await
1739    }
1740
1741    /// Accepts the transaction into mined blocks at a higher (or lower) priority
1742    pub async fn prioritisetransaction(
1743        &self,
1744        txid: bitcoin::Txid,
1745        dummy: Option<String>,
1746        fee_delta: f64,
1747    ) -> Result<PrioritisetransactionResponse, TransportError> {
1748        let mut params = Vec::new();
1749        params.push(serde_json::to_value(txid)?);
1750        params.push(serde_json::to_value(dummy)?);
1751        params.push(serde_json::to_value(fee_delta)?);
1752        self.transport.call("prioritisetransaction", &params).await
1753    }
1754
1755    /// Attempts to delete block and undo data up to a specified height or timestamp, if eligible for pruning.
1756    /// Requires ``-prune`` to be enabled at startup. While pruned data may be re-fetched in some cases (e.g., via ``getblockfrompeer``), local deletion is irreversible.
1757    pub async fn pruneblockchain(
1758        &self,
1759        height: u64,
1760    ) -> Result<PruneblockchainResponse, TransportError> {
1761        let mut params = Vec::new();
1762        params.push(serde_json::to_value(height)?);
1763        self.transport.call("pruneblockchain", &params).await
1764    }
1765
1766    /// Bumps the fee of a transaction T, replacing it with a new transaction B.
1767    /// Returns a PSBT instead of creating and signing a new transaction.
1768    /// A transaction with the given txid must be in the wallet.
1769    /// The command will pay the additional fee by reducing change outputs or adding inputs when necessary.
1770    /// It may add a new change output if one does not already exist.
1771    /// All inputs in the original transaction will be included in the replacement transaction.
1772    /// The command will fail if the wallet or mempool contains a transaction that spends one of T"s outputs.
1773    /// By default, the new fee will be calculated automatically using the estimatesmartfee RPC.
1774    /// The user can specify a confirmation target for estimatesmartfee.
1775    /// Alternatively, the user can specify a fee rate in sat/vB for the new transaction.
1776    /// At a minimum, the new fee rate must be high enough to pay an additional new relay fee (incrementalfee
1777    /// returned by getnetworkinfo) to enter the node"s mempool.
1778    /// * WARNING: before version 0.21, fee_rate was in BTC/kvB. As of 0.21, fee_rate is in sat/vB. *
1779    pub async fn psbtbumpfee(
1780        &self,
1781        txid: bitcoin::Txid,
1782        options: serde_json::Value,
1783    ) -> Result<PsbtbumpfeeResponse, TransportError> {
1784        let mut params = Vec::new();
1785        params.push(serde_json::to_value(txid)?);
1786        params.push(serde_json::to_value(options)?);
1787        self.transport.call("psbtbumpfee", &params).await
1788    }
1789
1790    /// Removes invalidity status of a block, its ancestors and its descendants, reconsider them for activation.
1791    /// This can be used to undo the effects of invalidateblock.
1792    pub async fn reconsiderblock(
1793        &self,
1794        blockhash: bitcoin::BlockHash,
1795    ) -> Result<(), TransportError> {
1796        let mut params = Vec::new();
1797        params.push(serde_json::to_value(blockhash)?);
1798        self.transport.call("reconsiderblock", &params).await
1799    }
1800
1801    /// Deletes the specified transaction from the wallet. Meant for use with pruned wallets and as a companion to importprunedfunds. This will affect wallet balances.
1802    pub async fn removeprunedfunds(&self, txid: bitcoin::Txid) -> Result<(), TransportError> {
1803        let mut params = Vec::new();
1804        params.push(serde_json::to_value(txid)?);
1805        self.transport.call("removeprunedfunds", &params).await
1806    }
1807
1808    /// Rescan the local blockchain for wallet related transactions.
1809    /// Note: Use "getwalletinfo" to query the scanning progress.
1810    /// The rescan is significantly faster if block filters are available
1811    /// (using startup option "-blockfilterindex=1").
1812    pub async fn rescanblockchain(
1813        &self,
1814        start_height: u64,
1815        stop_height: u64,
1816    ) -> Result<RescanblockchainResponse, TransportError> {
1817        let mut params = Vec::new();
1818        params.push(serde_json::to_value(start_height)?);
1819        params.push(serde_json::to_value(stop_height)?);
1820        self.transport.call("rescanblockchain", &params).await
1821    }
1822
1823    /// Restores and loads a wallet from backup.
1824    ///
1825    /// The rescan is significantly faster if block filters are available
1826    /// (using startup option "-blockfilterindex=1").
1827    pub async fn restorewallet(
1828        &self,
1829        wallet_name: String,
1830        backup_file: String,
1831        load_on_startup: bool,
1832    ) -> Result<RestorewalletResponse, TransportError> {
1833        let mut params = Vec::new();
1834        params.push(serde_json::to_value(wallet_name)?);
1835        params.push(serde_json::to_value(backup_file)?);
1836        params.push(serde_json::to_value(load_on_startup)?);
1837        self.transport.call("restorewallet", &params).await
1838    }
1839
1840    /// Dumps the mempool to disk. It will fail until the previous dump is fully loaded.
1841    pub async fn savemempool(&self) -> Result<SavemempoolResponse, TransportError> {
1842        self.transport.call("savemempool", &[]).await
1843    }
1844
1845    /// Return relevant blockhashes for given descriptors (requires blockfilterindex).
1846    /// This call may take several minutes. Make sure to use no RPC timeout (bitcoin-cli -rpcclienttimeout=0)
1847    pub async fn scanblocks(
1848        &self,
1849        action: String,
1850        scanobjects: Vec<serde_json::Value>,
1851        start_height: u64,
1852        stop_height: u64,
1853        filtertype: String,
1854        options: serde_json::Value,
1855    ) -> Result<(), TransportError> {
1856        let mut params = Vec::new();
1857        params.push(serde_json::to_value(action)?);
1858        params.push(serde_json::to_value(scanobjects)?);
1859        params.push(serde_json::to_value(start_height)?);
1860        params.push(serde_json::to_value(stop_height)?);
1861        params.push(serde_json::to_value(filtertype)?);
1862        params.push(serde_json::to_value(options)?);
1863        self.transport.call("scanblocks", &params).await
1864    }
1865
1866    /// Scans the unspent transaction output set for entries that match certain output descriptors.
1867    /// Examples of output descriptors are:
1868    /// addr(<address>)                      Outputs whose output script corresponds to the specified address (does not include P2PK)
1869    /// raw(<hex script>)                    Outputs whose output script equals the specified hex-encoded bytes
1870    /// combo(<pubkey>)                      P2PK, P2PKH, P2WPKH, and P2SH-P2WPKH outputs for the given pubkey
1871    /// pkh(<pubkey>)                        P2PKH outputs for the given pubkey
1872    /// sh(multi(<n>,<pubkey>,<pubkey>,...)) P2SH-multisig outputs for the given threshold and pubkeys
1873    /// tr(<pubkey>)                         P2TR
1874    /// tr(<pubkey>,{pk(<pubkey>)})          P2TR with single fallback pubkey in tapscript
1875    /// rawtr(<pubkey>)                      P2TR with the specified key as output key rather than inner
1876    /// wsh(and_v(v:pk(<pubkey>),after(2)))  P2WSH miniscript with mandatory pubkey and a timelock
1877    ///
1878    /// In the above, <pubkey> either refers to a fixed public key in hexadecimal notation, or to an xpub/xprv optionally followed by one
1879    /// or more path elements separated by "/", and optionally ending in "/*" (unhardened), or "/*"" or "/*h" (hardened) to specify all
1880    /// unhardened or hardened child keys.
1881    /// In the latter case, a range needs to be specified by below if different from 1000.
1882    /// For more information on output descriptors, see the documentation in the doc/descriptors.md file.
1883    pub async fn scantxoutset(
1884        &self,
1885        action: String,
1886        scanobjects: Vec<serde_json::Value>,
1887    ) -> Result<ScantxoutsetResponse, TransportError> {
1888        let mut params = Vec::new();
1889        params.push(serde_json::to_value(action)?);
1890        params.push(serde_json::to_value(scanobjects)?);
1891        self.transport.call("scantxoutset", &params).await
1892    }
1893
1894    /// Return RPC command JSON Schema descriptions.
1895    pub async fn schema(&self) -> Result<SchemaResponse, TransportError> {
1896        self.transport.call("schema", &[]).await
1897    }
1898
1899    /// EXPERIMENTAL warning: this call may be changed in future releases.
1900    ///
1901    /// Send a transaction.
1902    pub async fn send(
1903        &self,
1904        outputs: Vec<serde_json::Value>,
1905        conf_target: u64,
1906        estimate_mode: String,
1907        fee_rate: f64,
1908        options: serde_json::Value,
1909        version: u32,
1910    ) -> Result<SendResponse, TransportError> {
1911        let mut params = Vec::new();
1912        params.push(serde_json::to_value(outputs)?);
1913        params.push(serde_json::to_value(conf_target)?);
1914        params.push(serde_json::to_value(estimate_mode)?);
1915        params.push(serde_json::to_value(fee_rate)?);
1916        params.push(serde_json::to_value(options)?);
1917        params.push(serde_json::to_value(version)?);
1918        self.transport.call("send", &params).await
1919    }
1920
1921    /// EXPERIMENTAL warning: this call may be changed in future releases.
1922    ///
1923    /// Spend the value of all (or specific) confirmed UTXOs and unconfirmed change in the wallet to one or more recipients.
1924    /// Unconfirmed inbound UTXOs and locked UTXOs will not be spent. Sendall will respect the avoid_reuse wallet flag.
1925    /// If your wallet contains many small inputs, either because it received tiny payments or as a result of accumulating change, consider using ``send_max`` to exclude inputs that are worth less than the fees needed to spend them.
1926    pub async fn sendall(
1927        &self,
1928        recipients: Vec<serde_json::Value>,
1929        conf_target: u64,
1930        estimate_mode: String,
1931        fee_rate: f64,
1932        options: serde_json::Value,
1933    ) -> Result<SendallResponse, TransportError> {
1934        let mut params = Vec::new();
1935        params.push(serde_json::to_value(recipients)?);
1936        params.push(serde_json::to_value(conf_target)?);
1937        params.push(serde_json::to_value(estimate_mode)?);
1938        params.push(serde_json::to_value(fee_rate)?);
1939        params.push(serde_json::to_value(options)?);
1940        self.transport.call("sendall", &params).await
1941    }
1942
1943    /// Send multiple times. Amounts are double-precision floating point numbers.
1944    /// Requires wallet passphrase to be set with walletpassphrase call if wallet is encrypted.
1945    #[allow(clippy::too_many_arguments)]
1946    pub async fn sendmany(
1947        &self,
1948        dummy: Option<String>,
1949        amounts: serde_json::Value,
1950        minconf: u32,
1951        comment: String,
1952        subtractfeefrom: Vec<serde_json::Value>,
1953        replaceable: bool,
1954        conf_target: u64,
1955        estimate_mode: String,
1956        fee_rate: f64,
1957        verbose: bool,
1958    ) -> Result<SendmanyResponse, TransportError> {
1959        let mut params = Vec::new();
1960        params.push(serde_json::to_value(dummy)?);
1961        params.push(serde_json::to_value(amounts)?);
1962        params.push(serde_json::to_value(minconf)?);
1963        params.push(serde_json::to_value(comment)?);
1964        params.push(serde_json::to_value(subtractfeefrom)?);
1965        params.push(serde_json::to_value(replaceable)?);
1966        params.push(serde_json::to_value(conf_target)?);
1967        params.push(serde_json::to_value(estimate_mode)?);
1968        params.push(serde_json::to_value(fee_rate)?);
1969        params.push(serde_json::to_value(verbose)?);
1970        self.transport.call("sendmany", &params).await
1971    }
1972
1973    /// Send a p2p message to a peer specified by id.
1974    /// The message type and body must be provided, the message header will be generated.
1975    /// This RPC is for testing only.
1976    pub async fn sendmsgtopeer(
1977        &self,
1978        peer_id: u64,
1979        msg_type: String,
1980        msg: String,
1981    ) -> Result<SendmsgtopeerResponse, TransportError> {
1982        let mut params = Vec::new();
1983        params.push(serde_json::to_value(peer_id)?);
1984        params.push(serde_json::to_value(msg_type)?);
1985        params.push(serde_json::to_value(msg)?);
1986        self.transport.call("sendmsgtopeer", &params).await
1987    }
1988
1989    /// Submit a raw transaction (serialized, hex-encoded) to local node and network.
1990    ///
1991    /// The transaction will be sent unconditionally to all peers, so using sendrawtransaction
1992    /// for manual rebroadcast may degrade privacy by leaking the transaction"s origin, as
1993    /// nodes will normally not rebroadcast non-wallet transactions already in their mempool.
1994    ///
1995    /// A specific exception, RPC_TRANSACTION_ALREADY_IN_UTXO_SET, may throw if the transaction cannot be added to the mempool.
1996    ///
1997    /// Related RPCs: createrawtransaction, signrawtransactionwithkey
1998    pub async fn sendrawtransaction(
1999        &self,
2000        hexstring: String,
2001        maxfeerate: f64,
2002        maxburnamount: f64,
2003    ) -> Result<SendrawtransactionResponse, TransportError> {
2004        let mut params = Vec::new();
2005        params.push(serde_json::to_value(hexstring)?);
2006        params.push(serde_json::to_value(maxfeerate)?);
2007        params.push(serde_json::to_value(maxburnamount)?);
2008        self.transport.call("sendrawtransaction", &params).await
2009    }
2010
2011    /// Send an amount to a given address.
2012    /// Requires wallet passphrase to be set with walletpassphrase call if wallet is encrypted.
2013    #[allow(clippy::too_many_arguments)]
2014    pub async fn sendtoaddress(
2015        &self,
2016        address: String,
2017        amount: bitcoin::Amount,
2018        comment: String,
2019        comment_to: String,
2020        subtractfeefromamount: bool,
2021        replaceable: bool,
2022        conf_target: u64,
2023        estimate_mode: String,
2024        avoid_reuse: bool,
2025        fee_rate: f64,
2026        verbose: bool,
2027    ) -> Result<SendtoaddressResponse, TransportError> {
2028        let mut params = Vec::new();
2029        params.push(serde_json::to_value(address)?);
2030        params.push(serde_json::to_value(amount)?);
2031        params.push(serde_json::to_value(comment)?);
2032        params.push(serde_json::to_value(comment_to)?);
2033        params.push(serde_json::to_value(subtractfeefromamount)?);
2034        params.push(serde_json::to_value(replaceable)?);
2035        params.push(serde_json::to_value(conf_target)?);
2036        params.push(serde_json::to_value(estimate_mode)?);
2037        params.push(serde_json::to_value(avoid_reuse)?);
2038        params.push(serde_json::to_value(fee_rate)?);
2039        params.push(serde_json::to_value(verbose)?);
2040        self.transport.call("sendtoaddress", &params).await
2041    }
2042
2043    /// Attempts to add or remove an IP/Subnet from the banned list.
2044    pub async fn setban(
2045        &self,
2046        subnet: String,
2047        command: String,
2048        bantime: u64,
2049        absolute: bool,
2050    ) -> Result<(), TransportError> {
2051        let mut params = Vec::new();
2052        params.push(serde_json::to_value(subnet)?);
2053        params.push(serde_json::to_value(command)?);
2054        params.push(serde_json::to_value(bantime)?);
2055        params.push(serde_json::to_value(absolute)?);
2056        self.transport.call("setban", &params).await
2057    }
2058
2059    /// Sets the label associated with the given address.
2060    pub async fn setlabel(&self, address: String, label: String) -> Result<(), TransportError> {
2061        let mut params = Vec::new();
2062        params.push(serde_json::to_value(address)?);
2063        params.push(serde_json::to_value(label)?);
2064        self.transport.call("setlabel", &params).await
2065    }
2066
2067    /// Set the local time to given timestamp (-regtest only)
2068    pub async fn setmocktime(&self, timestamp: u64) -> Result<(), TransportError> {
2069        let mut params = Vec::new();
2070        params.push(serde_json::to_value(timestamp)?);
2071        self.transport.call("setmocktime", &params).await
2072    }
2073
2074    /// Disable/enable all p2p network activity.
2075    pub async fn setnetworkactive(
2076        &self,
2077        state: bool,
2078    ) -> Result<SetnetworkactiveResponse, TransportError> {
2079        let mut params = Vec::new();
2080        params.push(serde_json::to_value(state)?);
2081        self.transport.call("setnetworkactive", &params).await
2082    }
2083
2084    /// (DEPRECATED) Set the transaction fee rate in BTC/kvB for this wallet. Overrides the global -paytxfee command line parameter.
2085    /// Can be deactivated by passing 0 as the fee. In that case automatic fee selection will be used by default.
2086    pub async fn settxfee(
2087        &self,
2088        amount: bitcoin::Amount,
2089    ) -> Result<SettxfeeResponse, TransportError> {
2090        let mut params = Vec::new();
2091        params.push(serde_json::to_value(amount)?);
2092        self.transport.call("settxfee", &params).await
2093    }
2094
2095    /// Change the state of the given wallet flag for a wallet.
2096    pub async fn setwalletflag(
2097        &self,
2098        flag: String,
2099        value: bool,
2100    ) -> Result<SetwalletflagResponse, TransportError> {
2101        let mut params = Vec::new();
2102        params.push(serde_json::to_value(flag)?);
2103        params.push(serde_json::to_value(value)?);
2104        self.transport.call("setwalletflag", &params).await
2105    }
2106
2107    /// Sign a message with the private key of an address
2108    /// Requires wallet passphrase to be set with walletpassphrase call if wallet is encrypted.
2109    pub async fn signmessage(
2110        &self,
2111        address: String,
2112        message: String,
2113    ) -> Result<SignmessageResponse, TransportError> {
2114        let mut params = Vec::new();
2115        params.push(serde_json::to_value(address)?);
2116        params.push(serde_json::to_value(message)?);
2117        self.transport.call("signmessage", &params).await
2118    }
2119
2120    /// Sign a message with the private key of an address
2121    pub async fn signmessagewithprivkey(
2122        &self,
2123        privkey: String,
2124        message: String,
2125    ) -> Result<SignmessagewithprivkeyResponse, TransportError> {
2126        let mut params = Vec::new();
2127        params.push(serde_json::to_value(privkey)?);
2128        params.push(serde_json::to_value(message)?);
2129        self.transport.call("signmessagewithprivkey", &params).await
2130    }
2131
2132    /// Sign inputs for raw transaction (serialized, hex-encoded).
2133    /// The second argument is an array of base58-encoded private
2134    /// keys that will be the only keys used to sign the transaction.
2135    /// The third optional argument (may be null) is an array of previous transaction outputs that
2136    /// this transaction depends on but may not yet be in the block chain.
2137    pub async fn signrawtransactionwithkey(
2138        &self,
2139        hexstring: String,
2140        privkeys: Vec<String>,
2141        prevtxs: Vec<serde_json::Value>,
2142        sighashtype: String,
2143    ) -> Result<SignrawtransactionwithkeyResponse, TransportError> {
2144        let mut params = Vec::new();
2145        params.push(serde_json::to_value(hexstring)?);
2146        params.push(serde_json::to_value(privkeys)?);
2147        params.push(serde_json::to_value(prevtxs)?);
2148        params.push(serde_json::to_value(sighashtype)?);
2149        self.transport.call("signrawtransactionwithkey", &params).await
2150    }
2151
2152    /// Sign inputs for raw transaction (serialized, hex-encoded).
2153    /// The second optional argument (may be null) is an array of previous transaction outputs that
2154    /// this transaction depends on but may not yet be in the block chain.
2155    /// Requires wallet passphrase to be set with walletpassphrase call if wallet is encrypted.
2156    pub async fn signrawtransactionwithwallet(
2157        &self,
2158        hexstring: String,
2159        prevtxs: Vec<serde_json::Value>,
2160        sighashtype: String,
2161    ) -> Result<SignrawtransactionwithwalletResponse, TransportError> {
2162        let mut params = Vec::new();
2163        params.push(serde_json::to_value(hexstring)?);
2164        params.push(serde_json::to_value(prevtxs)?);
2165        params.push(serde_json::to_value(sighashtype)?);
2166        self.transport.call("signrawtransactionwithwallet", &params).await
2167    }
2168
2169    /// Calculate the balance change resulting in the signing and broadcasting of the given transaction(s).
2170    pub async fn simulaterawtransaction(
2171        &self,
2172        rawtxs: Vec<serde_json::Value>,
2173        options: serde_json::Value,
2174    ) -> Result<SimulaterawtransactionResponse, TransportError> {
2175        let mut params = Vec::new();
2176        params.push(serde_json::to_value(rawtxs)?);
2177        params.push(serde_json::to_value(options)?);
2178        self.transport.call("simulaterawtransaction", &params).await
2179    }
2180
2181    /// Request a graceful shutdown of Bitcoin Core.
2182    pub async fn stop(&self, wait: u64) -> Result<StopResponse, TransportError> {
2183        let mut params = Vec::new();
2184        params.push(serde_json::to_value(wait)?);
2185        self.transport.call("stop", &params).await
2186    }
2187
2188    /// Attempts to submit new block to network.
2189    /// See https://en.bitcoin.it/wiki/BIP_0022 for full specification.
2190    pub async fn submitblock(
2191        &self,
2192        hexdata: String,
2193        dummy: Option<String>,
2194    ) -> Result<(), TransportError> {
2195        let mut params = Vec::new();
2196        params.push(serde_json::to_value(hexdata)?);
2197        params.push(serde_json::to_value(dummy)?);
2198        self.transport.call("submitblock", &params).await
2199    }
2200
2201    /// Decode the given hexdata as a header and submit it as a candidate chain tip if valid.
2202    /// Throws when the header is invalid.
2203    pub async fn submitheader(&self, hexdata: String) -> Result<(), TransportError> {
2204        let mut params = Vec::new();
2205        params.push(serde_json::to_value(hexdata)?);
2206        self.transport.call("submitheader", &params).await
2207    }
2208
2209    /// Submit a package of raw transactions (serialized, hex-encoded) to local node.
2210    /// The package will be validated according to consensus and mempool policy rules. If any transaction passes, it will be accepted to mempool.
2211    /// This RPC is experimental and the interface may be unstable. Refer to doc/policy/packages.md for documentation on package policies.
2212    /// Warning: successful submission does not mean the transactions will propagate throughout the network.
2213    pub async fn submitpackage(
2214        &self,
2215        package: Vec<serde_json::Value>,
2216        maxfeerate: f64,
2217        maxburnamount: f64,
2218    ) -> Result<SubmitpackageResponse, TransportError> {
2219        let mut params = Vec::new();
2220        params.push(serde_json::to_value(package)?);
2221        params.push(serde_json::to_value(maxfeerate)?);
2222        params.push(serde_json::to_value(maxburnamount)?);
2223        self.transport.call("submitpackage", &params).await
2224    }
2225
2226    /// Waits for the validation interface queue to catch up on everything that was there when we entered this function.
2227    pub async fn syncwithvalidationinterfacequeue(&self) -> Result<(), TransportError> {
2228        self.transport.call("syncwithvalidationinterfacequeue", &[]).await
2229    }
2230
2231    /// Returns result of mempool acceptance tests indicating if raw transaction(s) (serialized, hex-encoded) would be accepted by mempool.
2232    ///
2233    /// If multiple transactions are passed in, parents must come before children and package policies apply: the transactions cannot conflict with any mempool transactions or each other.
2234    ///
2235    /// If one transaction fails, other transactions may not be fully validated (the "allowed" key will be blank).
2236    ///
2237    /// The maximum number of transactions allowed is 25.
2238    ///
2239    /// This checks if transactions violate the consensus or policy rules.
2240    ///
2241    /// See sendrawtransaction call.
2242    pub async fn testmempoolaccept(
2243        &self,
2244        rawtxs: Vec<serde_json::Value>,
2245        maxfeerate: f64,
2246    ) -> Result<TestmempoolacceptResponse, TransportError> {
2247        let mut params = Vec::new();
2248        params.push(serde_json::to_value(rawtxs)?);
2249        params.push(serde_json::to_value(maxfeerate)?);
2250        self.transport.call("testmempoolaccept", &params).await
2251    }
2252
2253    /// Unloads the wallet referenced by the request endpoint or the wallet_name argument.
2254    /// If both are specified, they must be identical.
2255    pub async fn unloadwallet(
2256        &self,
2257        wallet_name: String,
2258        load_on_startup: bool,
2259    ) -> Result<UnloadwalletResponse, TransportError> {
2260        let mut params = Vec::new();
2261        params.push(serde_json::to_value(wallet_name)?);
2262        params.push(serde_json::to_value(load_on_startup)?);
2263        self.transport.call("unloadwallet", &params).await
2264    }
2265
2266    /// Returns the total uptime of the server.
2267    pub async fn uptime(&self) -> Result<UptimeResponse, TransportError> {
2268        self.transport.call("uptime", &[]).await
2269    }
2270
2271    /// Updates all segwit inputs and outputs in a PSBT with data from output descriptors, the UTXO set, txindex, or the mempool.
2272    pub async fn utxoupdatepsbt(
2273        &self,
2274        psbt: String,
2275        descriptors: Vec<serde_json::Value>,
2276    ) -> Result<UtxoupdatepsbtResponse, TransportError> {
2277        let mut params = Vec::new();
2278        params.push(serde_json::to_value(psbt)?);
2279        params.push(serde_json::to_value(descriptors)?);
2280        self.transport.call("utxoupdatepsbt", &params).await
2281    }
2282
2283    /// Return information about the given bitcoin address.
2284    pub async fn validateaddress(
2285        &self,
2286        address: String,
2287    ) -> Result<ValidateaddressResponse, TransportError> {
2288        let mut params = Vec::new();
2289        params.push(serde_json::to_value(address)?);
2290        self.transport.call("validateaddress", &params).await
2291    }
2292
2293    /// Verifies blockchain database.
2294    pub async fn verifychain(
2295        &self,
2296        checklevel: u32,
2297        nblocks: u64,
2298    ) -> Result<VerifychainResponse, TransportError> {
2299        let mut params = Vec::new();
2300        params.push(serde_json::to_value(checklevel)?);
2301        params.push(serde_json::to_value(nblocks)?);
2302        self.transport.call("verifychain", &params).await
2303    }
2304
2305    /// Verify a signed message.
2306    pub async fn verifymessage(
2307        &self,
2308        address: String,
2309        signature: String,
2310        message: String,
2311    ) -> Result<VerifymessageResponse, TransportError> {
2312        let mut params = Vec::new();
2313        params.push(serde_json::to_value(address)?);
2314        params.push(serde_json::to_value(signature)?);
2315        params.push(serde_json::to_value(message)?);
2316        self.transport.call("verifymessage", &params).await
2317    }
2318
2319    /// Verifies that a proof points to a transaction in a block, returning the transaction it commits to
2320    /// and throwing an RPC error if the block is not in our best chain
2321    pub async fn verifytxoutproof(
2322        &self,
2323        proof: String,
2324    ) -> Result<VerifytxoutproofResponse, TransportError> {
2325        let mut params = Vec::new();
2326        params.push(serde_json::to_value(proof)?);
2327        self.transport.call("verifytxoutproof", &params).await
2328    }
2329
2330    /// Waits for a specific new block and returns useful info about it.
2331    ///
2332    /// Returns the current block on timeout or exit.
2333    ///
2334    /// Make sure to use no RPC timeout (bitcoin-cli -rpcclienttimeout=0)
2335    pub async fn waitforblock(
2336        &self,
2337        blockhash: bitcoin::BlockHash,
2338        timeout: u64,
2339    ) -> Result<WaitforblockResponse, TransportError> {
2340        let mut params = Vec::new();
2341        params.push(serde_json::to_value(blockhash)?);
2342        params.push(serde_json::to_value(timeout)?);
2343        self.transport.call("waitforblock", &params).await
2344    }
2345
2346    /// Waits for (at least) block height and returns the height and hash
2347    /// of the current tip.
2348    ///
2349    /// Returns the current block on timeout or exit.
2350    ///
2351    /// Make sure to use no RPC timeout (bitcoin-cli -rpcclienttimeout=0)
2352    pub async fn waitforblockheight(
2353        &self,
2354        height: u64,
2355        timeout: u64,
2356    ) -> Result<WaitforblockheightResponse, TransportError> {
2357        let mut params = Vec::new();
2358        params.push(serde_json::to_value(height)?);
2359        params.push(serde_json::to_value(timeout)?);
2360        self.transport.call("waitforblockheight", &params).await
2361    }
2362
2363    /// Waits for any new block and returns useful info about it.
2364    ///
2365    /// Returns the current block on timeout or exit.
2366    ///
2367    /// Make sure to use no RPC timeout (bitcoin-cli -rpcclienttimeout=0)
2368    pub async fn waitfornewblock(
2369        &self,
2370        timeout: u64,
2371        current_tip: String,
2372    ) -> Result<WaitfornewblockResponse, TransportError> {
2373        let mut params = Vec::new();
2374        params.push(serde_json::to_value(timeout)?);
2375        params.push(serde_json::to_value(current_tip)?);
2376        self.transport.call("waitfornewblock", &params).await
2377    }
2378
2379    /// Creates and funds a transaction in the Partially Signed Transaction format.
2380    /// Implements the Creator and Updater roles.
2381    /// All existing inputs must either have their previous output transaction be in the wallet
2382    /// or be in the UTXO set. Solving data must be provided for non-wallet inputs.
2383    pub async fn walletcreatefundedpsbt(
2384        &self,
2385        inputs: Vec<serde_json::Value>,
2386        outputs: Vec<serde_json::Value>,
2387        locktime: u32,
2388        options: serde_json::Value,
2389        bip32derivs: bool,
2390        version: u32,
2391    ) -> Result<WalletcreatefundedpsbtResponse, TransportError> {
2392        let mut params = Vec::new();
2393        params.push(serde_json::to_value(inputs)?);
2394        params.push(serde_json::to_value(outputs)?);
2395        params.push(serde_json::to_value(locktime)?);
2396        params.push(serde_json::to_value(options)?);
2397        params.push(serde_json::to_value(bip32derivs)?);
2398        params.push(serde_json::to_value(version)?);
2399        self.transport.call("walletcreatefundedpsbt", &params).await
2400    }
2401
2402    /// Display address on an external signer for verification.
2403    pub async fn walletdisplayaddress(
2404        &self,
2405        address: String,
2406    ) -> Result<WalletdisplayaddressResponse, TransportError> {
2407        let mut params = Vec::new();
2408        params.push(serde_json::to_value(address)?);
2409        self.transport.call("walletdisplayaddress", &params).await
2410    }
2411
2412    /// Removes the wallet encryption key from memory, locking the wallet.
2413    /// After calling this method, you will need to call walletpassphrase again
2414    /// before being able to call any methods which require the wallet to be unlocked.
2415    pub async fn walletlock(&self) -> Result<(), TransportError> {
2416        self.transport.call("walletlock", &[]).await
2417    }
2418
2419    /// Stores the wallet decryption key in memory for "timeout" seconds.
2420    /// This is needed prior to performing transactions related to private keys such as sending bitcoins
2421    ///
2422    /// Note:
2423    /// Issuing the walletpassphrase command while the wallet is already unlocked will set a new unlock
2424    /// time that overrides the old one.
2425    pub async fn walletpassphrase(
2426        &self,
2427        passphrase: String,
2428        timeout: u64,
2429    ) -> Result<(), TransportError> {
2430        let mut params = Vec::new();
2431        params.push(serde_json::to_value(passphrase)?);
2432        params.push(serde_json::to_value(timeout)?);
2433        self.transport.call("walletpassphrase", &params).await
2434    }
2435
2436    /// Changes the wallet passphrase from "oldpassphrase" to "newpassphrase".
2437    pub async fn walletpassphrasechange(
2438        &self,
2439        oldpassphrase: String,
2440        newpassphrase: String,
2441    ) -> Result<(), TransportError> {
2442        let mut params = Vec::new();
2443        params.push(serde_json::to_value(oldpassphrase)?);
2444        params.push(serde_json::to_value(newpassphrase)?);
2445        self.transport.call("walletpassphrasechange", &params).await
2446    }
2447
2448    /// Update a PSBT with input information from our wallet and then sign inputs
2449    /// that we can sign for.
2450    /// Requires wallet passphrase to be set with walletpassphrase call if wallet is encrypted.
2451    pub async fn walletprocesspsbt(
2452        &self,
2453        psbt: String,
2454        sign: bool,
2455        sighashtype: String,
2456        bip32derivs: bool,
2457        finalize: bool,
2458    ) -> Result<WalletprocesspsbtResponse, TransportError> {
2459        let mut params = Vec::new();
2460        params.push(serde_json::to_value(psbt)?);
2461        params.push(serde_json::to_value(sign)?);
2462        params.push(serde_json::to_value(sighashtype)?);
2463        params.push(serde_json::to_value(bip32derivs)?);
2464        params.push(serde_json::to_value(finalize)?);
2465        self.transport.call("walletprocesspsbt", &params).await
2466    }
2467
2468    /// Helper method to send bitcoin to an address with either a confirmation target or fee rate.
2469    /// This is a more ergonomic wrapper around sendtoaddress that prevents specifying both conf_target and fee_rate.
2470    ///
2471    /// Parameters:
2472    /// - address: The destination address
2473    /// - amount: The amount to send
2474    /// - conf_target: The confirmation target in blocks
2475    /// - estimate_mode: The fee estimate mode ("economical" or "conservative")
2476    /// ```
2477    pub async fn send_to_address_with_conf_target(
2478        &self,
2479        address: String,
2480        amount: Amount,
2481        conf_target: u64,
2482        estimate_mode: String,
2483    ) -> Result<Value, TransportError> {
2484        Ok(serde_json::to_value(
2485            self.sendtoaddress(
2486                address,
2487                amount,
2488                "".to_string(),
2489                "".to_string(),
2490                false,
2491                true,
2492                conf_target,
2493                estimate_mode,
2494                false,
2495                0.0,
2496                false,
2497            )
2498            .await?,
2499        )?)
2500    }
2501
2502    pub async fn send_to_address_with_fee_rate(
2503        &self,
2504        address: String,
2505        amount: Amount,
2506        fee_rate: f64,
2507    ) -> Result<Value, TransportError> {
2508        Ok(serde_json::to_value(
2509            self.sendtoaddress(
2510                address,
2511                amount,
2512                "".to_string(),
2513                "".to_string(),
2514                false,
2515                true,
2516                0u64,
2517                "unset".to_string(),
2518                false,
2519                fee_rate,
2520                false,
2521            )
2522            .await?,
2523        )?)
2524    }
2525}
2526
2527impl Drop for BitcoinTestClient {
2528    fn drop(&mut self) { let _ = self.node_manager.take(); }
2529}