bitgesellcore_rpc_json/
lib.rs

1// To the extent possible under law, the author(s) have dedicated all
2// copyright and related and neighboring rights to this software to
3// the public domain worldwide. This software is distributed without
4// any warranty.
5//
6// You should have received a copy of the CC0 Public Domain Dedication
7// along with this software.
8// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
9//
10
11//! # Rust Client for Bitcoin Core API
12//!
13//! This is a client library for the Bitcoin Core JSON-RPC API.
14//!
15
16#![crate_name = "bitgesellcore_rpc_json"]
17#![crate_type = "rlib"]
18
19pub extern crate bitcoin;
20#[allow(unused)]
21#[macro_use] // `macro_use` is needed for v1.24.0 compilation.
22extern crate serde;
23extern crate serde_json;
24
25use std::collections::HashMap;
26
27
28use bitcoin::address::NetworkUnchecked;
29use bitcoin::block::Version;
30use bitcoin::consensus::encode;
31use bitcoin::hashes::hex::FromHex;
32use bitcoin::hashes::sha256;
33use bitcoin::{Address, Amount, PrivateKey, PublicKey, SignedAmount, Transaction, ScriptBuf, Script, bip158, bip32, Network};
34use serde::de::Error as SerdeError;
35use serde::{Deserialize, Serialize};
36use std::fmt;
37
38//TODO(stevenroose) consider using a Time type
39
40/// A module used for serde serialization of bytes in hexadecimal format.
41///
42/// The module is compatible with the serde attribute.
43pub mod serde_hex {
44    use bitcoin::hashes::hex::FromHex;
45    use bitcoin_private::hex::exts::DisplayHex;
46    use serde::de::Error;
47    use serde::{Deserializer, Serializer};
48
49    pub fn serialize<S: Serializer>(b: &Vec<u8>, s: S) -> Result<S::Ok, S::Error> {
50        s.serialize_str(&b.to_lower_hex_string())
51    }
52
53    pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result<Vec<u8>, D::Error> {
54        let hex_str: String = ::serde::Deserialize::deserialize(d)?;
55        Ok(FromHex::from_hex(&hex_str).map_err(D::Error::custom)?)
56    }
57
58    pub mod opt {
59        use bitcoin::hashes::hex::FromHex;
60        use bitcoin_private::hex::exts::DisplayHex;
61        use serde::de::Error;
62        use serde::{Deserializer, Serializer};
63
64        pub fn serialize<S: Serializer>(b: &Option<Vec<u8>>, s: S) -> Result<S::Ok, S::Error> {
65            match *b {
66                None => s.serialize_none(),
67                Some(ref b) => s.serialize_str(&b.to_lower_hex_string()),
68            }
69        }
70
71        pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result<Option<Vec<u8>>, D::Error> {
72            let hex_str: String = ::serde::Deserialize::deserialize(d)?;
73            Ok(Some(FromHex::from_hex(&hex_str).map_err(D::Error::custom)?))
74        }
75    }
76}
77
78#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
79pub struct GetNetworkInfoResultNetwork {
80    pub name: String,
81    pub limited: bool,
82    pub reachable: bool,
83    pub proxy: String,
84    pub proxy_randomize_credentials: bool,
85}
86
87#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
88pub struct GetNetworkInfoResultAddress {
89    pub address: String,
90    pub port: usize,
91    pub score: usize,
92}
93
94#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
95pub struct GetNetworkInfoResult {
96    pub version: usize,
97    pub subversion: String,
98    #[serde(rename = "protocolversion")]
99    pub protocol_version: usize,
100    #[serde(rename = "localservices")]
101    pub local_services: String,
102    #[serde(rename = "localrelay")]
103    pub local_relay: bool,
104    #[serde(rename = "timeoffset")]
105    pub time_offset: isize,
106    pub connections: usize,
107    /// The number of inbound connections
108    /// Added in Bitcoin Core v0.21
109    pub connections_in: Option<usize>,
110    /// The number of outbound connections
111    /// Added in Bitcoin Core v0.21
112    pub connections_out: Option<usize>,
113    #[serde(rename = "networkactive")]
114    pub network_active: bool,
115    pub networks: Vec<GetNetworkInfoResultNetwork>,
116    #[serde(rename = "relayfee", with = "bitcoin::amount::serde::as_btc")]
117    pub relay_fee: Amount,
118    #[serde(rename = "incrementalfee", with = "bitcoin::amount::serde::as_btc")]
119    pub incremental_fee: Amount,
120    #[serde(rename = "localaddresses")]
121    pub local_addresses: Vec<GetNetworkInfoResultAddress>,
122    pub warnings: String,
123}
124
125#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
126#[serde(rename_all = "camelCase")]
127pub struct AddMultiSigAddressResult {
128    pub address: Address<NetworkUnchecked>,
129    pub redeem_script: ScriptBuf,
130}
131
132#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
133pub struct LoadWalletResult {
134    pub name: String,
135    pub warning: Option<String>,
136}
137
138#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
139pub struct UnloadWalletResult {
140    pub warning: Option<String>,
141}
142
143#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
144pub struct ListWalletDirResult {
145    pub wallets: Vec<ListWalletDirItem>,
146}
147
148#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
149pub struct ListWalletDirItem {
150    pub name: String,
151}
152
153#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
154pub struct GetWalletInfoResult {
155    #[serde(rename = "walletname")]
156    pub wallet_name: String,
157    #[serde(rename = "walletversion")]
158    pub wallet_version: u32,
159    #[serde(with = "bitcoin::amount::serde::as_btc")]
160    pub balance: Amount,
161    #[serde(with = "bitcoin::amount::serde::as_btc")]
162    pub unconfirmed_balance: Amount,
163    #[serde(with = "bitcoin::amount::serde::as_btc")]
164    pub immature_balance: Amount,
165    #[serde(rename = "txcount")]
166    pub tx_count: usize,
167    #[serde(rename = "keypoololdest")]
168    pub keypool_oldest: Option<usize>,
169    #[serde(rename = "keypoolsize")]
170    pub keypool_size: usize,
171    #[serde(rename = "keypoolsize_hd_internal")]
172    pub keypool_size_hd_internal: usize,
173    pub unlocked_until: Option<u64>,
174    #[serde(rename = "paytxfee", with = "bitcoin::amount::serde::as_btc")]
175    pub pay_tx_fee: Amount,
176    #[serde(rename = "hdseedid")]
177    pub hd_seed_id: Option<bitcoin::hash_types::XpubIdentifier>,
178    pub private_keys_enabled: bool,
179    pub avoid_reuse: Option<bool>,
180    pub scanning: Option<ScanningDetails>,
181}
182
183#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
184#[serde(untagged)]
185pub enum ScanningDetails {
186    Scanning {
187        duration: usize,
188        progress: f32,
189    },
190    /// The bool in this field will always be false.
191    NotScanning(bool),
192}
193
194impl Eq for ScanningDetails {}
195
196#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
197#[serde(rename_all = "camelCase")]
198pub struct GetBlockResult {
199    pub hash: bitcoin::BlockHash,
200    pub confirmations: i32,
201    pub size: usize,
202    pub strippedsize: Option<usize>,
203    pub weight: usize,
204    pub height: usize,
205    pub version: i32,
206    #[serde(default, with = "crate::serde_hex::opt")]
207    pub version_hex: Option<Vec<u8>>,
208    pub merkleroot: bitcoin::hash_types::TxMerkleNode,
209    pub tx: Vec<bitcoin::Txid>,
210    pub time: usize,
211    pub mediantime: Option<usize>,
212    pub nonce: u32,
213    pub bits: String,
214    pub difficulty: f64,
215    #[serde(with = "crate::serde_hex")]
216    pub chainwork: Vec<u8>,
217    pub n_tx: usize,
218    pub previousblockhash: Option<bitcoin::BlockHash>,
219    pub nextblockhash: Option<bitcoin::BlockHash>,
220}
221
222#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
223#[serde(rename_all = "camelCase")]
224pub struct GetBlockHeaderResult {
225    pub hash: bitcoin::BlockHash,
226    pub confirmations: i32,
227    pub height: usize,
228    pub version: Version,
229    #[serde(default, with = "crate::serde_hex::opt")]
230    pub version_hex: Option<Vec<u8>>,
231    #[serde(rename = "merkleroot")]
232    pub merkle_root: bitcoin::hash_types::TxMerkleNode,
233    pub time: usize,
234    #[serde(rename = "mediantime")]
235    pub median_time: Option<usize>,
236    pub nonce: u32,
237    pub bits: String,
238    pub difficulty: f64,
239    #[serde(with = "crate::serde_hex")]
240    pub chainwork: Vec<u8>,
241    pub n_tx: usize,
242    #[serde(rename = "previousblockhash")]
243    pub previous_block_hash: Option<bitcoin::BlockHash>,
244    #[serde(rename = "nextblockhash")]
245    pub next_block_hash: Option<bitcoin::BlockHash>,
246}
247
248#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
249pub struct GetBlockStatsResult {
250    #[serde(rename = "avgfee", with = "bitcoin::amount::serde::as_sat")]
251    pub avg_fee: Amount,
252    #[serde(rename = "avgfeerate", with = "bitcoin::amount::serde::as_sat")]
253    pub avg_fee_rate: Amount,
254    #[serde(rename = "avgtxsize")]
255    pub avg_tx_size: u32,
256    #[serde(rename = "blockhash")]
257    pub block_hash: bitcoin::BlockHash,
258    #[serde(rename = "feerate_percentiles")]
259    pub fee_rate_percentiles: FeeRatePercentiles,
260    pub height: u64,
261    pub ins: usize,
262    #[serde(rename = "maxfee", with = "bitcoin::amount::serde::as_sat")]
263    pub max_fee: Amount,
264    #[serde(rename = "maxfeerate", with = "bitcoin::amount::serde::as_sat")]
265    pub max_fee_rate: Amount,
266    #[serde(rename = "maxtxsize")]
267    pub max_tx_size: u32,
268    #[serde(rename = "medianfee", with = "bitcoin::amount::serde::as_sat")]
269    pub median_fee: Amount,
270    #[serde(rename = "mediantime")]
271    pub median_time: u64,
272    #[serde(rename = "mediantxsize")]
273    pub median_tx_size: u32,
274    #[serde(rename = "minfee", with = "bitcoin::amount::serde::as_sat")]
275    pub min_fee: Amount,
276    #[serde(rename = "minfeerate", with = "bitcoin::amount::serde::as_sat")]
277    pub min_fee_rate: Amount,
278    #[serde(rename = "mintxsize")]
279    pub min_tx_size: u32,
280    pub outs: usize,
281    #[serde(with = "bitcoin::amount::serde::as_sat")]
282    pub subsidy: Amount,
283    #[serde(rename = "swtotal_size")]
284    pub sw_total_size: usize,
285    #[serde(rename = "swtotal_weight")]
286    pub sw_total_weight: usize,
287    #[serde(rename = "swtxs")]
288    pub sw_txs: usize,
289    pub time: u64,
290    #[serde(with = "bitcoin::amount::serde::as_sat")]
291    pub total_out: Amount,
292    pub total_size: usize,
293    pub total_weight: usize,
294    #[serde(rename = "totalfee", with = "bitcoin::amount::serde::as_sat")]
295    pub total_fee: Amount,
296    pub txs: usize,
297    pub utxo_increase: i32,
298    pub utxo_size_inc: i32,
299}
300
301#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
302pub struct GetBlockStatsResultPartial {
303    #[serde(
304        default,
305        rename = "avgfee",
306        with = "bitcoin::amount::serde::as_sat::opt",
307        skip_serializing_if = "Option::is_none"
308    )]
309    pub avg_fee: Option<Amount>,
310    #[serde(
311        default,
312        rename = "avgfeerate",
313        with = "bitcoin::amount::serde::as_sat::opt",
314        skip_serializing_if = "Option::is_none"
315    )]
316    pub avg_fee_rate: Option<Amount>,
317    #[serde(default, rename = "avgtxsize", skip_serializing_if = "Option::is_none")]
318    pub avg_tx_size: Option<u32>,
319    #[serde(default, rename = "blockhash", skip_serializing_if = "Option::is_none")]
320    pub block_hash: Option<bitcoin::BlockHash>,
321    #[serde(default, rename = "feerate_percentiles", skip_serializing_if = "Option::is_none")]
322    pub fee_rate_percentiles: Option<FeeRatePercentiles>,
323    #[serde(default, skip_serializing_if = "Option::is_none")]
324    pub height: Option<u64>,
325    #[serde(default, skip_serializing_if = "Option::is_none")]
326    pub ins: Option<usize>,
327    #[serde(
328        default,
329        rename = "maxfee",
330        with = "bitcoin::amount::serde::as_sat::opt",
331        skip_serializing_if = "Option::is_none"
332    )]
333    pub max_fee: Option<Amount>,
334    #[serde(
335        default,
336        rename = "maxfeerate",
337        with = "bitcoin::amount::serde::as_sat::opt",
338        skip_serializing_if = "Option::is_none"
339    )]
340    pub max_fee_rate: Option<Amount>,
341    #[serde(default, rename = "maxtxsize", skip_serializing_if = "Option::is_none")]
342    pub max_tx_size: Option<u32>,
343    #[serde(
344        default,
345        rename = "medianfee",
346        with = "bitcoin::amount::serde::as_sat::opt",
347        skip_serializing_if = "Option::is_none"
348    )]
349    pub median_fee: Option<Amount>,
350    #[serde(default, rename = "mediantime", skip_serializing_if = "Option::is_none")]
351    pub median_time: Option<u64>,
352    #[serde(default, rename = "mediantxsize", skip_serializing_if = "Option::is_none")]
353    pub median_tx_size: Option<u32>,
354    #[serde(
355        default,
356        rename = "minfee",
357        with = "bitcoin::amount::serde::as_sat::opt",
358        skip_serializing_if = "Option::is_none"
359    )]
360    pub min_fee: Option<Amount>,
361    #[serde(
362        default,
363        rename = "minfeerate",
364        with = "bitcoin::amount::serde::as_sat::opt",
365        skip_serializing_if = "Option::is_none"
366    )]
367    pub min_fee_rate: Option<Amount>,
368    #[serde(default, rename = "mintxsize", skip_serializing_if = "Option::is_none")]
369    pub min_tx_size: Option<u32>,
370    #[serde(default, skip_serializing_if = "Option::is_none")]
371    pub outs: Option<usize>,
372    #[serde(
373        default,
374        with = "bitcoin::amount::serde::as_sat::opt",
375        skip_serializing_if = "Option::is_none"
376    )]
377    pub subsidy: Option<Amount>,
378    #[serde(default, rename = "swtotal_size", skip_serializing_if = "Option::is_none")]
379    pub sw_total_size: Option<usize>,
380    #[serde(default, rename = "swtotal_weight", skip_serializing_if = "Option::is_none")]
381    pub sw_total_weight: Option<usize>,
382    #[serde(default, rename = "swtxs", skip_serializing_if = "Option::is_none")]
383    pub sw_txs: Option<usize>,
384    #[serde(default, skip_serializing_if = "Option::is_none")]
385    pub time: Option<u64>,
386    #[serde(
387        default,
388        with = "bitcoin::amount::serde::as_sat::opt",
389        skip_serializing_if = "Option::is_none"
390    )]
391    pub total_out: Option<Amount>,
392    #[serde(default, skip_serializing_if = "Option::is_none")]
393    pub total_size: Option<usize>,
394    #[serde(default, skip_serializing_if = "Option::is_none")]
395    pub total_weight: Option<usize>,
396    #[serde(
397        default,
398        rename = "totalfee",
399        with = "bitcoin::amount::serde::as_sat::opt",
400        skip_serializing_if = "Option::is_none"
401    )]
402    pub total_fee: Option<Amount>,
403    #[serde(default, skip_serializing_if = "Option::is_none")]
404    pub txs: Option<usize>,
405    #[serde(default, skip_serializing_if = "Option::is_none")]
406    pub utxo_increase: Option<i32>,
407    #[serde(default, skip_serializing_if = "Option::is_none")]
408    pub utxo_size_inc: Option<i32>,
409}
410
411#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
412pub struct FeeRatePercentiles {
413    #[serde(with = "bitcoin::amount::serde::as_sat")]
414    pub fr_10th: Amount,
415    #[serde(with = "bitcoin::amount::serde::as_sat")]
416    pub fr_25th: Amount,
417    #[serde(with = "bitcoin::amount::serde::as_sat")]
418    pub fr_50th: Amount,
419    #[serde(with = "bitcoin::amount::serde::as_sat")]
420    pub fr_75th: Amount,
421    #[serde(with = "bitcoin::amount::serde::as_sat")]
422    pub fr_90th: Amount,
423}
424
425#[derive(Clone)]
426pub enum BlockStatsFields {
427    AverageFee,
428    AverageFeeRate,
429    AverageTxSize,
430    BlockHash,
431    FeeRatePercentiles,
432    Height,
433    Ins,
434    MaxFee,
435    MaxFeeRate,
436    MaxTxSize,
437    MedianFee,
438    MedianTime,
439    MedianTxSize,
440    MinFee,
441    MinFeeRate,
442    MinTxSize,
443    Outs,
444    Subsidy,
445    SegWitTotalSize,
446    SegWitTotalWeight,
447    SegWitTxs,
448    Time,
449    TotalOut,
450    TotalSize,
451    TotalWeight,
452    TotalFee,
453    Txs,
454    UtxoIncrease,
455    UtxoSizeIncrease,
456}
457
458impl BlockStatsFields {
459    fn get_rpc_keyword(&self) -> &str {
460        match *self {
461            BlockStatsFields::AverageFee => "avgfee",
462            BlockStatsFields::AverageFeeRate => "avgfeerate",
463            BlockStatsFields::AverageTxSize => "avgtxsize",
464            BlockStatsFields::BlockHash => "blockhash",
465            BlockStatsFields::FeeRatePercentiles => "feerate_percentiles",
466            BlockStatsFields::Height => "height",
467            BlockStatsFields::Ins => "ins",
468            BlockStatsFields::MaxFee => "maxfee",
469            BlockStatsFields::MaxFeeRate => "maxfeerate",
470            BlockStatsFields::MaxTxSize => "maxtxsize",
471            BlockStatsFields::MedianFee => "medianfee",
472            BlockStatsFields::MedianTime => "mediantime",
473            BlockStatsFields::MedianTxSize => "mediantxsize",
474            BlockStatsFields::MinFee => "minfee",
475            BlockStatsFields::MinFeeRate => "minfeerate",
476            BlockStatsFields::MinTxSize => "minfeerate",
477            BlockStatsFields::Outs => "outs",
478            BlockStatsFields::Subsidy => "subsidy",
479            BlockStatsFields::SegWitTotalSize => "swtotal_size",
480            BlockStatsFields::SegWitTotalWeight => "swtotal_weight",
481            BlockStatsFields::SegWitTxs => "swtxs",
482            BlockStatsFields::Time => "time",
483            BlockStatsFields::TotalOut => "total_out",
484            BlockStatsFields::TotalSize => "total_size",
485            BlockStatsFields::TotalWeight => "total_weight",
486            BlockStatsFields::TotalFee => "totalfee",
487            BlockStatsFields::Txs => "txs",
488            BlockStatsFields::UtxoIncrease => "utxo_increase",
489            BlockStatsFields::UtxoSizeIncrease => "utxo_size_inc",
490        }
491    }
492}
493
494impl fmt::Display for BlockStatsFields {
495    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
496        write!(f, "{}", self.get_rpc_keyword())
497    }
498}
499
500impl From<BlockStatsFields> for serde_json::Value {
501    fn from(bsf: BlockStatsFields) -> Self {
502        Self::from(bsf.to_string())
503    }
504}
505
506#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
507#[serde(rename_all = "camelCase")]
508pub struct GetMiningInfoResult {
509    pub blocks: u32,
510    #[serde(rename = "currentblockweight")]
511    pub current_block_weight: Option<u64>,
512    #[serde(rename = "currentblocktx")]
513    pub current_block_tx: Option<usize>,
514    pub difficulty: f64,
515    #[serde(rename = "networkhashps")]
516    pub network_hash_ps: f64,
517    #[serde(rename = "pooledtx")]
518    pub pooled_tx: usize,
519    #[serde(deserialize_with = "deserialize_bip70_network")]
520    pub chain: Network,
521    pub warnings: String,
522}
523
524#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
525#[serde(rename_all = "camelCase")]
526pub struct GetRawTransactionResultVinScriptSig {
527    pub asm: String,
528    #[serde(with = "crate::serde_hex")]
529    pub hex: Vec<u8>,
530}
531
532impl GetRawTransactionResultVinScriptSig {
533    pub fn script(&self) -> Result<ScriptBuf, encode::Error> {
534        Ok(ScriptBuf::from(self.hex.clone()))
535    }
536}
537
538#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
539#[serde(rename_all = "camelCase")]
540pub struct GetRawTransactionResultVin {
541    pub sequence: u32,
542    /// The raw scriptSig in case of a coinbase tx.
543    #[serde(default, with = "crate::serde_hex::opt")]
544    pub coinbase: Option<Vec<u8>>,
545    /// Not provided for coinbase txs.
546    pub txid: Option<bitcoin::Txid>,
547    /// Not provided for coinbase txs.
548    pub vout: Option<u32>,
549    /// The scriptSig in case of a non-coinbase tx.
550    pub script_sig: Option<GetRawTransactionResultVinScriptSig>,
551    /// Not provided for coinbase txs.
552    #[serde(default, deserialize_with = "deserialize_hex_array_opt")]
553    pub txinwitness: Option<Vec<Vec<u8>>>,
554}
555
556impl GetRawTransactionResultVin {
557    /// Whether this input is from a coinbase tx.
558    /// The [txid], [vout] and [script_sig] fields are not provided
559    /// for coinbase transactions.
560    pub fn is_coinbase(&self) -> bool {
561        self.coinbase.is_some()
562    }
563}
564
565#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
566#[serde(rename_all = "camelCase")]
567pub struct GetRawTransactionResultVoutScriptPubKey {
568    pub asm: String,
569    #[serde(with = "crate::serde_hex")]
570    pub hex: Vec<u8>,
571    pub req_sigs: Option<usize>,
572    #[serde(rename = "type")]
573    pub type_: Option<ScriptPubkeyType>,
574    // Deprecated in Bitcoin Core 22
575    #[serde(default)]
576    pub addresses: Vec<Address<NetworkUnchecked>>,
577    // Added in Bitcoin Core 22
578    #[serde(default)]
579    pub address: Option<Address<NetworkUnchecked>>,
580}
581
582impl GetRawTransactionResultVoutScriptPubKey {
583    pub fn script(&self) -> Result<ScriptBuf, encode::Error> {
584        Ok(ScriptBuf::from(self.hex.clone()))
585    }
586}
587
588#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
589#[serde(rename_all = "camelCase")]
590pub struct GetRawTransactionResultVout {
591    #[serde(with = "bitcoin::amount::serde::as_btc")]
592    pub value: Amount,
593    pub n: u32,
594    pub script_pub_key: GetRawTransactionResultVoutScriptPubKey,
595}
596
597#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
598#[serde(rename_all = "camelCase")]
599pub struct GetRawTransactionResult {
600    #[serde(rename = "in_active_chain")]
601    pub in_active_chain: Option<bool>,
602    #[serde(with = "crate::serde_hex")]
603    pub hex: Vec<u8>,
604    pub txid: bitcoin::Txid,
605    pub hash: bitcoin::Wtxid,
606    pub size: usize,
607    pub vsize: usize,
608    pub version: u32,
609    pub locktime: u32,
610    pub vin: Vec<GetRawTransactionResultVin>,
611    pub vout: Vec<GetRawTransactionResultVout>,
612    pub blockhash: Option<bitcoin::BlockHash>,
613    pub confirmations: Option<u32>,
614    pub time: Option<usize>,
615    pub blocktime: Option<usize>,
616}
617
618#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
619pub struct GetBlockFilterResult {
620    pub header: bitcoin::hash_types::FilterHash,
621    #[serde(with = "crate::serde_hex")]
622    pub filter: Vec<u8>,
623}
624
625impl GetBlockFilterResult {
626    /// Get the filter.
627    /// Note that this copies the underlying filter data. To prevent this,
628    /// use [into_filter] instead.
629    pub fn to_filter(&self) -> bip158::BlockFilter {
630        bip158::BlockFilter::new(&self.filter)
631    }
632
633    /// Convert the result in the filter type.
634    pub fn into_filter(self) -> bip158::BlockFilter {
635        bip158::BlockFilter {
636            content: self.filter,
637        }
638    }
639}
640
641impl GetRawTransactionResult {
642    /// Whether this tx is a coinbase tx.
643    pub fn is_coinbase(&self) -> bool {
644        self.vin.len() == 1 && self.vin[0].is_coinbase()
645    }
646
647    pub fn transaction(&self) -> Result<Transaction, encode::Error> {
648        Ok(encode::deserialize(&self.hex)?)
649    }
650}
651
652/// Enum to represent the BIP125 replaceable status for a transaction.
653#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
654#[serde(rename_all = "lowercase")]
655pub enum Bip125Replaceable {
656    Yes,
657    No,
658    Unknown,
659}
660
661/// Enum to represent the category of a transaction.
662#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
663#[serde(rename_all = "lowercase")]
664pub enum GetTransactionResultDetailCategory {
665    Send,
666    Receive,
667    Generate,
668    Immature,
669    Orphan,
670}
671
672#[derive(Clone, PartialEq, Eq, Debug, Deserialize)]
673pub struct GetTransactionResultDetail {
674    pub address: Option<Address<NetworkUnchecked>>,
675    pub category: GetTransactionResultDetailCategory,
676    #[serde(with = "bitcoin::amount::serde::as_btc")]
677    pub amount: SignedAmount,
678    pub label: Option<String>,
679    pub vout: u32,
680    #[serde(default, with = "bitcoin::amount::serde::as_btc::opt")]
681    pub fee: Option<SignedAmount>,
682    pub abandoned: Option<bool>,
683}
684
685#[derive(Clone, PartialEq, Eq, Debug, Deserialize)]
686pub struct WalletTxInfo {
687    pub confirmations: i32,
688    pub blockhash: Option<bitcoin::BlockHash>,
689    pub blockindex: Option<usize>,
690    pub blocktime: Option<u64>,
691    pub blockheight: Option<u32>,
692    pub txid: bitcoin::Txid,
693    pub time: u64,
694    pub timereceived: u64,
695    #[serde(rename = "bip125-replaceable")]
696    pub bip125_replaceable: Bip125Replaceable,
697    /// Conflicting transaction ids
698    #[serde(rename = "walletconflicts")]
699    pub wallet_conflicts: Vec<bitcoin::Txid>,
700}
701
702#[derive(Clone, PartialEq, Eq, Debug, Deserialize)]
703pub struct GetTransactionResult {
704    #[serde(flatten)]
705    pub info: WalletTxInfo,
706    #[serde(with = "bitcoin::amount::serde::as_btc")]
707    pub amount: SignedAmount,
708    #[serde(default, with = "bitcoin::amount::serde::as_btc::opt")]
709    pub fee: Option<SignedAmount>,
710    pub details: Vec<GetTransactionResultDetail>,
711    #[serde(with = "crate::serde_hex")]
712    pub hex: Vec<u8>,
713}
714
715impl GetTransactionResult {
716    pub fn transaction(&self) -> Result<Transaction, encode::Error> {
717        Ok(encode::deserialize(&self.hex)?)
718    }
719}
720
721#[derive(Clone, PartialEq, Eq, Debug, Deserialize)]
722pub struct ListTransactionResult {
723    #[serde(flatten)]
724    pub info: WalletTxInfo,
725    #[serde(flatten)]
726    pub detail: GetTransactionResultDetail,
727
728    pub trusted: Option<bool>,
729    pub comment: Option<String>,
730}
731
732#[derive(Clone, PartialEq, Eq, Debug, Deserialize)]
733pub struct ListSinceBlockResult {
734    pub transactions: Vec<ListTransactionResult>,
735    #[serde(default)]
736    pub removed: Vec<ListTransactionResult>,
737    pub lastblock: bitcoin::BlockHash,
738}
739
740#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
741#[serde(rename_all = "camelCase")]
742pub struct GetTxOutResult {
743    pub bestblock: bitcoin::BlockHash,
744    pub confirmations: u32,
745    #[serde(with = "bitcoin::amount::serde::as_btc")]
746    pub value: Amount,
747    pub script_pub_key: GetRawTransactionResultVoutScriptPubKey,
748    pub coinbase: bool,
749}
750
751#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize, Default)]
752#[serde(rename_all = "camelCase")]
753pub struct ListUnspentQueryOptions {
754    #[serde(
755        rename = "minimumAmount",
756        with = "bitcoin::amount::serde::as_btc::opt",
757        skip_serializing_if = "Option::is_none"
758    )]
759    pub minimum_amount: Option<Amount>,
760    #[serde(
761        rename = "maximumAmount",
762        with = "bitcoin::amount::serde::as_btc::opt",
763        skip_serializing_if = "Option::is_none"
764    )]
765    pub maximum_amount: Option<Amount>,
766    #[serde(rename = "maximumCount", skip_serializing_if = "Option::is_none")]
767    pub maximum_count: Option<usize>,
768    #[serde(
769        rename = "minimumSumAmount",
770        with = "bitcoin::amount::serde::as_btc::opt",
771        skip_serializing_if = "Option::is_none"
772    )]
773    pub minimum_sum_amount: Option<Amount>,
774}
775
776#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
777#[serde(rename_all = "camelCase")]
778pub struct ListUnspentResultEntry {
779    pub txid: bitcoin::Txid,
780    pub vout: u32,
781    pub address: Option<Address<NetworkUnchecked>>,
782    pub label: Option<String>,
783    pub redeem_script: Option<ScriptBuf>,
784    pub witness_script: Option<ScriptBuf>,
785    pub script_pub_key: ScriptBuf,
786    #[serde(with = "bitcoin::amount::serde::as_btc")]
787    pub amount: Amount,
788    pub confirmations: u32,
789    pub spendable: bool,
790    pub solvable: bool,
791    #[serde(rename = "desc")]
792    pub descriptor: Option<String>,
793    pub safe: bool,
794}
795
796#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
797#[serde(rename_all = "camelCase")]
798pub struct ListReceivedByAddressResult {
799    #[serde(default, rename = "involvesWatchonly")]
800    pub involved_watch_only: bool,
801    pub address: Address<NetworkUnchecked>,
802    #[serde(with = "bitcoin::amount::serde::as_btc")]
803    pub amount: Amount,
804    pub confirmations: u32,
805    pub label: String,
806    pub txids: Vec<bitcoin::Txid>,
807}
808
809#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
810#[serde(rename_all = "camelCase")]
811pub struct SignRawTransactionResultError {
812    pub txid: bitcoin::Txid,
813    pub vout: u32,
814    pub script_sig: ScriptBuf,
815    pub sequence: u32,
816    pub error: String,
817}
818
819#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
820#[serde(rename_all = "camelCase")]
821pub struct SignRawTransactionResult {
822    #[serde(with = "crate::serde_hex")]
823    pub hex: Vec<u8>,
824    pub complete: bool,
825    pub errors: Option<Vec<SignRawTransactionResultError>>,
826}
827
828impl SignRawTransactionResult {
829    pub fn transaction(&self) -> Result<Transaction, encode::Error> {
830        Ok(encode::deserialize(&self.hex)?)
831    }
832}
833
834#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
835pub struct TestMempoolAcceptResult {
836    pub txid: bitcoin::Txid,
837    pub allowed: bool,
838    #[serde(rename = "reject-reason")]
839    pub reject_reason: Option<String>,
840    /// Virtual transaction size as defined in BIP 141 (only present when 'allowed' is true)
841    /// Added in Bitcoin Core v0.21
842    pub vsize: Option<u64>,
843    /// Transaction fees (only present if 'allowed' is true)
844    /// Added in Bitcoin Core v0.21
845    pub fees: Option<TestMempoolAcceptResultFees>,
846}
847
848#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
849pub struct TestMempoolAcceptResultFees {
850    /// Transaction fee in BTC
851    #[serde(with = "bitcoin::amount::serde::as_btc")]
852    pub base: Amount,
853    // unlike GetMempoolEntryResultFees, this only has the `base` fee
854}
855
856#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
857#[serde(rename_all = "snake_case")]
858pub enum Bip9SoftforkStatus {
859    Defined,
860    Started,
861    LockedIn,
862    Active,
863    Failed,
864}
865
866#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
867pub struct Bip9SoftforkStatistics {
868    pub period: u32,
869    pub threshold: Option<u32>,
870    pub elapsed: u32,
871    pub count: u32,
872    pub possible: Option<bool>,
873}
874
875#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
876pub struct Bip9SoftforkInfo {
877    pub status: Bip9SoftforkStatus,
878    pub bit: Option<u8>,
879    // Can be -1 for 0.18.x inactive ones.
880    pub start_time: i64,
881    pub timeout: u64,
882    pub since: u32,
883    pub statistics: Option<Bip9SoftforkStatistics>,
884}
885
886#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
887#[serde(rename_all = "lowercase")]
888pub enum SoftforkType {
889    Buried,
890    Bip9,
891    #[serde(other)]
892    Other,
893}
894
895/// Status of a softfork
896#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
897pub struct Softfork {
898    #[serde(rename = "type")]
899    pub type_: SoftforkType,
900    pub bip9: Option<Bip9SoftforkInfo>,
901    pub height: Option<u32>,
902    pub active: bool,
903}
904
905#[allow(non_camel_case_types)]
906#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
907#[serde(rename_all = "lowercase")]
908pub enum ScriptPubkeyType {
909    Nonstandard,
910    Pubkey,
911    PubkeyHash,
912    ScriptHash,
913    MultiSig,
914    NullData,
915    Witness_v0_KeyHash,
916    Witness_v0_ScriptHash,
917    Witness_v1_Taproot,
918    Witness_Unknown,
919}
920
921#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
922pub struct GetAddressInfoResultEmbedded {
923    pub address: Address<NetworkUnchecked>,
924    #[serde(rename = "scriptPubKey")]
925    pub script_pub_key: ScriptBuf,
926    #[serde(rename = "is_script")]
927    pub is_script: Option<bool>,
928    #[serde(rename = "is_witness")]
929    pub is_witness: Option<bool>,
930    pub witness_version: Option<u32>,
931    #[serde(with = "crate::serde_hex")]
932    pub witness_program: Vec<u8>,
933    pub script: Option<ScriptPubkeyType>,
934    /// The redeemscript for the p2sh address.
935    #[serde(default, with = "crate::serde_hex::opt")]
936    pub hex: Option<Vec<u8>>,
937    pub pubkeys: Option<Vec<PublicKey>>,
938    #[serde(rename = "sigsrequired")]
939    pub n_signatures_required: Option<usize>,
940    pub pubkey: Option<PublicKey>,
941    #[serde(rename = "is_compressed")]
942    pub is_compressed: Option<bool>,
943    pub label: Option<String>,
944    #[serde(rename = "hdkeypath")]
945    pub hd_key_path: Option<bip32::DerivationPath>,
946    #[serde(rename = "hdseedid")]
947    pub hd_seed_id: Option<bitcoin::hash_types::XpubIdentifier>,
948    #[serde(default)]
949    pub labels: Vec<GetAddressInfoResultLabel>,
950}
951
952#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
953#[serde(rename_all = "lowercase")]
954pub enum GetAddressInfoResultLabelPurpose {
955    Send,
956    Receive,
957}
958
959#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
960#[serde(untagged)]
961pub enum GetAddressInfoResultLabel {
962    Simple(String),
963    WithPurpose {
964        name: String,
965        purpose: GetAddressInfoResultLabelPurpose,
966    },
967}
968
969#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
970pub struct GetAddressInfoResult {
971    pub address: Address<NetworkUnchecked>,
972    #[serde(rename = "scriptPubKey")]
973    pub script_pub_key: ScriptBuf,
974    #[serde(rename = "ismine")]
975    pub is_mine: Option<bool>,
976    #[serde(rename = "iswatchonly")]
977    pub is_watchonly: Option<bool>,
978    #[serde(rename = "isscript")]
979    pub is_script: Option<bool>,
980    #[serde(rename = "iswitness")]
981    pub is_witness: Option<bool>,
982    pub witness_version: Option<u32>,
983    #[serde(default, with = "crate::serde_hex::opt")]
984    pub witness_program: Option<Vec<u8>>,
985    pub script: Option<ScriptPubkeyType>,
986    /// The redeemscript for the p2sh address.
987    #[serde(default, with = "crate::serde_hex::opt")]
988    pub hex: Option<Vec<u8>>,
989    pub pubkeys: Option<Vec<PublicKey>>,
990    #[serde(rename = "sigsrequired")]
991    pub n_signatures_required: Option<usize>,
992    pub pubkey: Option<PublicKey>,
993    /// Information about the address embedded in P2SH or P2WSH, if relevant and known.
994    pub embedded: Option<GetAddressInfoResultEmbedded>,
995    #[serde(rename = "is_compressed")]
996    pub is_compressed: Option<bool>,
997    pub timestamp: Option<u64>,
998    #[serde(rename = "hdkeypath")]
999    pub hd_key_path: Option<bip32::DerivationPath>,
1000    #[serde(rename = "hdseedid")]
1001    pub hd_seed_id: Option<bitcoin::hash_types::XpubIdentifier>,
1002    pub labels: Vec<GetAddressInfoResultLabel>,
1003    /// Deprecated in v0.20.0. See `labels` field instead.
1004    #[deprecated(note = "since Core v0.20.0")]
1005    pub label: Option<String>,
1006}
1007
1008/// Models the result of "getblockchaininfo"
1009#[derive(Clone, Debug, Deserialize, Serialize)]
1010pub struct GetBlockchainInfoResult {
1011    /// Current network name as defined in BIP70 (main, test, signet, regtest)
1012    #[serde(deserialize_with = "deserialize_bip70_network")]
1013    pub chain: Network,
1014    /// The current number of blocks processed in the server
1015    pub blocks: u64,
1016    /// The current number of headers we have validated
1017    pub headers: u64,
1018    /// The hash of the currently best block
1019    #[serde(rename = "bestblockhash")]
1020    pub best_block_hash: bitcoin::BlockHash,
1021    /// The current difficulty
1022    pub difficulty: f64,
1023    /// Median time for the current best block
1024    #[serde(rename = "mediantime")]
1025    pub median_time: u64,
1026    /// Estimate of verification progress [0..1]
1027    #[serde(rename = "verificationprogress")]
1028    pub verification_progress: f64,
1029    /// Estimate of whether this node is in Initial Block Download mode
1030    #[serde(rename = "initialblockdownload")]
1031    pub initial_block_download: bool,
1032    /// Total amount of work in active chain, in hexadecimal
1033    #[serde(rename = "chainwork", with = "crate::serde_hex")]
1034    pub chain_work: Vec<u8>,
1035    /// The estimated size of the block and undo files on disk
1036    pub size_on_disk: u64,
1037    /// If the blocks are subject to pruning
1038    pub pruned: bool,
1039    /// Lowest-height complete block stored (only present if pruning is enabled)
1040    #[serde(rename = "pruneheight")]
1041    pub prune_height: Option<u64>,
1042    /// Whether automatic pruning is enabled (only present if pruning is enabled)
1043    pub automatic_pruning: Option<bool>,
1044    /// The target size used by pruning (only present if automatic pruning is enabled)
1045    pub prune_target_size: Option<u64>,
1046    /// Status of softforks in progress
1047    #[serde(default)]
1048    pub softforks: HashMap<String, Softfork>,
1049    /// Any network and blockchain warnings.
1050    pub warnings: String,
1051}
1052
1053#[derive(Clone, PartialEq, Eq, Debug)]
1054pub enum ImportMultiRequestScriptPubkey<'a> {
1055    Address(&'a Address),
1056    Script(&'a Script),
1057}
1058
1059#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1060pub struct GetMempoolInfoResult {
1061    /// True if the mempool is fully loaded
1062    pub loaded: Option<bool>,
1063    /// Current tx count
1064    pub size: usize,
1065    /// Sum of all virtual transaction sizes as defined in BIP 141. Differs from actual serialized size because witness data is discounted
1066    pub bytes: usize,
1067    /// Total memory usage for the mempool
1068    pub usage: usize,
1069    /// Total fees for the mempool in BTC, ignoring modified fees through prioritisetransaction
1070    #[serde(default, with = "bitcoin::amount::serde::as_btc::opt")]
1071    pub total_fee: Option<Amount>,
1072    /// Maximum memory usage for the mempool
1073    #[serde(rename = "maxmempool")]
1074    pub max_mempool: usize,
1075    /// Minimum fee rate in BTC/kvB for tx to be accepted. Is the maximum of minrelaytxfee and minimum mempool fee
1076    #[serde(rename = "mempoolminfee", with = "bitcoin::amount::serde::as_btc")]
1077    pub mempool_min_fee: Amount,
1078    /// Current minimum relay fee for transactions
1079    #[serde(rename = "minrelaytxfee", with = "bitcoin::amount::serde::as_btc")]
1080    pub min_relay_tx_fee: Amount,
1081    /// Minimum fee rate increment for mempool limiting or replacement in BTC/kvB
1082    #[serde(rename = "incrementalrelayfee", default, with = "bitcoin::amount::serde::as_btc::opt")]
1083    pub incremental_relay_fee: Option<Amount>,
1084    /// Current number of transactions that haven't passed initial broadcast yet
1085    #[serde(rename = "unbroadcastcount")]
1086    pub unbroadcast_count: Option<usize>,
1087    /// True if the mempool accepts RBF without replaceability signaling inspection
1088    #[serde(rename = "fullrbf")]
1089    pub full_rbf: Option<bool>,
1090}
1091
1092#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1093pub struct GetMempoolEntryResult {
1094    /// Virtual transaction size as defined in BIP 141. This is different from actual serialized
1095    /// size for witness transactions as witness data is discounted.
1096    #[serde(alias = "size")]
1097    pub vsize: u64,
1098    /// Transaction weight as defined in BIP 141. Added in Core v0.19.0.
1099    pub weight: Option<u64>,
1100    /// Local time transaction entered pool in seconds since 1 Jan 1970 GMT
1101    pub time: u64,
1102    /// Block height when transaction entered pool
1103    pub height: u64,
1104    /// Number of in-mempool descendant transactions (including this one)
1105    #[serde(rename = "descendantcount")]
1106    pub descendant_count: u64,
1107    /// Virtual transaction size of in-mempool descendants (including this one)
1108    #[serde(rename = "descendantsize")]
1109    pub descendant_size: u64,
1110    /// Number of in-mempool ancestor transactions (including this one)
1111    #[serde(rename = "ancestorcount")]
1112    pub ancestor_count: u64,
1113    /// Virtual transaction size of in-mempool ancestors (including this one)
1114    #[serde(rename = "ancestorsize")]
1115    pub ancestor_size: u64,
1116    /// Hash of serialized transaction, including witness data
1117    pub wtxid: bitcoin::Txid,
1118    /// Fee information
1119    pub fees: GetMempoolEntryResultFees,
1120    /// Unconfirmed transactions used as inputs for this transaction
1121    pub depends: Vec<bitcoin::Txid>,
1122    /// Unconfirmed transactions spending outputs from this transaction
1123    #[serde(rename = "spentby")]
1124    pub spent_by: Vec<bitcoin::Txid>,
1125    /// Whether this transaction could be replaced due to BIP125 (replace-by-fee)
1126    #[serde(rename = "bip125-replaceable")]
1127    pub bip125_replaceable: bool,
1128    /// Whether this transaction is currently unbroadcast (initial broadcast not yet acknowledged by any peers)
1129    /// Added in Bitcoin Core v0.21
1130    pub unbroadcast: Option<bool>,
1131}
1132
1133#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1134pub struct GetMempoolEntryResultFees {
1135    /// Transaction fee in BTC
1136    #[serde(with = "bitcoin::amount::serde::as_btc")]
1137    pub base: Amount,
1138    /// Transaction fee with fee deltas used for mining priority in BTC
1139    #[serde(with = "bitcoin::amount::serde::as_btc")]
1140    pub modified: Amount,
1141    /// Modified fees (see above) of in-mempool ancestors (including this one) in BTC
1142    #[serde(with = "bitcoin::amount::serde::as_btc")]
1143    pub ancestor: Amount,
1144    /// Modified fees (see above) of in-mempool descendants (including this one) in BTC
1145    #[serde(with = "bitcoin::amount::serde::as_btc")]
1146    pub descendant: Amount,
1147}
1148
1149impl<'a> serde::Serialize for ImportMultiRequestScriptPubkey<'a> {
1150    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1151    where
1152        S: serde::Serializer,
1153    {
1154        match *self {
1155            ImportMultiRequestScriptPubkey::Address(ref addr) => {
1156                #[derive(Serialize)]
1157                struct Tmp<'a> {
1158                    pub address: &'a Address,
1159                }
1160                serde::Serialize::serialize(
1161                    &Tmp {
1162                        address: addr,
1163                    },
1164                    serializer,
1165                )
1166            }
1167            ImportMultiRequestScriptPubkey::Script(script) => {
1168                serializer.serialize_str(&script.to_hex_string())
1169            }
1170        }
1171    }
1172}
1173
1174/// A import request for importmulti.
1175///
1176/// Note: unlike in bitcoind, `timestamp` defaults to 0.
1177#[derive(Clone, PartialEq, Eq, Debug, Default, Serialize)]
1178pub struct ImportMultiRequest<'a> {
1179    pub timestamp: Timestamp,
1180    /// If using descriptor, do not also provide address/scriptPubKey, scripts, or pubkeys.
1181    #[serde(rename = "desc", skip_serializing_if = "Option::is_none")]
1182    pub descriptor: Option<&'a str>,
1183    #[serde(rename = "scriptPubKey", skip_serializing_if = "Option::is_none")]
1184    pub script_pubkey: Option<ImportMultiRequestScriptPubkey<'a>>,
1185    #[serde(rename = "redeemscript", skip_serializing_if = "Option::is_none")]
1186    pub redeem_script: Option<&'a Script>,
1187    #[serde(rename = "witnessscript", skip_serializing_if = "Option::is_none")]
1188    pub witness_script: Option<&'a Script>,
1189    #[serde(skip_serializing_if = "<[_]>::is_empty")]
1190    pub pubkeys: &'a [PublicKey],
1191    #[serde(skip_serializing_if = "<[_]>::is_empty")]
1192    pub keys: &'a [PrivateKey],
1193    #[serde(skip_serializing_if = "Option::is_none")]
1194    pub range: Option<(usize, usize)>,
1195    #[serde(skip_serializing_if = "Option::is_none")]
1196    pub internal: Option<bool>,
1197    #[serde(skip_serializing_if = "Option::is_none")]
1198    pub watchonly: Option<bool>,
1199    #[serde(skip_serializing_if = "Option::is_none")]
1200    pub label: Option<&'a str>,
1201    #[serde(skip_serializing_if = "Option::is_none")]
1202    pub keypool: Option<bool>,
1203}
1204
1205#[derive(Clone, PartialEq, Eq, Debug, Default, Deserialize, Serialize)]
1206pub struct ImportMultiOptions {
1207    #[serde(skip_serializing_if = "Option::is_none")]
1208    pub rescan: Option<bool>,
1209}
1210
1211#[derive(Clone, PartialEq, Eq, Copy, Debug)]
1212pub enum Timestamp {
1213    Now,
1214    Time(u64),
1215}
1216
1217impl serde::Serialize for Timestamp {
1218    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1219    where
1220        S: serde::Serializer,
1221    {
1222        match *self {
1223            Timestamp::Now => serializer.serialize_str("now"),
1224            Timestamp::Time(timestamp) => serializer.serialize_u64(timestamp),
1225        }
1226    }
1227}
1228
1229impl<'de> serde::Deserialize<'de> for Timestamp {
1230    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1231    where
1232        D: serde::Deserializer<'de>,
1233    {
1234        use serde::de;
1235        struct Visitor;
1236        impl<'de> de::Visitor<'de> for Visitor {
1237            type Value = Timestamp;
1238
1239            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
1240                write!(formatter, "unix timestamp or 'now'")
1241            }
1242
1243            fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
1244            where
1245                E: de::Error,
1246            {
1247                Ok(Timestamp::Time(value))
1248            }
1249
1250            fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
1251            where
1252                E: de::Error,
1253            {
1254                if value == "now" {
1255                    Ok(Timestamp::Now)
1256                } else {
1257                    Err(de::Error::custom(format!(
1258                        "invalid str '{}', expecting 'now' or unix timestamp",
1259                        value
1260                    )))
1261                }
1262            }
1263        }
1264        deserializer.deserialize_any(Visitor)
1265    }
1266}
1267
1268impl Default for Timestamp {
1269    fn default() -> Self {
1270        Timestamp::Time(0)
1271    }
1272}
1273
1274impl From<u64> for Timestamp {
1275    fn from(t: u64) -> Self {
1276        Timestamp::Time(t)
1277    }
1278}
1279
1280impl From<Option<u64>> for Timestamp {
1281    fn from(timestamp: Option<u64>) -> Self {
1282        timestamp.map_or(Timestamp::Now, Timestamp::Time)
1283    }
1284}
1285
1286#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1287pub struct ImportMultiResultError {
1288    pub code: i64,
1289    pub message: String,
1290}
1291
1292#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1293pub struct ImportMultiResult {
1294    pub success: bool,
1295    #[serde(default)]
1296    pub warnings: Vec<String>,
1297    pub error: Option<ImportMultiResultError>,
1298}
1299
1300/// A import request for importdescriptors.
1301#[derive(Clone, PartialEq, Eq, Debug, Default, Deserialize, Serialize)]
1302pub struct ImportDescriptors {
1303    #[serde(rename = "desc")]
1304    pub descriptor: String,
1305    pub timestamp: Timestamp,
1306    #[serde(skip_serializing_if = "Option::is_none")]
1307    pub active: Option<bool>,
1308    #[serde(skip_serializing_if = "Option::is_none")]
1309    pub range: Option<(usize, usize)>,
1310    #[serde(skip_serializing_if = "Option::is_none")]
1311    pub next_index: Option<usize>,
1312    #[serde(skip_serializing_if = "Option::is_none")]
1313    pub internal: Option<bool>,
1314    #[serde(skip_serializing_if = "Option::is_none")]
1315    pub label: Option<String>,
1316}
1317
1318/// Progress toward rejecting pre-softfork blocks
1319#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1320pub struct RejectStatus {
1321    /// `true` if threshold reached
1322    pub status: bool,
1323}
1324
1325/// Models the result of "getpeerinfo"
1326#[derive(Clone, Debug, Deserialize, Serialize)]
1327pub struct GetPeerInfoResult {
1328    /// Peer index
1329    pub id: u64,
1330    /// The IP address and port of the peer
1331    // TODO: use a type for addr
1332    pub addr: String,
1333    /// Bind address of the connection to the peer
1334    // TODO: use a type for addrbind
1335    pub addrbind: String,
1336    /// Local address as reported by the peer
1337    // TODO: use a type for addrlocal
1338    pub addrlocal: Option<String>,
1339    /// Network (ipv4, ipv6, or onion) the peer connected through
1340    /// Added in Bitcoin Core v0.21
1341    pub network: Option<GetPeerInfoResultNetwork>,
1342    /// The services offered
1343    // TODO: use a type for services
1344    pub services: String,
1345    /// Whether peer has asked us to relay transactions to it
1346    pub relaytxes: bool,
1347    /// The time in seconds since epoch (Jan 1 1970 GMT) of the last send
1348    pub lastsend: u64,
1349    /// The time in seconds since epoch (Jan 1 1970 GMT) of the last receive
1350    pub lastrecv: u64,
1351    /// The time in seconds since epoch (Jan 1 1970 GMT) of the last valid transaction received from this peer
1352    /// Added in Bitcoin Core v0.21
1353    pub last_transaction: Option<u64>,
1354    /// The time in seconds since epoch (Jan 1 1970 GMT) of the last block received from this peer
1355    /// Added in Bitcoin Core v0.21
1356    pub last_block: Option<u64>,
1357    /// The total bytes sent
1358    pub bytessent: u64,
1359    /// The total bytes received
1360    pub bytesrecv: u64,
1361    /// The connection time in seconds since epoch (Jan 1 1970 GMT)
1362    pub conntime: u64,
1363    /// The time offset in seconds
1364    pub timeoffset: i64,
1365    /// ping time (if available)
1366    pub pingtime: Option<f64>,
1367    /// minimum observed ping time (if any at all)
1368    pub minping: Option<f64>,
1369    /// ping wait (if non-zero)
1370    pub pingwait: Option<f64>,
1371    /// The peer version, such as 70001
1372    pub version: u64,
1373    /// The string version
1374    pub subver: String,
1375    /// Inbound (true) or Outbound (false)
1376    pub inbound: bool,
1377    /// Whether connection was due to `addnode`/`-connect` or if it was an
1378    /// automatic/inbound connection
1379    /// Deprecated in Bitcoin Core v0.21
1380    pub addnode: Option<bool>,
1381    /// The starting height (block) of the peer
1382    pub startingheight: i64,
1383    /// The ban score
1384    /// Deprecated in Bitcoin Core v0.21
1385    pub banscore: Option<i64>,
1386    /// The last header we have in common with this peer
1387    pub synced_headers: i64,
1388    /// The last block we have in common with this peer
1389    pub synced_blocks: i64,
1390    /// The heights of blocks we're currently asking from this peer
1391    pub inflight: Vec<u64>,
1392    /// Whether the peer is whitelisted
1393    /// Deprecated in Bitcoin Core v0.21
1394    pub whitelisted: Option<bool>,
1395    #[serde(rename = "minfeefilter", default, with = "bitcoin::amount::serde::as_btc::opt")]
1396    pub min_fee_filter: Option<Amount>,
1397    /// The total bytes sent aggregated by message type
1398    pub bytessent_per_msg: HashMap<String, u64>,
1399    /// The total bytes received aggregated by message type
1400    pub bytesrecv_per_msg: HashMap<String, u64>,
1401    /// The type of the connection
1402    /// Added in Bitcoin Core v0.21
1403    pub connection_type: Option<GetPeerInfoResultConnectionType>,
1404}
1405
1406#[derive(Copy, Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
1407#[serde(rename_all = "snake_case")]
1408pub enum GetPeerInfoResultNetwork {
1409    Ipv4,
1410    Ipv6,
1411    Onion,
1412    #[deprecated]
1413    Unroutable,
1414    NotPubliclyRoutable,
1415    I2p,
1416    Cjdns,
1417    Internal,
1418}
1419
1420#[derive(Copy, Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
1421#[serde(rename_all = "kebab-case")]
1422pub enum GetPeerInfoResultConnectionType {
1423    OutboundFullRelay,
1424    BlockRelayOnly,
1425    Inbound,
1426    Manual,
1427    AddrFetch,
1428    Feeler,
1429}
1430
1431#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1432pub struct GetAddedNodeInfoResult {
1433    /// The node IP address or name (as provided to addnode)
1434    #[serde(rename = "addednode")]
1435    pub added_node: String,
1436    ///  If connected
1437    pub connected: bool,
1438    /// Only when connected = true
1439    pub addresses: Vec<GetAddedNodeInfoResultAddress>,
1440}
1441
1442#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1443pub struct GetAddedNodeInfoResultAddress {
1444    /// The bitcoin server IP and port we're connected to
1445    pub address: String,
1446    /// connection, inbound or outbound
1447    pub connected: GetAddedNodeInfoResultAddressType,
1448}
1449
1450#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1451#[serde(rename_all = "lowercase")]
1452pub enum GetAddedNodeInfoResultAddressType {
1453    Inbound,
1454    Outbound,
1455}
1456
1457#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1458pub struct GetNodeAddressesResult {
1459    /// Timestamp in seconds since epoch (Jan 1 1970 GMT) keeping track of when the node was last seen
1460    pub time: u64,
1461    /// The services offered
1462    pub services: usize,
1463    /// The address of the node
1464    pub address: String,
1465    /// The port of the node
1466    pub port: u16,
1467}
1468
1469#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1470pub struct ListBannedResult {
1471    pub address: String,
1472    pub banned_until: u64,
1473    pub ban_created: u64,
1474}
1475
1476/// Models the result of "estimatesmartfee"
1477#[derive(Clone, Debug, Deserialize, Serialize)]
1478pub struct EstimateSmartFeeResult {
1479    /// Estimate fee rate in BTC/kB.
1480    #[serde(
1481        default,
1482        rename = "feerate",
1483        skip_serializing_if = "Option::is_none",
1484        with = "bitcoin::amount::serde::as_btc::opt"
1485    )]
1486    pub fee_rate: Option<Amount>,
1487    /// Errors encountered during processing.
1488    pub errors: Option<Vec<String>>,
1489    /// Block number where estimate was found.
1490    pub blocks: i64,
1491}
1492
1493/// Models the result of "waitfornewblock", and "waitforblock"
1494#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1495pub struct BlockRef {
1496    pub hash: bitcoin::BlockHash,
1497    pub height: u64,
1498}
1499
1500/// Models the result of "getdescriptorinfo"
1501#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1502pub struct GetDescriptorInfoResult {
1503    pub descriptor: String,
1504    pub checksum: Option<String>,
1505    #[serde(rename = "isrange")]
1506    pub is_range: bool,
1507    #[serde(rename = "issolvable")]
1508    pub is_solvable: bool,
1509    #[serde(rename = "hasprivatekeys")]
1510    pub has_private_keys: bool,
1511}
1512
1513/// Models the request options of "getblocktemplate"
1514#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1515pub struct GetBlockTemplateOptions {
1516    pub mode: GetBlockTemplateModes,
1517    //// List of client side supported softfork deployment
1518    pub rules: Vec<GetBlockTemplateRules>,
1519    /// List of client side supported features
1520    pub capabilities: Vec<GetBlockTemplateCapabilities>,
1521}
1522
1523/// Enum to represent client-side supported features
1524#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1525#[serde(rename_all = "lowercase")]
1526pub enum GetBlockTemplateCapabilities {
1527    // No features supported yet. In the future this could be, for example, Proposal and Longpolling
1528}
1529
1530/// Enum to representing specific block rules that the requested template
1531/// should support.
1532#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1533#[serde(rename_all = "lowercase")]
1534pub enum GetBlockTemplateRules {
1535    SegWit,
1536    Signet,
1537    Csv,
1538    Taproot,
1539}
1540
1541/// Enum to represent client-side supported features.
1542#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1543#[serde(rename_all = "lowercase")]
1544pub enum GetBlockTemplateModes {
1545    /// Using this mode, the server build a block template and return it as
1546    /// response to the request. This is the default mode.
1547    Template,
1548    // TODO: Support for "proposal" mode is not yet implemented on the client
1549    // side.
1550}
1551
1552/// Models the result of "getblocktemplate"
1553#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1554pub struct GetBlockTemplateResult {
1555    /// The compressed difficulty in hexadecimal
1556    #[serde(with = "crate::serde_hex")]
1557    pub bits: Vec<u8>,
1558    /// The previous block hash the current template is mining on
1559    #[serde(rename = "previousblockhash")]
1560    pub previous_block_hash: bitcoin::BlockHash,
1561    /// The current time as seen by the server (recommended for block time)
1562    /// Note: this is not necessarily the system clock, and must fall within
1563    /// the mintime/maxtime rules. Expressed as UNIX timestamp.
1564    #[serde(rename = "curtime")]
1565    pub current_time: u64,
1566    /// The height of the block we will be mining: `current height + 1`
1567    pub height: u64,
1568    /// Block sigops limit
1569    #[serde(rename = "sigoplimit")]
1570    pub sigop_limit: u32,
1571    /// Block size limit
1572    #[serde(rename = "sizelimit")]
1573    pub size_limit: u32,
1574    /// Block weight limit
1575    #[serde(rename = "weightlimit")]
1576    pub weight_limit: u32,
1577    /// Block header version
1578    pub version: u32,
1579    /// Block rules that are to be enforced
1580    pub rules: Vec<GetBlockTemplateResultRules>,
1581    /// List of features the Bitcoin Core getblocktemplate implementation supports
1582    pub capabilities: Vec<GetBlockTemplateResultCapabilities>,
1583    /// Set of pending, supported versionbit (BIP 9) softfork deployments
1584    #[serde(rename = "vbavailable")]
1585    pub version_bits_available: HashMap<String, u32>,
1586    /// Bit mask of versionbits the server requires set in submissions
1587    #[serde(rename = "vbrequired")]
1588    pub version_bits_required: u32,
1589    /// Id used in longpoll requests for this template.
1590    pub longpollid: String,
1591    /// List of transactions included in the template block
1592    pub transactions: Vec<GetBlockTemplateResultTransaction>,
1593    /// The signet challenge. Only set if mining on a signet, otherwise empty
1594    #[serde(default, with = "bitcoin::script::ScriptBuf")]
1595    pub signet_challenge: bitcoin::script::ScriptBuf,
1596    /// The default witness commitment included in an OP_RETURN output of the
1597    /// coinbase transactions. Only set when mining on a network where SegWit
1598    /// is activated.
1599    #[serde(with = "bitcoin::script::ScriptBuf", default)]
1600    pub default_witness_commitment: bitcoin::script::ScriptBuf,
1601    /// Data that should be included in the coinbase's scriptSig content. Only
1602    /// the values (hexadecimal byte-for-byte) in this map should be included,
1603    /// not the keys. This does not include the block height, which is required
1604    /// to be included in the scriptSig by BIP 0034. It is advisable to encode
1605    /// values inside "PUSH" opcodes, so as to not inadvertently expend SIGOPs
1606    /// (which are counted toward limits, despite not being executed).
1607    pub coinbaseaux: HashMap<String, String>,
1608    /// Total funds available for the coinbase
1609    #[serde(rename = "coinbasevalue", with = "bitcoin::amount::serde::as_sat", default)]
1610    pub coinbase_value: Amount,
1611    /// The number which valid hashes must be less than, in big-endian
1612    #[serde(with = "crate::serde_hex")]
1613    pub target: Vec<u8>,
1614    /// The minimum timestamp appropriate for the next block time. Expressed as
1615    /// UNIX timestamp.
1616    #[serde(rename = "mintime")]
1617    pub min_time: u64,
1618    /// List of things that may be changed by the client before submitting a
1619    /// block
1620    pub mutable: Vec<GetBlockTemplateResulMutations>,
1621    /// A range of valid nonces
1622    #[serde(with = "crate::serde_hex", rename = "noncerange")]
1623    pub nonce_range: Vec<u8>,
1624}
1625
1626/// Models a single transaction entry in the result of "getblocktemplate"
1627#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1628pub struct GetBlockTemplateResultTransaction {
1629    /// The transaction id
1630    pub txid: bitcoin::Txid,
1631    /// The wtxid of the transaction
1632    #[serde(rename = "hash")]
1633    pub wtxid: bitcoin::Wtxid,
1634    /// The serilaized transaction bytes
1635    #[serde(with = "crate::serde_hex", rename = "data")]
1636    pub raw_tx: Vec<u8>,
1637    // The transaction fee
1638    #[serde(with = "bitcoin::amount::serde::as_sat")]
1639    pub fee: Amount,
1640    /// Transaction sigops
1641    pub sigops: u32,
1642    /// Transaction weight in weight units
1643    pub weight: usize,
1644    /// Transactions that must be in present in the final block if this one is.
1645    /// Indexed by a 1-based index in the `GetBlockTemplateResult.transactions`
1646    /// list
1647    pub depends: Vec<u32>,
1648}
1649
1650impl GetBlockTemplateResultTransaction {
1651    pub fn transaction(&self) -> Result<Transaction, encode::Error> {
1652        encode::deserialize(&self.raw_tx)
1653    }
1654}
1655
1656/// Enum to represent Bitcoin Core's supported features for getblocktemplate
1657#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1658#[serde(rename_all = "lowercase")]
1659pub enum GetBlockTemplateResultCapabilities {
1660    Proposal,
1661}
1662
1663/// Enum to representing specific block rules that client must support to work
1664/// with the template returned by Bitcoin Core
1665#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1666#[serde(rename_all = "lowercase")]
1667pub enum GetBlockTemplateResultRules {
1668    /// Inidcates that the client must support the SegWit rules when using this
1669    /// template.
1670    #[serde(alias = "!segwit")]
1671    SegWit,
1672    /// Indicates that the client must support the Signet rules when using this
1673    /// template.
1674    #[serde(alias = "!signet")]
1675    Signet,
1676    /// Indicates that the client must support the CSV rules when using this
1677    /// template.
1678    Csv,
1679    /// Indicates that the client must support the taproot rules when using this
1680    /// template.
1681    Taproot,
1682    /// Indicates that the client must support the Regtest rules when using this
1683    /// template. TestDummy is a test soft-fork only used on the regtest network.
1684    Testdummy,
1685}
1686
1687/// Enum to representing mutable parts of the block template. This does only
1688/// cover the muations implemented in Bitcoin Core. More mutations are defined
1689/// in [BIP-23](https://github.com/bitcoin/bips/blob/master/bip-0023.mediawiki#Mutations),
1690/// but not implemented in the getblocktemplate implementation of Bitcoin Core.
1691#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1692#[serde(rename_all = "lowercase")]
1693pub enum GetBlockTemplateResulMutations {
1694    /// The client is allowed to modify the time in the header of the block
1695    Time,
1696    /// The client is allowed to add transactions to the block
1697    Transactions,
1698    /// The client is allowed to use the work with other previous blocks.
1699    /// This implicitly allows removing transactions that are no longer valid.
1700    /// It also implies adjusting the "height" as necessary.
1701    #[serde(rename = "prevblock")]
1702    PreviousBlock,
1703}
1704
1705/// Models the result of "walletcreatefundedpsbt"
1706#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1707pub struct WalletCreateFundedPsbtResult {
1708    pub psbt: String,
1709    #[serde(with = "bitcoin::amount::serde::as_btc")]
1710    pub fee: Amount,
1711    #[serde(rename = "changepos")]
1712    pub change_position: i32,
1713}
1714
1715/// Models the result of "walletprocesspsbt"
1716#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1717pub struct WalletProcessPsbtResult {
1718    pub psbt: String,
1719    pub complete: bool,
1720}
1721
1722/// Models the request for "walletcreatefundedpsbt"
1723#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize, Default)]
1724pub struct WalletCreateFundedPsbtOptions {
1725    /// For a transaction with existing inputs, automatically include more if they are not enough (default true).
1726    /// Added in Bitcoin Core v0.21
1727    #[serde(skip_serializing_if = "Option::is_none")]
1728    pub add_inputs: Option<bool>,
1729    #[serde(rename = "changeAddress", skip_serializing_if = "Option::is_none")]
1730    pub change_address: Option<Address<NetworkUnchecked>>,
1731    #[serde(rename = "changePosition", skip_serializing_if = "Option::is_none")]
1732    pub change_position: Option<u16>,
1733    #[serde(skip_serializing_if = "Option::is_none")]
1734    pub change_type: Option<AddressType>,
1735    #[serde(rename = "includeWatching", skip_serializing_if = "Option::is_none")]
1736    pub include_watching: Option<bool>,
1737    #[serde(rename = "lockUnspents", skip_serializing_if = "Option::is_none")]
1738    pub lock_unspent: Option<bool>,
1739    #[serde(
1740        rename = "feeRate",
1741        skip_serializing_if = "Option::is_none",
1742        with = "bitcoin::amount::serde::as_btc::opt"
1743    )]
1744    pub fee_rate: Option<Amount>,
1745    #[serde(rename = "subtractFeeFromOutputs", skip_serializing_if = "Vec::is_empty")]
1746    pub subtract_fee_from_outputs: Vec<u16>,
1747    #[serde(skip_serializing_if = "Option::is_none")]
1748    pub replaceable: Option<bool>,
1749    #[serde(skip_serializing_if = "Option::is_none")]
1750    pub conf_target: Option<u16>,
1751    #[serde(skip_serializing_if = "Option::is_none")]
1752    pub estimate_mode: Option<EstimateMode>,
1753}
1754
1755/// Models the result of "finalizepsbt"
1756#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1757pub struct FinalizePsbtResult {
1758    pub psbt: Option<String>,
1759    #[serde(default, with = "crate::serde_hex::opt")]
1760    pub hex: Option<Vec<u8>>,
1761    pub complete: bool,
1762}
1763
1764/// Model for decode transaction
1765#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1766pub struct DecodeRawTransactionResult {
1767    pub txid: bitcoin::Txid,
1768    pub hash: bitcoin::Wtxid,
1769    pub size: u32,
1770    pub vsize: u32,
1771    pub weight: u32,
1772    pub version: u32,
1773    pub locktime: u32,
1774    pub vin: Vec<GetRawTransactionResultVin>,
1775    pub vout: Vec<GetRawTransactionResultVout>,
1776}
1777
1778/// Models the result of "getchaintips"
1779pub type GetChainTipsResult = Vec<GetChainTipsResultTip>;
1780
1781/// Models a single chain tip for the result of "getchaintips"
1782#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1783pub struct GetChainTipsResultTip {
1784    /// Block height of the chain tip
1785    pub height: u64,
1786    /// Header hash of the chain tip
1787    pub hash: bitcoin::BlockHash,
1788    /// Length of the branch (number of blocks since the last common block)
1789    #[serde(rename = "branchlen")]
1790    pub branch_length: usize,
1791    /// Status of the tip as seen by Bitcoin Core
1792    pub status: GetChainTipsResultStatus,
1793}
1794
1795#[derive(Copy, Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
1796#[serde(rename_all = "lowercase")]
1797pub enum GetChainTipsResultStatus {
1798    /// The branch contains at least one invalid block
1799    Invalid,
1800    /// Not all blocks for this branch are available, but the headers are valid
1801    #[serde(rename = "headers-only")]
1802    HeadersOnly,
1803    /// All blocks are available for this branch, but they were never fully validated
1804    #[serde(rename = "valid-headers")]
1805    ValidHeaders,
1806    /// This branch is not part of the active chain, but is fully validated
1807    #[serde(rename = "valid-fork")]
1808    ValidFork,
1809    /// This is the tip of the active main chain, which is certainly valid
1810    Active,
1811}
1812
1813impl FinalizePsbtResult {
1814    pub fn transaction(&self) -> Option<Result<Transaction, encode::Error>> {
1815        self.hex.as_ref().map(|h| encode::deserialize(h))
1816    }
1817}
1818
1819// Custom types for input arguments.
1820
1821#[derive(Serialize, Deserialize, Debug, Clone, Copy, Eq, PartialEq, Hash)]
1822#[serde(rename_all = "UPPERCASE")]
1823pub enum EstimateMode {
1824    Unset,
1825    Economical,
1826    Conservative,
1827}
1828
1829/// A wrapper around bitcoin::EcdsaSighashType that will be serialized
1830/// according to what the RPC expects.
1831pub struct SigHashType(bitcoin::sighash::EcdsaSighashType);
1832
1833impl From<bitcoin::sighash::EcdsaSighashType> for SigHashType {
1834    fn from(sht: bitcoin::sighash::EcdsaSighashType) -> SigHashType {
1835        SigHashType(sht)
1836    }
1837}
1838
1839impl serde::Serialize for SigHashType {
1840    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1841    where
1842        S: serde::Serializer,
1843    {
1844        serializer.serialize_str(match self.0 {
1845            bitcoin::sighash::EcdsaSighashType::All => "ALL",
1846            bitcoin::sighash::EcdsaSighashType::None => "NONE",
1847            bitcoin::sighash::EcdsaSighashType::Single => "SINGLE",
1848            bitcoin::sighash::EcdsaSighashType::AllPlusAnyoneCanPay => "ALL|ANYONECANPAY",
1849            bitcoin::sighash::EcdsaSighashType::NonePlusAnyoneCanPay => "NONE|ANYONECANPAY",
1850            bitcoin::sighash::EcdsaSighashType::SinglePlusAnyoneCanPay => "SINGLE|ANYONECANPAY",
1851        })
1852    }
1853}
1854
1855// Used for createrawtransaction argument.
1856#[derive(Serialize, Clone, PartialEq, Eq, Debug)]
1857#[serde(rename_all = "camelCase")]
1858pub struct CreateRawTransactionInput {
1859    pub txid: bitcoin::Txid,
1860    pub vout: u32,
1861    #[serde(skip_serializing_if = "Option::is_none")]
1862    pub sequence: Option<u32>,
1863}
1864
1865#[derive(Serialize, Clone, PartialEq, Eq, Debug, Default)]
1866#[serde(rename_all = "camelCase")]
1867pub struct FundRawTransactionOptions {
1868    /// For a transaction with existing inputs, automatically include more if they are not enough (default true).
1869    /// Added in Bitcoin Core v0.21
1870    #[serde(rename = "add_inputs", skip_serializing_if = "Option::is_none")]
1871    pub add_inputs: Option<bool>,
1872    #[serde(skip_serializing_if = "Option::is_none")]
1873    pub change_address: Option<Address>,
1874    #[serde(skip_serializing_if = "Option::is_none")]
1875    pub change_position: Option<u32>,
1876    #[serde(rename = "change_type", skip_serializing_if = "Option::is_none")]
1877    pub change_type: Option<AddressType>,
1878    #[serde(skip_serializing_if = "Option::is_none")]
1879    pub include_watching: Option<bool>,
1880    #[serde(skip_serializing_if = "Option::is_none")]
1881    pub lock_unspents: Option<bool>,
1882    #[serde(
1883        with = "bitcoin::amount::serde::as_btc::opt",
1884        skip_serializing_if = "Option::is_none"
1885    )]
1886    pub fee_rate: Option<Amount>,
1887    #[serde(skip_serializing_if = "Option::is_none")]
1888    pub subtract_fee_from_outputs: Option<Vec<u32>>,
1889    #[serde(skip_serializing_if = "Option::is_none")]
1890    pub replaceable: Option<bool>,
1891    #[serde(rename = "conf_target", skip_serializing_if = "Option::is_none")]
1892    pub conf_target: Option<u32>,
1893    #[serde(rename = "estimate_mode", skip_serializing_if = "Option::is_none")]
1894    pub estimate_mode: Option<EstimateMode>,
1895}
1896
1897#[derive(Deserialize, Clone, PartialEq, Eq, Debug)]
1898#[serde(rename_all = "camelCase")]
1899pub struct FundRawTransactionResult {
1900    #[serde(with = "crate::serde_hex")]
1901    pub hex: Vec<u8>,
1902    #[serde(with = "bitcoin::amount::serde::as_btc")]
1903    pub fee: Amount,
1904    #[serde(rename = "changepos")]
1905    pub change_position: i32,
1906}
1907
1908#[derive(Deserialize, Clone, PartialEq, Eq, Debug)]
1909pub struct GetBalancesResultEntry {
1910    #[serde(with = "bitcoin::amount::serde::as_btc")]
1911    pub trusted: Amount,
1912    #[serde(with = "bitcoin::amount::serde::as_btc")]
1913    pub untrusted_pending: Amount,
1914    #[serde(with = "bitcoin::amount::serde::as_btc")]
1915    pub immature: Amount,
1916}
1917
1918#[derive(Deserialize, Clone, PartialEq, Eq, Debug)]
1919#[serde(rename_all = "camelCase")]
1920pub struct GetBalancesResult {
1921    pub mine: GetBalancesResultEntry,
1922    pub watchonly: Option<GetBalancesResultEntry>,
1923}
1924
1925impl FundRawTransactionResult {
1926    pub fn transaction(&self) -> Result<Transaction, encode::Error> {
1927        encode::deserialize(&self.hex)
1928    }
1929}
1930
1931// Used for signrawtransaction argument.
1932#[derive(Serialize, Clone, PartialEq, Debug)]
1933#[serde(rename_all = "camelCase")]
1934pub struct SignRawTransactionInput {
1935    pub txid: bitcoin::Txid,
1936    pub vout: u32,
1937    pub script_pub_key: ScriptBuf,
1938    #[serde(skip_serializing_if = "Option::is_none")]
1939    pub redeem_script: Option<ScriptBuf>,
1940    #[serde(
1941        default,
1942        skip_serializing_if = "Option::is_none",
1943        with = "bitcoin::amount::serde::as_btc::opt"
1944    )]
1945    pub amount: Option<Amount>,
1946}
1947
1948/// Used to represent UTXO set hash type
1949#[derive(Clone, Serialize, PartialEq, Eq, Debug)]
1950#[serde(rename_all = "snake_case")]
1951pub enum TxOutSetHashType {
1952    HashSerialized2,
1953    Muhash,
1954    None,
1955}
1956
1957/// Used to specify a block hash or a height
1958#[derive(Clone, Serialize, PartialEq, Eq, Debug)]
1959#[serde(untagged)]
1960pub enum HashOrHeight {
1961    BlockHash(bitcoin::BlockHash),
1962    Height(u64),
1963}
1964
1965#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1966pub struct GetTxOutSetInfoResult {
1967    /// The block height (index) of the returned statistics
1968    pub height: u64,
1969    /// The hash of the block at which these statistics are calculated
1970    #[serde(rename = "bestblock")]
1971    pub best_block: bitcoin::BlockHash,
1972    /// The number of transactions with unspent outputs (not available when coinstatsindex is used)
1973    #[serde(default, skip_serializing_if = "Option::is_none")]
1974    pub transactions: Option<u64>,
1975    /// The number of unspent transaction outputs
1976    #[serde(rename = "txouts")]
1977    pub tx_outs: u64,
1978    /// A meaningless metric for UTXO set size
1979    pub bogosize: u64,
1980    /// The serialized hash (only present if 'hash_serialized_2' hash_type is chosen)
1981    #[serde(default, skip_serializing_if = "Option::is_none")]
1982    pub hash_serialized_2: Option<sha256::Hash>,
1983    /// The serialized hash (only present if 'muhash' hash_type is chosen)
1984    #[serde(default, skip_serializing_if = "Option::is_none")]
1985    pub muhash: Option<sha256::Hash>,
1986    /// The estimated size of the chainstate on disk (not available when coinstatsindex is used)
1987    #[serde(default, skip_serializing_if = "Option::is_none")]
1988    pub disk_size: Option<u64>,
1989    /// The total amount
1990    #[serde(with = "bitcoin::amount::serde::as_btc")]
1991    pub total_amount: Amount,
1992    /// The total amount of coins permanently excluded from the UTXO set (only available if coinstatsindex is used)
1993    #[serde(
1994        default,
1995        skip_serializing_if = "Option::is_none",
1996        with = "bitcoin::amount::serde::as_btc::opt"
1997    )]
1998    pub total_unspendable_amount: Option<Amount>,
1999    /// Info on amounts in the block at this block height (only available if coinstatsindex is used)
2000    #[serde(default, skip_serializing_if = "Option::is_none")]
2001    pub block_info: Option<BlockInfo>,
2002}
2003
2004/// Info on amounts in the block at the block height of the `gettxoutsetinfo` call (only available if coinstatsindex is used)
2005#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
2006pub struct BlockInfo {
2007    /// Amount of previous outputs spent
2008    #[serde(with = "bitcoin::amount::serde::as_btc")]
2009    pub prevout_spent: Amount,
2010    /// Output size of the coinbase transaction
2011    #[serde(with = "bitcoin::amount::serde::as_btc")]
2012    pub coinbase: Amount,
2013    /// Newly-created outputs
2014    #[serde(with = "bitcoin::amount::serde::as_btc")]
2015    pub new_outputs_ex_coinbase: Amount,
2016    /// Amount of unspendable outputs
2017    #[serde(with = "bitcoin::amount::serde::as_btc")]
2018    pub unspendable: Amount,
2019    /// Detailed view of the unspendable categories
2020    pub unspendables: Unspendables,
2021}
2022
2023/// Detailed view of the unspendable categories
2024#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
2025pub struct Unspendables {
2026    /// Unspendable coins from the Genesis block
2027    #[serde(with = "bitcoin::amount::serde::as_btc")]
2028    pub genesis_block: Amount,
2029    /// Transactions overridden by duplicates (no longer possible with BIP30)
2030    #[serde(with = "bitcoin::amount::serde::as_btc")]
2031    pub bip30: Amount,
2032    /// Amounts sent to scripts that are unspendable (for example OP_RETURN outputs)
2033    #[serde(with = "bitcoin::amount::serde::as_btc")]
2034    pub scripts: Amount,
2035    /// Fee rewards that miners did not claim in their coinbase transaction
2036    #[serde(with = "bitcoin::amount::serde::as_btc")]
2037    pub unclaimed_rewards: Amount,
2038}
2039
2040#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
2041pub struct GetNetTotalsResult {
2042    /// Total bytes received
2043    #[serde(rename = "totalbytesrecv")]
2044    pub total_bytes_recv: u64,
2045    /// Total bytes sent
2046    #[serde(rename = "totalbytessent")]
2047    pub total_bytes_sent: u64,
2048    /// Current UNIX time in milliseconds
2049    #[serde(rename = "timemillis")]
2050    pub time_millis: u64,
2051    /// Upload target statistics
2052    #[serde(rename = "uploadtarget")]
2053    pub upload_target: GetNetTotalsResultUploadTarget,
2054}
2055
2056#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
2057pub struct GetNetTotalsResultUploadTarget {
2058    /// Length of the measuring timeframe in seconds
2059    #[serde(rename = "timeframe")]
2060    pub time_frame: u64,
2061    /// Target in bytes
2062    pub target: u64,
2063    /// True if target is reached
2064    pub target_reached: bool,
2065    /// True if serving historical blocks
2066    pub serve_historical_blocks: bool,
2067    /// Bytes left in current time cycle
2068    pub bytes_left_in_cycle: u64,
2069    /// Seconds left in current time cycle
2070    pub time_left_in_cycle: u64,
2071}
2072
2073/// Used to represent an address type.
2074#[derive(Copy, Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
2075#[serde(rename_all = "kebab-case")]
2076pub enum AddressType {
2077    Legacy,
2078    P2shSegwit,
2079    Bech32,
2080    Bech32m,
2081}
2082
2083/// Used to represent arguments that can either be an address or a public key.
2084#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
2085pub enum PubKeyOrAddress<'a> {
2086    Address(&'a Address),
2087    PubKey(&'a PublicKey),
2088}
2089
2090#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
2091#[serde(untagged)]
2092/// Start a scan of the UTXO set for an [output descriptor](https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md).
2093pub enum ScanTxOutRequest {
2094    /// Scan for a single descriptor
2095    Single(String),
2096    /// Scan for a descriptor with xpubs
2097    Extended {
2098        /// Descriptor
2099        desc: String,
2100        /// Range of the xpub derivations to scan
2101        range: (u64, u64),
2102    },
2103}
2104
2105#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
2106pub struct ScanTxOutResult {
2107    pub success: Option<bool>,
2108    #[serde(rename = "txouts")]
2109    pub tx_outs: Option<u64>,
2110    pub height: Option<u64>,
2111    #[serde(rename = "bestblock")]
2112    pub best_block_hash: Option<bitcoin::BlockHash>,
2113    pub unspents: Vec<Utxo>,
2114    #[serde(with = "bitcoin::amount::serde::as_btc")]
2115    pub total_amount: bitcoin::Amount,
2116}
2117
2118#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
2119#[serde(rename_all = "camelCase")]
2120pub struct Utxo {
2121    pub txid: bitcoin::Txid,
2122    pub vout: u32,
2123    pub script_pub_key: bitcoin::ScriptBuf,
2124    #[serde(rename = "desc")]
2125    pub descriptor: String,
2126    #[serde(with = "bitcoin::amount::serde::as_btc")]
2127    pub amount: bitcoin::Amount,
2128    pub height: u64,
2129}
2130
2131#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
2132pub struct IndexStatus {
2133    pub synced: bool,
2134    pub best_block_height: u32,
2135}
2136
2137#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
2138pub struct GetIndexInfoResult {
2139    pub txindex: Option<IndexStatus>,
2140    pub coinstatsindex: Option<IndexStatus>,
2141    #[serde(rename = "basic block filter index")]
2142    pub basic_block_filter_index: Option<IndexStatus>,
2143}
2144
2145impl<'a> serde::Serialize for PubKeyOrAddress<'a> {
2146    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
2147    where
2148        S: serde::Serializer,
2149    {
2150        match *self {
2151            PubKeyOrAddress::Address(a) => serde::Serialize::serialize(a, serializer),
2152            PubKeyOrAddress::PubKey(k) => serde::Serialize::serialize(k, serializer),
2153        }
2154    }
2155}
2156
2157// Custom deserializer functions.
2158
2159/// deserialize_hex_array_opt deserializes a vector of hex-encoded byte arrays.
2160fn deserialize_hex_array_opt<'de, D>(deserializer: D) -> Result<Option<Vec<Vec<u8>>>, D::Error>
2161where
2162    D: serde::Deserializer<'de>,
2163{
2164    //TODO(stevenroose) Revisit when issue is fixed:
2165    // https://github.com/serde-rs/serde/issues/723
2166
2167    let v: Vec<String> = Vec::deserialize(deserializer)?;
2168    let mut res = Vec::new();
2169    for h in v.into_iter() {
2170        res.push(FromHex::from_hex(&h).map_err(D::Error::custom)?);
2171    }
2172    Ok(Some(res))
2173}
2174
2175/// deserialize_bip70_network deserializes a Bitcoin Core network according to BIP70
2176/// The accepted input variants are: {"main", "test", "signet", "regtest"}
2177fn deserialize_bip70_network<'de, D>(deserializer: D) -> Result<Network, D::Error> 
2178where
2179    D: serde::Deserializer<'de>,
2180{
2181    struct NetworkVisitor;
2182    impl<'de> serde::de::Visitor<'de> for NetworkVisitor {
2183        type Value = Network;
2184
2185        fn visit_str<E: serde::de::Error>(self, s: &str) -> Result<Self::Value, E> {
2186            Network::from_core_arg(s)
2187                .map_err(|_| E::invalid_value(serde::de::Unexpected::Str(s), &"bitcoin network encoded as a string"))
2188        }
2189
2190        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
2191            write!(formatter, "bitcoin network encoded as a string")
2192        }
2193    }
2194
2195    deserializer.deserialize_str(NetworkVisitor)
2196}
2197
2198#[cfg(test)]
2199mod tests {
2200    use super::*;
2201
2202    #[test]
2203    fn test_softfork_type() {
2204        let buried: SoftforkType = serde_json::from_str("\"buried\"").unwrap();
2205        assert_eq!(buried, SoftforkType::Buried);
2206        let bip9: SoftforkType = serde_json::from_str("\"bip9\"").unwrap();
2207        assert_eq!(bip9, SoftforkType::Bip9);
2208        let other: SoftforkType = serde_json::from_str("\"bip8\"").unwrap();
2209        assert_eq!(other, SoftforkType::Other);
2210    }
2211}