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    #[serde(serialize_with = "serialize_bip70_network")]
1021    pub chain: Network,
1022    /// The current number of blocks processed in the server
1023    pub blocks: u64,
1024    /// The current number of headers we have validated
1025    pub headers: u64,
1026    /// The hash of the currently best block
1027    #[serde(rename = "bestblockhash")]
1028    pub best_block_hash: bitcoin::BlockHash,
1029    /// The current difficulty
1030    pub difficulty: f64,
1031    /// Median time for the current best block
1032    #[serde(rename = "mediantime")]
1033    pub median_time: u64,
1034    /// Estimate of verification progress [0..1]
1035    #[serde(rename = "verificationprogress")]
1036    pub verification_progress: f64,
1037    /// Estimate of whether this node is in Initial Block Download mode
1038    #[serde(rename = "initialblockdownload")]
1039    pub initial_block_download: bool,
1040    /// Total amount of work in active chain, in hexadecimal
1041    #[serde(rename = "chainwork", with = "crate::serde_hex")]
1042    pub chain_work: Vec<u8>,
1043    /// The estimated size of the block and undo files on disk
1044    pub size_on_disk: u64,
1045    /// If the blocks are subject to pruning
1046    pub pruned: bool,
1047    /// Lowest-height complete block stored (only present if pruning is enabled)
1048    #[serde(rename = "pruneheight")]
1049    pub prune_height: Option<u64>,
1050    /// Whether automatic pruning is enabled (only present if pruning is enabled)
1051    pub automatic_pruning: Option<bool>,
1052    /// The target size used by pruning (only present if automatic pruning is enabled)
1053    pub prune_target_size: Option<u64>,
1054    /// Status of softforks in progress
1055    #[serde(default)]
1056    pub softforks: HashMap<String, Softfork>,
1057    /// Any network and blockchain warnings. In later versions of bitcoind, it's an array of strings.
1058    pub warnings: StringOrStringArray,
1059}
1060
1061#[derive(Clone, PartialEq, Eq, Debug)]
1062pub enum ImportMultiRequestScriptPubkey<'a> {
1063    Address(&'a Address),
1064    Script(&'a Script),
1065}
1066
1067#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1068pub struct GetMempoolInfoResult {
1069    /// True if the mempool is fully loaded
1070    pub loaded: Option<bool>,
1071    /// Current tx count
1072    pub size: usize,
1073    /// Sum of all virtual transaction sizes as defined in BIP 141. Differs from actual serialized size because witness data is discounted
1074    pub bytes: usize,
1075    /// Total memory usage for the mempool
1076    pub usage: usize,
1077    /// Total fees for the mempool in BTC, ignoring modified fees through prioritisetransaction
1078    #[serde(default, with = "bitcoin::amount::serde::as_btc::opt")]
1079    pub total_fee: Option<Amount>,
1080    /// Maximum memory usage for the mempool
1081    #[serde(rename = "maxmempool")]
1082    pub max_mempool: usize,
1083    /// Minimum fee rate in BTC/kvB for tx to be accepted. Is the maximum of minrelaytxfee and minimum mempool fee
1084    #[serde(rename = "mempoolminfee", with = "bitcoin::amount::serde::as_btc")]
1085    pub mempool_min_fee: Amount,
1086    /// Current minimum relay fee for transactions
1087    #[serde(rename = "minrelaytxfee", with = "bitcoin::amount::serde::as_btc")]
1088    pub min_relay_tx_fee: Amount,
1089    /// Minimum fee rate increment for mempool limiting or replacement in BTC/kvB
1090    #[serde(rename = "incrementalrelayfee", default, with = "bitcoin::amount::serde::as_btc::opt")]
1091    pub incremental_relay_fee: Option<Amount>,
1092    /// Current number of transactions that haven't passed initial broadcast yet
1093    #[serde(rename = "unbroadcastcount")]
1094    pub unbroadcast_count: Option<usize>,
1095    /// True if the mempool accepts RBF without replaceability signaling inspection
1096    #[serde(rename = "fullrbf")]
1097    pub full_rbf: Option<bool>,
1098}
1099
1100#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1101pub struct GetMempoolEntryResult {
1102    /// Virtual transaction size as defined in BIP 141. This is different from actual serialized
1103    /// size for witness transactions as witness data is discounted.
1104    #[serde(alias = "size")]
1105    pub vsize: u64,
1106    /// Transaction weight as defined in BIP 141. Added in Core v0.19.0.
1107    pub weight: Option<u64>,
1108    /// Local time transaction entered pool in seconds since 1 Jan 1970 GMT
1109    pub time: u64,
1110    /// Block height when transaction entered pool
1111    pub height: u64,
1112    /// Number of in-mempool descendant transactions (including this one)
1113    #[serde(rename = "descendantcount")]
1114    pub descendant_count: u64,
1115    /// Virtual transaction size of in-mempool descendants (including this one)
1116    #[serde(rename = "descendantsize")]
1117    pub descendant_size: u64,
1118    /// Number of in-mempool ancestor transactions (including this one)
1119    #[serde(rename = "ancestorcount")]
1120    pub ancestor_count: u64,
1121    /// Virtual transaction size of in-mempool ancestors (including this one)
1122    #[serde(rename = "ancestorsize")]
1123    pub ancestor_size: u64,
1124    /// Hash of serialized transaction, including witness data
1125    pub wtxid: bitcoin::Txid,
1126    /// Fee information
1127    pub fees: GetMempoolEntryResultFees,
1128    /// Unconfirmed transactions used as inputs for this transaction
1129    pub depends: Vec<bitcoin::Txid>,
1130    /// Unconfirmed transactions spending outputs from this transaction
1131    #[serde(rename = "spentby")]
1132    pub spent_by: Vec<bitcoin::Txid>,
1133    /// Whether this transaction could be replaced due to BIP125 (replace-by-fee)
1134    #[serde(rename = "bip125-replaceable")]
1135    pub bip125_replaceable: bool,
1136    /// Whether this transaction is currently unbroadcast (initial broadcast not yet acknowledged by any peers)
1137    /// Added in Bitcoin Core v0.21
1138    pub unbroadcast: Option<bool>,
1139}
1140
1141#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1142pub struct GetMempoolEntryResultFees {
1143    /// Transaction fee in BTC
1144    #[serde(with = "bitcoin::amount::serde::as_btc")]
1145    pub base: Amount,
1146    /// Transaction fee with fee deltas used for mining priority in BTC
1147    #[serde(with = "bitcoin::amount::serde::as_btc")]
1148    pub modified: Amount,
1149    /// Modified fees (see above) of in-mempool ancestors (including this one) in BTC
1150    #[serde(with = "bitcoin::amount::serde::as_btc")]
1151    pub ancestor: Amount,
1152    /// Modified fees (see above) of in-mempool descendants (including this one) in BTC
1153    #[serde(with = "bitcoin::amount::serde::as_btc")]
1154    pub descendant: Amount,
1155}
1156
1157impl<'a> serde::Serialize for ImportMultiRequestScriptPubkey<'a> {
1158    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1159    where
1160        S: serde::Serializer,
1161    {
1162        match *self {
1163            ImportMultiRequestScriptPubkey::Address(ref addr) => {
1164                #[derive(Serialize)]
1165                struct Tmp<'a> {
1166                    pub address: &'a Address,
1167                }
1168                serde::Serialize::serialize(
1169                    &Tmp {
1170                        address: addr,
1171                    },
1172                    serializer,
1173                )
1174            }
1175            ImportMultiRequestScriptPubkey::Script(script) => {
1176                serializer.serialize_str(&script.to_hex_string())
1177            }
1178        }
1179    }
1180}
1181
1182/// A import request for importmulti.
1183///
1184/// Note: unlike in bitcoind, `timestamp` defaults to 0.
1185#[derive(Clone, PartialEq, Eq, Debug, Default, Serialize)]
1186pub struct ImportMultiRequest<'a> {
1187    pub timestamp: Timestamp,
1188    /// If using descriptor, do not also provide address/scriptPubKey, scripts, or pubkeys.
1189    #[serde(rename = "desc", skip_serializing_if = "Option::is_none")]
1190    pub descriptor: Option<&'a str>,
1191    #[serde(rename = "scriptPubKey", skip_serializing_if = "Option::is_none")]
1192    pub script_pubkey: Option<ImportMultiRequestScriptPubkey<'a>>,
1193    #[serde(rename = "redeemscript", skip_serializing_if = "Option::is_none")]
1194    pub redeem_script: Option<&'a Script>,
1195    #[serde(rename = "witnessscript", skip_serializing_if = "Option::is_none")]
1196    pub witness_script: Option<&'a Script>,
1197    #[serde(skip_serializing_if = "<[_]>::is_empty")]
1198    pub pubkeys: &'a [PublicKey],
1199    #[serde(skip_serializing_if = "<[_]>::is_empty")]
1200    pub keys: &'a [PrivateKey],
1201    #[serde(skip_serializing_if = "Option::is_none")]
1202    pub range: Option<(usize, usize)>,
1203    #[serde(skip_serializing_if = "Option::is_none")]
1204    pub internal: Option<bool>,
1205    #[serde(skip_serializing_if = "Option::is_none")]
1206    pub watchonly: Option<bool>,
1207    #[serde(skip_serializing_if = "Option::is_none")]
1208    pub label: Option<&'a str>,
1209    #[serde(skip_serializing_if = "Option::is_none")]
1210    pub keypool: Option<bool>,
1211}
1212
1213#[derive(Clone, PartialEq, Eq, Debug, Default, Deserialize, Serialize)]
1214pub struct ImportMultiOptions {
1215    #[serde(skip_serializing_if = "Option::is_none")]
1216    pub rescan: Option<bool>,
1217}
1218
1219#[derive(Clone, PartialEq, Eq, Copy, Debug)]
1220pub enum Timestamp {
1221    Now,
1222    Time(u64),
1223}
1224
1225impl serde::Serialize for Timestamp {
1226    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1227    where
1228        S: serde::Serializer,
1229    {
1230        match *self {
1231            Timestamp::Now => serializer.serialize_str("now"),
1232            Timestamp::Time(timestamp) => serializer.serialize_u64(timestamp),
1233        }
1234    }
1235}
1236
1237impl<'de> serde::Deserialize<'de> for Timestamp {
1238    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1239    where
1240        D: serde::Deserializer<'de>,
1241    {
1242        use serde::de;
1243        struct Visitor;
1244        impl<'de> de::Visitor<'de> for Visitor {
1245            type Value = Timestamp;
1246
1247            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
1248                write!(formatter, "unix timestamp or 'now'")
1249            }
1250
1251            fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
1252            where
1253                E: de::Error,
1254            {
1255                Ok(Timestamp::Time(value))
1256            }
1257
1258            fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
1259            where
1260                E: de::Error,
1261            {
1262                if value == "now" {
1263                    Ok(Timestamp::Now)
1264                } else {
1265                    Err(de::Error::custom(format!(
1266                        "invalid str '{}', expecting 'now' or unix timestamp",
1267                        value
1268                    )))
1269                }
1270            }
1271        }
1272        deserializer.deserialize_any(Visitor)
1273    }
1274}
1275
1276impl Default for Timestamp {
1277    fn default() -> Self {
1278        Timestamp::Time(0)
1279    }
1280}
1281
1282impl From<u64> for Timestamp {
1283    fn from(t: u64) -> Self {
1284        Timestamp::Time(t)
1285    }
1286}
1287
1288impl From<Option<u64>> for Timestamp {
1289    fn from(timestamp: Option<u64>) -> Self {
1290        timestamp.map_or(Timestamp::Now, Timestamp::Time)
1291    }
1292}
1293
1294#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1295pub struct ImportMultiResultError {
1296    pub code: i64,
1297    pub message: String,
1298}
1299
1300#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1301pub struct ImportMultiResult {
1302    pub success: bool,
1303    #[serde(default)]
1304    pub warnings: Vec<String>,
1305    pub error: Option<ImportMultiResultError>,
1306}
1307
1308/// A import request for importdescriptors.
1309#[derive(Clone, PartialEq, Eq, Debug, Default, Deserialize, Serialize)]
1310pub struct ImportDescriptors {
1311    #[serde(rename = "desc")]
1312    pub descriptor: String,
1313    pub timestamp: Timestamp,
1314    #[serde(skip_serializing_if = "Option::is_none")]
1315    pub active: Option<bool>,
1316    #[serde(skip_serializing_if = "Option::is_none")]
1317    pub range: Option<(usize, usize)>,
1318    #[serde(skip_serializing_if = "Option::is_none")]
1319    pub next_index: Option<usize>,
1320    #[serde(skip_serializing_if = "Option::is_none")]
1321    pub internal: Option<bool>,
1322    #[serde(skip_serializing_if = "Option::is_none")]
1323    pub label: Option<String>,
1324}
1325
1326/// Progress toward rejecting pre-softfork blocks
1327#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1328pub struct RejectStatus {
1329    /// `true` if threshold reached
1330    pub status: bool,
1331}
1332
1333/// Models the result of "getpeerinfo"
1334#[derive(Clone, Debug, Deserialize, Serialize)]
1335pub struct GetPeerInfoResult {
1336    /// Peer index
1337    pub id: u64,
1338    /// The IP address and port of the peer
1339    // TODO: use a type for addr
1340    pub addr: String,
1341    /// Bind address of the connection to the peer
1342    // TODO: use a type for addrbind
1343    pub addrbind: String,
1344    /// Local address as reported by the peer
1345    // TODO: use a type for addrlocal
1346    pub addrlocal: Option<String>,
1347    /// Network (ipv4, ipv6, or onion) the peer connected through
1348    /// Added in Bitcoin Core v0.21
1349    pub network: Option<GetPeerInfoResultNetwork>,
1350    /// The services offered
1351    // TODO: use a type for services
1352    pub services: String,
1353    /// Whether peer has asked us to relay transactions to it
1354    pub relaytxes: bool,
1355    /// The time in seconds since epoch (Jan 1 1970 GMT) of the last send
1356    pub lastsend: u64,
1357    /// The time in seconds since epoch (Jan 1 1970 GMT) of the last receive
1358    pub lastrecv: u64,
1359    /// The time in seconds since epoch (Jan 1 1970 GMT) of the last valid transaction received from this peer
1360    /// Added in Bitcoin Core v0.21
1361    pub last_transaction: Option<u64>,
1362    /// The time in seconds since epoch (Jan 1 1970 GMT) of the last block received from this peer
1363    /// Added in Bitcoin Core v0.21
1364    pub last_block: Option<u64>,
1365    /// The total bytes sent
1366    pub bytessent: u64,
1367    /// The total bytes received
1368    pub bytesrecv: u64,
1369    /// The connection time in seconds since epoch (Jan 1 1970 GMT)
1370    pub conntime: u64,
1371    /// The time offset in seconds
1372    pub timeoffset: i64,
1373    /// ping time (if available)
1374    pub pingtime: Option<f64>,
1375    /// minimum observed ping time (if any at all)
1376    pub minping: Option<f64>,
1377    /// ping wait (if non-zero)
1378    pub pingwait: Option<f64>,
1379    /// The peer version, such as 70001
1380    pub version: u64,
1381    /// The string version
1382    pub subver: String,
1383    /// Inbound (true) or Outbound (false)
1384    pub inbound: bool,
1385    /// Whether connection was due to `addnode`/`-connect` or if it was an
1386    /// automatic/inbound connection
1387    /// Deprecated in Bitcoin Core v0.21
1388    pub addnode: Option<bool>,
1389    /// The starting height (block) of the peer
1390    pub startingheight: i64,
1391    /// The ban score
1392    /// Deprecated in Bitcoin Core v0.21
1393    pub banscore: Option<i64>,
1394    /// The last header we have in common with this peer
1395    pub synced_headers: i64,
1396    /// The last block we have in common with this peer
1397    pub synced_blocks: i64,
1398    /// The heights of blocks we're currently asking from this peer
1399    pub inflight: Vec<u64>,
1400    /// Whether the peer is whitelisted
1401    /// Deprecated in Bitcoin Core v0.21
1402    pub whitelisted: Option<bool>,
1403    #[serde(rename = "minfeefilter", default, with = "bitcoin::amount::serde::as_btc::opt")]
1404    pub min_fee_filter: Option<Amount>,
1405    /// The total bytes sent aggregated by message type
1406    pub bytessent_per_msg: HashMap<String, u64>,
1407    /// The total bytes received aggregated by message type
1408    pub bytesrecv_per_msg: HashMap<String, u64>,
1409    /// The type of the connection
1410    /// Added in Bitcoin Core v0.21
1411    pub connection_type: Option<GetPeerInfoResultConnectionType>,
1412}
1413
1414#[derive(Copy, Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
1415#[serde(rename_all = "snake_case")]
1416pub enum GetPeerInfoResultNetwork {
1417    Ipv4,
1418    Ipv6,
1419    Onion,
1420    #[deprecated]
1421    Unroutable,
1422    NotPubliclyRoutable,
1423    I2p,
1424    Cjdns,
1425    Internal,
1426}
1427
1428#[derive(Copy, Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
1429#[serde(rename_all = "kebab-case")]
1430pub enum GetPeerInfoResultConnectionType {
1431    OutboundFullRelay,
1432    BlockRelayOnly,
1433    Inbound,
1434    Manual,
1435    AddrFetch,
1436    Feeler,
1437}
1438
1439#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1440pub struct GetAddedNodeInfoResult {
1441    /// The node IP address or name (as provided to addnode)
1442    #[serde(rename = "addednode")]
1443    pub added_node: String,
1444    ///  If connected
1445    pub connected: bool,
1446    /// Only when connected = true
1447    pub addresses: Vec<GetAddedNodeInfoResultAddress>,
1448}
1449
1450#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1451pub struct GetAddedNodeInfoResultAddress {
1452    /// The bitcoin server IP and port we're connected to
1453    pub address: String,
1454    /// connection, inbound or outbound
1455    pub connected: GetAddedNodeInfoResultAddressType,
1456}
1457
1458#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1459#[serde(rename_all = "lowercase")]
1460pub enum GetAddedNodeInfoResultAddressType {
1461    Inbound,
1462    Outbound,
1463}
1464
1465#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1466pub struct GetNodeAddressesResult {
1467    /// Timestamp in seconds since epoch (Jan 1 1970 GMT) keeping track of when the node was last seen
1468    pub time: u64,
1469    /// The services offered
1470    pub services: usize,
1471    /// The address of the node
1472    pub address: String,
1473    /// The port of the node
1474    pub port: u16,
1475}
1476
1477#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1478pub struct ListBannedResult {
1479    pub address: String,
1480    pub banned_until: u64,
1481    pub ban_created: u64,
1482}
1483
1484/// Models the result of "estimatesmartfee"
1485#[derive(Clone, Debug, Deserialize, Serialize)]
1486pub struct EstimateSmartFeeResult {
1487    /// Estimate fee rate in BTC/kB.
1488    #[serde(
1489        default,
1490        rename = "feerate",
1491        skip_serializing_if = "Option::is_none",
1492        with = "bitcoin::amount::serde::as_btc::opt"
1493    )]
1494    pub fee_rate: Option<Amount>,
1495    /// Errors encountered during processing.
1496    pub errors: Option<Vec<String>>,
1497    /// Block number where estimate was found.
1498    pub blocks: i64,
1499}
1500
1501/// Models the result of "waitfornewblock", and "waitforblock"
1502#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1503pub struct BlockRef {
1504    pub hash: bitcoin::BlockHash,
1505    pub height: u64,
1506}
1507
1508/// Models the result of "getdescriptorinfo"
1509#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1510pub struct GetDescriptorInfoResult {
1511    pub descriptor: String,
1512    pub checksum: Option<String>,
1513    #[serde(rename = "isrange")]
1514    pub is_range: bool,
1515    #[serde(rename = "issolvable")]
1516    pub is_solvable: bool,
1517    #[serde(rename = "hasprivatekeys")]
1518    pub has_private_keys: bool,
1519}
1520
1521/// Models the request options of "getblocktemplate"
1522#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1523pub struct GetBlockTemplateOptions {
1524    pub mode: GetBlockTemplateModes,
1525    //// List of client side supported softfork deployment
1526    pub rules: Vec<GetBlockTemplateRules>,
1527    /// List of client side supported features
1528    pub capabilities: Vec<GetBlockTemplateCapabilities>,
1529}
1530
1531/// Enum to represent client-side supported features
1532#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1533#[serde(rename_all = "lowercase")]
1534pub enum GetBlockTemplateCapabilities {
1535    // No features supported yet. In the future this could be, for example, Proposal and Longpolling
1536}
1537
1538/// Enum to representing specific block rules that the requested template
1539/// should support.
1540#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1541#[serde(rename_all = "lowercase")]
1542pub enum GetBlockTemplateRules {
1543    SegWit,
1544    Signet,
1545    Csv,
1546    Taproot,
1547}
1548
1549/// Enum to represent client-side supported features.
1550#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1551#[serde(rename_all = "lowercase")]
1552pub enum GetBlockTemplateModes {
1553    /// Using this mode, the server build a block template and return it as
1554    /// response to the request. This is the default mode.
1555    Template,
1556    // TODO: Support for "proposal" mode is not yet implemented on the client
1557    // side.
1558}
1559
1560/// Models the result of "getblocktemplate"
1561#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1562pub struct GetBlockTemplateResult {
1563    /// The compressed difficulty in hexadecimal
1564    #[serde(with = "crate::serde_hex")]
1565    pub bits: Vec<u8>,
1566    /// The previous block hash the current template is mining on
1567    #[serde(rename = "previousblockhash")]
1568    pub previous_block_hash: bitcoin::BlockHash,
1569    /// The current time as seen by the server (recommended for block time)
1570    /// Note: this is not necessarily the system clock, and must fall within
1571    /// the mintime/maxtime rules. Expressed as UNIX timestamp.
1572    #[serde(rename = "curtime")]
1573    pub current_time: u64,
1574    /// The height of the block we will be mining: `current height + 1`
1575    pub height: u64,
1576    /// Block sigops limit
1577    #[serde(rename = "sigoplimit")]
1578    pub sigop_limit: u32,
1579    /// Block size limit
1580    #[serde(rename = "sizelimit")]
1581    pub size_limit: u32,
1582    /// Block weight limit
1583    #[serde(rename = "weightlimit")]
1584    pub weight_limit: u32,
1585    /// Block header version
1586    pub version: u32,
1587    /// Block rules that are to be enforced
1588    pub rules: Vec<GetBlockTemplateResultRules>,
1589    /// List of features the Bitcoin Core getblocktemplate implementation supports
1590    pub capabilities: Vec<GetBlockTemplateResultCapabilities>,
1591    /// Set of pending, supported versionbit (BIP 9) softfork deployments
1592    #[serde(rename = "vbavailable")]
1593    pub version_bits_available: HashMap<String, u32>,
1594    /// Bit mask of versionbits the server requires set in submissions
1595    #[serde(rename = "vbrequired")]
1596    pub version_bits_required: u32,
1597    /// Id used in longpoll requests for this template.
1598    pub longpollid: String,
1599    /// List of transactions included in the template block
1600    pub transactions: Vec<GetBlockTemplateResultTransaction>,
1601    /// The signet challenge. Only set if mining on a signet, otherwise empty
1602    #[serde(default, with = "bitcoin::script::ScriptBuf")]
1603    pub signet_challenge: bitcoin::script::ScriptBuf,
1604    /// The default witness commitment included in an OP_RETURN output of the
1605    /// coinbase transactions. Only set when mining on a network where SegWit
1606    /// is activated.
1607    #[serde(with = "bitcoin::script::ScriptBuf", default)]
1608    pub default_witness_commitment: bitcoin::script::ScriptBuf,
1609    /// Data that should be included in the coinbase's scriptSig content. Only
1610    /// the values (hexadecimal byte-for-byte) in this map should be included,
1611    /// not the keys. This does not include the block height, which is required
1612    /// to be included in the scriptSig by BIP 0034. It is advisable to encode
1613    /// values inside "PUSH" opcodes, so as to not inadvertently expend SIGOPs
1614    /// (which are counted toward limits, despite not being executed).
1615    pub coinbaseaux: HashMap<String, String>,
1616    /// Total funds available for the coinbase
1617    #[serde(rename = "coinbasevalue", with = "bitcoin::amount::serde::as_sat", default)]
1618    pub coinbase_value: Amount,
1619    /// The number which valid hashes must be less than, in big-endian
1620    #[serde(with = "crate::serde_hex")]
1621    pub target: Vec<u8>,
1622    /// The minimum timestamp appropriate for the next block time. Expressed as
1623    /// UNIX timestamp.
1624    #[serde(rename = "mintime")]
1625    pub min_time: u64,
1626    /// List of things that may be changed by the client before submitting a
1627    /// block
1628    pub mutable: Vec<GetBlockTemplateResulMutations>,
1629    /// A range of valid nonces
1630    #[serde(with = "crate::serde_hex", rename = "noncerange")]
1631    pub nonce_range: Vec<u8>,
1632}
1633
1634/// Models a single transaction entry in the result of "getblocktemplate"
1635#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1636pub struct GetBlockTemplateResultTransaction {
1637    /// The transaction id
1638    pub txid: bitcoin::Txid,
1639    /// The wtxid of the transaction
1640    #[serde(rename = "hash")]
1641    pub wtxid: bitcoin::Wtxid,
1642    /// The serilaized transaction bytes
1643    #[serde(with = "crate::serde_hex", rename = "data")]
1644    pub raw_tx: Vec<u8>,
1645    // The transaction fee
1646    #[serde(with = "bitcoin::amount::serde::as_sat")]
1647    pub fee: Amount,
1648    /// Transaction sigops
1649    pub sigops: u32,
1650    /// Transaction weight in weight units
1651    pub weight: usize,
1652    /// Transactions that must be in present in the final block if this one is.
1653    /// Indexed by a 1-based index in the `GetBlockTemplateResult.transactions`
1654    /// list
1655    pub depends: Vec<u32>,
1656}
1657
1658impl GetBlockTemplateResultTransaction {
1659    pub fn transaction(&self) -> Result<Transaction, encode::Error> {
1660        encode::deserialize(&self.raw_tx)
1661    }
1662}
1663
1664/// Enum to represent Bitcoin Core's supported features for getblocktemplate
1665#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1666#[serde(rename_all = "lowercase")]
1667pub enum GetBlockTemplateResultCapabilities {
1668    Proposal,
1669}
1670
1671/// Enum to representing specific block rules that client must support to work
1672/// with the template returned by Bitcoin Core
1673#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1674#[serde(rename_all = "lowercase")]
1675pub enum GetBlockTemplateResultRules {
1676    /// Inidcates that the client must support the SegWit rules when using this
1677    /// template.
1678    #[serde(alias = "!segwit")]
1679    SegWit,
1680    /// Indicates that the client must support the Signet rules when using this
1681    /// template.
1682    #[serde(alias = "!signet")]
1683    Signet,
1684    /// Indicates that the client must support the CSV rules when using this
1685    /// template.
1686    Csv,
1687    /// Indicates that the client must support the taproot rules when using this
1688    /// template.
1689    Taproot,
1690    /// Indicates that the client must support the Regtest rules when using this
1691    /// template. TestDummy is a test soft-fork only used on the regtest network.
1692    Testdummy,
1693}
1694
1695/// Enum to representing mutable parts of the block template. This does only
1696/// cover the muations implemented in Bitcoin Core. More mutations are defined
1697/// in [BIP-23](https://github.com/bitcoin/bips/blob/master/bip-0023.mediawiki#Mutations),
1698/// but not implemented in the getblocktemplate implementation of Bitcoin Core.
1699#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1700#[serde(rename_all = "lowercase")]
1701pub enum GetBlockTemplateResulMutations {
1702    /// The client is allowed to modify the time in the header of the block
1703    Time,
1704    /// The client is allowed to add transactions to the block
1705    Transactions,
1706    /// The client is allowed to use the work with other previous blocks.
1707    /// This implicitly allows removing transactions that are no longer valid.
1708    /// It also implies adjusting the "height" as necessary.
1709    #[serde(rename = "prevblock")]
1710    PreviousBlock,
1711}
1712
1713/// Models the result of "walletcreatefundedpsbt"
1714#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1715pub struct WalletCreateFundedPsbtResult {
1716    pub psbt: String,
1717    #[serde(with = "bitcoin::amount::serde::as_btc")]
1718    pub fee: Amount,
1719    #[serde(rename = "changepos")]
1720    pub change_position: i32,
1721}
1722
1723/// Models the result of "walletprocesspsbt"
1724#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1725pub struct WalletProcessPsbtResult {
1726    pub psbt: String,
1727    pub complete: bool,
1728}
1729
1730/// Models the request for "walletcreatefundedpsbt"
1731#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize, Default)]
1732pub struct WalletCreateFundedPsbtOptions {
1733    /// For a transaction with existing inputs, automatically include more if they are not enough (default true).
1734    /// Added in Bitcoin Core v0.21
1735    #[serde(skip_serializing_if = "Option::is_none")]
1736    pub add_inputs: Option<bool>,
1737    #[serde(rename = "changeAddress", skip_serializing_if = "Option::is_none")]
1738    pub change_address: Option<Address<NetworkUnchecked>>,
1739    #[serde(rename = "changePosition", skip_serializing_if = "Option::is_none")]
1740    pub change_position: Option<u16>,
1741    #[serde(skip_serializing_if = "Option::is_none")]
1742    pub change_type: Option<AddressType>,
1743    #[serde(rename = "includeWatching", skip_serializing_if = "Option::is_none")]
1744    pub include_watching: Option<bool>,
1745    #[serde(rename = "lockUnspents", skip_serializing_if = "Option::is_none")]
1746    pub lock_unspent: Option<bool>,
1747    #[serde(
1748        rename = "feeRate",
1749        skip_serializing_if = "Option::is_none",
1750        with = "bitcoin::amount::serde::as_btc::opt"
1751    )]
1752    pub fee_rate: Option<Amount>,
1753    #[serde(rename = "subtractFeeFromOutputs", skip_serializing_if = "Vec::is_empty")]
1754    pub subtract_fee_from_outputs: Vec<u16>,
1755    #[serde(skip_serializing_if = "Option::is_none")]
1756    pub replaceable: Option<bool>,
1757    #[serde(skip_serializing_if = "Option::is_none")]
1758    pub conf_target: Option<u16>,
1759    #[serde(skip_serializing_if = "Option::is_none")]
1760    pub estimate_mode: Option<EstimateMode>,
1761}
1762
1763/// Models the result of "finalizepsbt"
1764#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1765pub struct FinalizePsbtResult {
1766    pub psbt: Option<String>,
1767    #[serde(default, with = "crate::serde_hex::opt")]
1768    pub hex: Option<Vec<u8>>,
1769    pub complete: bool,
1770}
1771
1772/// Model for decode transaction
1773#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1774pub struct DecodeRawTransactionResult {
1775    pub txid: bitcoin::Txid,
1776    pub hash: bitcoin::Wtxid,
1777    pub size: u32,
1778    pub vsize: u32,
1779    pub weight: u32,
1780    pub version: u32,
1781    pub locktime: u32,
1782    pub vin: Vec<GetRawTransactionResultVin>,
1783    pub vout: Vec<GetRawTransactionResultVout>,
1784}
1785
1786/// Models the result of "getchaintips"
1787pub type GetChainTipsResult = Vec<GetChainTipsResultTip>;
1788
1789/// Models a single chain tip for the result of "getchaintips"
1790#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1791pub struct GetChainTipsResultTip {
1792    /// Block height of the chain tip
1793    pub height: u64,
1794    /// Header hash of the chain tip
1795    pub hash: bitcoin::BlockHash,
1796    /// Length of the branch (number of blocks since the last common block)
1797    #[serde(rename = "branchlen")]
1798    pub branch_length: usize,
1799    /// Status of the tip as seen by Bitcoin Core
1800    pub status: GetChainTipsResultStatus,
1801}
1802
1803#[derive(Copy, Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
1804#[serde(rename_all = "lowercase")]
1805pub enum GetChainTipsResultStatus {
1806    /// The branch contains at least one invalid block
1807    Invalid,
1808    /// Not all blocks for this branch are available, but the headers are valid
1809    #[serde(rename = "headers-only")]
1810    HeadersOnly,
1811    /// All blocks are available for this branch, but they were never fully validated
1812    #[serde(rename = "valid-headers")]
1813    ValidHeaders,
1814    /// This branch is not part of the active chain, but is fully validated
1815    #[serde(rename = "valid-fork")]
1816    ValidFork,
1817    /// This is the tip of the active main chain, which is certainly valid
1818    Active,
1819}
1820
1821impl FinalizePsbtResult {
1822    pub fn transaction(&self) -> Option<Result<Transaction, encode::Error>> {
1823        self.hex.as_ref().map(|h| encode::deserialize(h))
1824    }
1825}
1826
1827// Custom types for input arguments.
1828
1829#[derive(Serialize, Deserialize, Debug, Clone, Copy, Eq, PartialEq, Hash)]
1830#[serde(rename_all = "UPPERCASE")]
1831pub enum EstimateMode {
1832    Unset,
1833    Economical,
1834    Conservative,
1835}
1836
1837/// A wrapper around bitcoin::EcdsaSighashType that will be serialized
1838/// according to what the RPC expects.
1839pub struct SigHashType(bitcoin::sighash::EcdsaSighashType);
1840
1841impl From<bitcoin::sighash::EcdsaSighashType> for SigHashType {
1842    fn from(sht: bitcoin::sighash::EcdsaSighashType) -> SigHashType {
1843        SigHashType(sht)
1844    }
1845}
1846
1847impl serde::Serialize for SigHashType {
1848    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1849    where
1850        S: serde::Serializer,
1851    {
1852        serializer.serialize_str(match self.0 {
1853            bitcoin::sighash::EcdsaSighashType::All => "ALL",
1854            bitcoin::sighash::EcdsaSighashType::None => "NONE",
1855            bitcoin::sighash::EcdsaSighashType::Single => "SINGLE",
1856            bitcoin::sighash::EcdsaSighashType::AllPlusAnyoneCanPay => "ALL|ANYONECANPAY",
1857            bitcoin::sighash::EcdsaSighashType::NonePlusAnyoneCanPay => "NONE|ANYONECANPAY",
1858            bitcoin::sighash::EcdsaSighashType::SinglePlusAnyoneCanPay => "SINGLE|ANYONECANPAY",
1859        })
1860    }
1861}
1862
1863// Used for createrawtransaction argument.
1864#[derive(Serialize, Clone, PartialEq, Eq, Debug, Deserialize)]
1865#[serde(rename_all = "camelCase")]
1866pub struct CreateRawTransactionInput {
1867    pub txid: bitcoin::Txid,
1868    pub vout: u32,
1869    #[serde(skip_serializing_if = "Option::is_none")]
1870    pub sequence: Option<u32>,
1871}
1872
1873#[derive(Serialize, Clone, PartialEq, Eq, Debug, Default)]
1874#[serde(rename_all = "camelCase")]
1875pub struct FundRawTransactionOptions {
1876    /// For a transaction with existing inputs, automatically include more if they are not enough (default true).
1877    /// Added in Bitcoin Core v0.21
1878    #[serde(rename = "add_inputs", skip_serializing_if = "Option::is_none")]
1879    pub add_inputs: Option<bool>,
1880    #[serde(skip_serializing_if = "Option::is_none")]
1881    pub change_address: Option<Address>,
1882    #[serde(skip_serializing_if = "Option::is_none")]
1883    pub change_position: Option<u32>,
1884    #[serde(rename = "change_type", skip_serializing_if = "Option::is_none")]
1885    pub change_type: Option<AddressType>,
1886    #[serde(skip_serializing_if = "Option::is_none")]
1887    pub include_watching: Option<bool>,
1888    #[serde(skip_serializing_if = "Option::is_none")]
1889    pub lock_unspents: Option<bool>,
1890    /// The fee rate to pay per kvB. NB. This field is converted to camelCase
1891    /// when serialized, so it is receeived by fundrawtransaction as `feeRate`,
1892    /// which fee rate per kvB, and *not* `fee_rate`, which is per vB.
1893    #[serde(
1894        with = "bitcoin::amount::serde::as_btc::opt",
1895        skip_serializing_if = "Option::is_none"
1896    )]
1897    pub fee_rate: Option<Amount>,
1898    #[serde(skip_serializing_if = "Option::is_none")]
1899    pub subtract_fee_from_outputs: Option<Vec<u32>>,
1900    #[serde(skip_serializing_if = "Option::is_none")]
1901    pub replaceable: Option<bool>,
1902    #[serde(rename = "conf_target", skip_serializing_if = "Option::is_none")]
1903    pub conf_target: Option<u32>,
1904    #[serde(rename = "estimate_mode", skip_serializing_if = "Option::is_none")]
1905    pub estimate_mode: Option<EstimateMode>,
1906}
1907
1908#[derive(Deserialize, Clone, PartialEq, Eq, Debug, Serialize)]
1909#[serde(rename_all = "camelCase")]
1910pub struct FundRawTransactionResult {
1911    #[serde(with = "crate::serde_hex")]
1912    pub hex: Vec<u8>,
1913    #[serde(with = "bitcoin::amount::serde::as_btc")]
1914    pub fee: Amount,
1915    #[serde(rename = "changepos")]
1916    pub change_position: i32,
1917}
1918
1919#[derive(Deserialize, Clone, PartialEq, Eq, Debug, Serialize)]
1920pub struct GetBalancesResultEntry {
1921    #[serde(with = "bitcoin::amount::serde::as_btc")]
1922    pub trusted: Amount,
1923    #[serde(with = "bitcoin::amount::serde::as_btc")]
1924    pub untrusted_pending: Amount,
1925    #[serde(with = "bitcoin::amount::serde::as_btc")]
1926    pub immature: Amount,
1927}
1928
1929#[derive(Deserialize, Clone, PartialEq, Eq, Debug, Serialize)]
1930#[serde(rename_all = "camelCase")]
1931pub struct GetBalancesResult {
1932    pub mine: GetBalancesResultEntry,
1933    pub watchonly: Option<GetBalancesResultEntry>,
1934}
1935
1936impl FundRawTransactionResult {
1937    pub fn transaction(&self) -> Result<Transaction, encode::Error> {
1938        encode::deserialize(&self.hex)
1939    }
1940}
1941
1942// Used for signrawtransaction argument.
1943#[derive(Serialize, Clone, PartialEq, Debug, Deserialize)]
1944#[serde(rename_all = "camelCase")]
1945pub struct SignRawTransactionInput {
1946    pub txid: bitcoin::Txid,
1947    pub vout: u32,
1948    pub script_pub_key: ScriptBuf,
1949    #[serde(skip_serializing_if = "Option::is_none")]
1950    pub redeem_script: Option<ScriptBuf>,
1951    #[serde(
1952        default,
1953        skip_serializing_if = "Option::is_none",
1954        with = "bitcoin::amount::serde::as_btc::opt"
1955    )]
1956    pub amount: Option<Amount>,
1957}
1958
1959/// Used to represent UTXO set hash type
1960#[derive(Clone, Serialize, PartialEq, Eq, Debug, Deserialize)]
1961#[serde(rename_all = "snake_case")]
1962pub enum TxOutSetHashType {
1963    HashSerialized2,
1964    Muhash,
1965    None,
1966}
1967
1968/// Used to specify a block hash or a height
1969#[derive(Clone, Serialize, PartialEq, Eq, Debug, Deserialize)]
1970#[serde(untagged)]
1971pub enum HashOrHeight {
1972    BlockHash(bitcoin::BlockHash),
1973    Height(u64),
1974}
1975
1976#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1977pub struct GetTxOutSetInfoResult {
1978    /// The block height (index) of the returned statistics
1979    pub height: u64,
1980    /// The hash of the block at which these statistics are calculated
1981    #[serde(rename = "bestblock")]
1982    pub best_block: bitcoin::BlockHash,
1983    /// The number of transactions with unspent outputs (not available when coinstatsindex is used)
1984    #[serde(default, skip_serializing_if = "Option::is_none")]
1985    pub transactions: Option<u64>,
1986    /// The number of unspent transaction outputs
1987    #[serde(rename = "txouts")]
1988    pub tx_outs: u64,
1989    /// A meaningless metric for UTXO set size
1990    pub bogosize: u64,
1991    /// The serialized hash (only present if 'hash_serialized_2' hash_type is chosen)
1992    #[serde(default, skip_serializing_if = "Option::is_none")]
1993    pub hash_serialized_2: Option<sha256::Hash>,
1994    /// The serialized hash (only present if 'muhash' hash_type is chosen)
1995    #[serde(default, skip_serializing_if = "Option::is_none")]
1996    pub muhash: Option<sha256::Hash>,
1997    /// The estimated size of the chainstate on disk (not available when coinstatsindex is used)
1998    #[serde(default, skip_serializing_if = "Option::is_none")]
1999    pub disk_size: Option<u64>,
2000    /// The total amount
2001    #[serde(with = "bitcoin::amount::serde::as_btc")]
2002    pub total_amount: Amount,
2003    /// The total amount of coins permanently excluded from the UTXO set (only available if coinstatsindex is used)
2004    #[serde(
2005        default,
2006        skip_serializing_if = "Option::is_none",
2007        with = "bitcoin::amount::serde::as_btc::opt"
2008    )]
2009    pub total_unspendable_amount: Option<Amount>,
2010    /// Info on amounts in the block at this block height (only available if coinstatsindex is used)
2011    #[serde(default, skip_serializing_if = "Option::is_none")]
2012    pub block_info: Option<BlockInfo>,
2013}
2014
2015/// Info on amounts in the block at the block height of the `gettxoutsetinfo` call (only available if coinstatsindex is used)
2016#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
2017pub struct BlockInfo {
2018    /// Amount of previous outputs spent
2019    #[serde(with = "bitcoin::amount::serde::as_btc")]
2020    pub prevout_spent: Amount,
2021    /// Output size of the coinbase transaction
2022    #[serde(with = "bitcoin::amount::serde::as_btc")]
2023    pub coinbase: Amount,
2024    /// Newly-created outputs
2025    #[serde(with = "bitcoin::amount::serde::as_btc")]
2026    pub new_outputs_ex_coinbase: Amount,
2027    /// Amount of unspendable outputs
2028    #[serde(with = "bitcoin::amount::serde::as_btc")]
2029    pub unspendable: Amount,
2030    /// Detailed view of the unspendable categories
2031    pub unspendables: Unspendables,
2032}
2033
2034/// Detailed view of the unspendable categories
2035#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
2036pub struct Unspendables {
2037    /// Unspendable coins from the Genesis block
2038    #[serde(with = "bitcoin::amount::serde::as_btc")]
2039    pub genesis_block: Amount,
2040    /// Transactions overridden by duplicates (no longer possible with BIP30)
2041    #[serde(with = "bitcoin::amount::serde::as_btc")]
2042    pub bip30: Amount,
2043    /// Amounts sent to scripts that are unspendable (for example OP_RETURN outputs)
2044    #[serde(with = "bitcoin::amount::serde::as_btc")]
2045    pub scripts: Amount,
2046    /// Fee rewards that miners did not claim in their coinbase transaction
2047    #[serde(with = "bitcoin::amount::serde::as_btc")]
2048    pub unclaimed_rewards: Amount,
2049}
2050
2051#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
2052pub struct GetNetTotalsResult {
2053    /// Total bytes received
2054    #[serde(rename = "totalbytesrecv")]
2055    pub total_bytes_recv: u64,
2056    /// Total bytes sent
2057    #[serde(rename = "totalbytessent")]
2058    pub total_bytes_sent: u64,
2059    /// Current UNIX time in milliseconds
2060    #[serde(rename = "timemillis")]
2061    pub time_millis: u64,
2062    /// Upload target statistics
2063    #[serde(rename = "uploadtarget")]
2064    pub upload_target: GetNetTotalsResultUploadTarget,
2065}
2066
2067#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
2068pub struct GetNetTotalsResultUploadTarget {
2069    /// Length of the measuring timeframe in seconds
2070    #[serde(rename = "timeframe")]
2071    pub time_frame: u64,
2072    /// Target in bytes
2073    pub target: u64,
2074    /// True if target is reached
2075    pub target_reached: bool,
2076    /// True if serving historical blocks
2077    pub serve_historical_blocks: bool,
2078    /// Bytes left in current time cycle
2079    pub bytes_left_in_cycle: u64,
2080    /// Seconds left in current time cycle
2081    pub time_left_in_cycle: u64,
2082}
2083
2084/// Used to represent an address type.
2085#[derive(Copy, Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
2086#[serde(rename_all = "kebab-case")]
2087pub enum AddressType {
2088    Legacy,
2089    P2shSegwit,
2090    Bech32,
2091    Bech32m,
2092}
2093
2094/// Used to represent arguments that can either be an address or a public key.
2095#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
2096pub enum PubKeyOrAddress<'a> {
2097    Address(&'a Address),
2098    PubKey(&'a PublicKey),
2099}
2100
2101#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
2102#[serde(untagged)]
2103/// Start a scan of the UTXO set for an [output descriptor](https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md).
2104pub enum ScanTxOutRequest {
2105    /// Scan for a single descriptor
2106    Single(String),
2107    /// Scan for a descriptor with xpubs
2108    Extended {
2109        /// Descriptor
2110        desc: String,
2111        /// Range of the xpub derivations to scan
2112        range: (u64, u64),
2113    },
2114}
2115
2116#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
2117pub struct ScanTxOutResult {
2118    pub success: Option<bool>,
2119    #[serde(rename = "txouts")]
2120    pub tx_outs: Option<u64>,
2121    pub height: Option<u64>,
2122    #[serde(rename = "bestblock")]
2123    pub best_block_hash: Option<bitcoin::BlockHash>,
2124    pub unspents: Vec<Utxo>,
2125    #[serde(with = "bitcoin::amount::serde::as_btc")]
2126    pub total_amount: bitcoin::Amount,
2127}
2128
2129#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
2130#[serde(rename_all = "camelCase")]
2131pub struct Utxo {
2132    pub txid: bitcoin::Txid,
2133    pub vout: u32,
2134    pub script_pub_key: bitcoin::ScriptBuf,
2135    #[serde(rename = "desc")]
2136    pub descriptor: String,
2137    #[serde(with = "bitcoin::amount::serde::as_btc")]
2138    pub amount: bitcoin::Amount,
2139    pub height: u64,
2140}
2141
2142#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
2143pub struct IndexStatus {
2144    pub synced: bool,
2145    pub best_block_height: u32,
2146}
2147
2148#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
2149pub struct GetIndexInfoResult {
2150    pub txindex: Option<IndexStatus>,
2151    pub coinstatsindex: Option<IndexStatus>,
2152    #[serde(rename = "basic block filter index")]
2153    pub basic_block_filter_index: Option<IndexStatus>,
2154}
2155
2156#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
2157pub struct GetZmqNotificationsResult {
2158    #[serde(rename = "type")]
2159    pub notification_type: String,
2160    pub address: String,
2161    pub hwm: u64,
2162}
2163
2164impl<'a> serde::Serialize for PubKeyOrAddress<'a> {
2165    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
2166    where
2167        S: serde::Serializer,
2168    {
2169        match *self {
2170            PubKeyOrAddress::Address(a) => serde::Serialize::serialize(a, serializer),
2171            PubKeyOrAddress::PubKey(k) => serde::Serialize::serialize(k, serializer),
2172        }
2173    }
2174}
2175
2176// Custom deserializer functions.
2177
2178/// deserialize_hex_array_opt deserializes a vector of hex-encoded byte arrays.
2179fn deserialize_hex_array_opt<'de, D>(deserializer: D) -> Result<Option<Vec<Vec<u8>>>, D::Error>
2180where
2181    D: serde::Deserializer<'de>,
2182{
2183    //TODO(stevenroose) Revisit when issue is fixed:
2184    // https://github.com/serde-rs/serde/issues/723
2185
2186    let v: Vec<String> = Vec::deserialize(deserializer)?;
2187    let mut res = Vec::new();
2188    for h in v.into_iter() {
2189        res.push(FromHex::from_hex(&h).map_err(D::Error::custom)?);
2190    }
2191    Ok(Some(res))
2192}
2193
2194fn serialize_bip70_network<S>(network: &Network, serializer: S) -> Result<S::Ok, S::Error>
2195where
2196    S: serde::Serializer,
2197{
2198    serializer.serialize_str(network.to_core_arg())
2199}
2200
2201/// deserialize_bip70_network deserializes a Bitcoin Core network according to BIP70
2202/// The accepted input variants are: {"main", "test", "signet", "regtest"}
2203fn deserialize_bip70_network<'de, D>(deserializer: D) -> Result<Network, D::Error> 
2204where
2205    D: serde::Deserializer<'de>,
2206{
2207    struct NetworkVisitor;
2208    impl<'de> serde::de::Visitor<'de> for NetworkVisitor {
2209        type Value = Network;
2210
2211        fn visit_str<E: serde::de::Error>(self, s: &str) -> Result<Self::Value, E> {
2212            Network::from_core_arg(s)
2213                .map_err(|_| E::invalid_value(serde::de::Unexpected::Str(s), &"bitcoin network encoded as a string"))
2214        }
2215
2216        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
2217            write!(formatter, "bitcoin network encoded as a string")
2218        }
2219    }
2220
2221    deserializer.deserialize_str(NetworkVisitor)
2222}
2223
2224#[cfg(test)]
2225mod tests {
2226    use super::*;
2227
2228    #[test]
2229    fn test_softfork_type() {
2230        let buried: SoftforkType = serde_json::from_str("\"buried\"").unwrap();
2231        assert_eq!(buried, SoftforkType::Buried);
2232        let bip9: SoftforkType = serde_json::from_str("\"bip9\"").unwrap();
2233        assert_eq!(bip9, SoftforkType::Bip9);
2234        let other: SoftforkType = serde_json::from_str("\"bip8\"").unwrap();
2235        assert_eq!(other, SoftforkType::Other);
2236    }
2237}