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