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