bitcoin_json/
lib.rs

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