Skip to main content

bellscoincore_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 = "bellscoincore_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::{
33    bip158, bip32, Address, Amount, Network, PrivateKey, PublicKey, Script, ScriptBuf,
34    SignedAmount, Transaction,
35};
36use serde::de::Error as SerdeError;
37use serde::{Deserialize, Serialize};
38use std::fmt;
39
40//TODO(stevenroose) consider using a Time type
41
42/// A module used for serde serialization of bytes in hexadecimal format.
43///
44/// The module is compatible with the serde attribute.
45pub mod serde_hex {
46    use bitcoin::hex::{DisplayHex, FromHex};
47    use serde::de::Error;
48    use serde::{Deserializer, Serializer};
49
50    pub fn serialize<S: Serializer>(b: &Vec<u8>, s: S) -> Result<S::Ok, S::Error> {
51        s.serialize_str(&b.to_lower_hex_string())
52    }
53
54    pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result<Vec<u8>, D::Error> {
55        let hex_str: String = ::serde::Deserialize::deserialize(d)?;
56        Ok(FromHex::from_hex(&hex_str).map_err(D::Error::custom)?)
57    }
58
59    pub mod opt {
60        use bitcoin::hex::{DisplayHex, FromHex};
61        use serde::de::Error;
62        use serde::{Deserializer, Serializer};
63
64        pub fn serialize<S: Serializer>(b: &Option<Vec<u8>>, s: S) -> Result<S::Ok, S::Error> {
65            match *b {
66                None => s.serialize_none(),
67                Some(ref b) => s.serialize_str(&b.to_lower_hex_string()),
68            }
69        }
70
71        pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result<Option<Vec<u8>>, D::Error> {
72            let hex_str: String = ::serde::Deserialize::deserialize(d)?;
73            Ok(Some(FromHex::from_hex(&hex_str).map_err(D::Error::custom)?))
74        }
75    }
76}
77
78#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
79pub struct GetNetworkInfoResultNetwork {
80    pub name: String,
81    pub limited: bool,
82    pub reachable: bool,
83    pub proxy: String,
84    pub proxy_randomize_credentials: bool,
85}
86
87#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
88pub struct GetNetworkInfoResultAddress {
89    pub address: String,
90    pub port: usize,
91    pub score: usize,
92}
93
94/// Used to represent values that can either be a string or a string array.
95#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)]
96#[serde(untagged)]
97pub enum StringOrStringArray {
98    String(String),
99    StringArray(Vec<String>),
100}
101
102#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
103pub struct GetNetworkInfoResult {
104    pub version: usize,
105    pub subversion: String,
106    #[serde(rename = "protocolversion")]
107    pub protocol_version: usize,
108    #[serde(rename = "localservices")]
109    pub local_services: String,
110    #[serde(rename = "localrelay")]
111    pub local_relay: bool,
112    #[serde(rename = "timeoffset")]
113    pub time_offset: isize,
114    pub connections: usize,
115    /// The number of inbound connections
116    /// Added in Bitcoin Core v0.21
117    pub connections_in: Option<usize>,
118    /// The number of outbound connections
119    /// Added in Bitcoin Core v0.21
120    pub connections_out: Option<usize>,
121    #[serde(rename = "networkactive")]
122    pub network_active: bool,
123    pub networks: Vec<GetNetworkInfoResultNetwork>,
124    #[serde(rename = "relayfee", with = "bitcoin::amount::serde::as_btc")]
125    pub relay_fee: Amount,
126    #[serde(rename = "incrementalfee", with = "bitcoin::amount::serde::as_btc")]
127    pub incremental_fee: Amount,
128    #[serde(rename = "localaddresses")]
129    pub local_addresses: Vec<GetNetworkInfoResultAddress>,
130    pub warnings: StringOrStringArray,
131}
132
133#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
134#[serde(rename_all = "camelCase")]
135pub struct AddMultiSigAddressResult {
136    pub address: Address<NetworkUnchecked>,
137    pub redeem_script: ScriptBuf,
138}
139
140#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
141pub struct LoadWalletResult {
142    pub name: String,
143    pub warning: Option<String>,
144}
145
146#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
147pub struct UnloadWalletResult {
148    pub warning: Option<String>,
149}
150
151#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
152pub struct ListWalletDirResult {
153    pub wallets: Vec<ListWalletDirItem>,
154}
155
156#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
157pub struct ListWalletDirItem {
158    pub name: String,
159}
160
161#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
162pub struct GetWalletInfoResult {
163    #[serde(rename = "walletname")]
164    pub wallet_name: String,
165    #[serde(rename = "walletversion")]
166    pub wallet_version: u32,
167    #[serde(with = "bitcoin::amount::serde::as_btc")]
168    pub balance: Amount,
169    #[serde(with = "bitcoin::amount::serde::as_btc")]
170    pub unconfirmed_balance: Amount,
171    #[serde(with = "bitcoin::amount::serde::as_btc")]
172    pub immature_balance: Amount,
173    #[serde(rename = "txcount")]
174    pub tx_count: usize,
175    #[serde(rename = "keypoololdest")]
176    pub keypool_oldest: Option<usize>,
177    #[serde(rename = "keypoolsize")]
178    pub keypool_size: usize,
179    #[serde(rename = "keypoolsize_hd_internal")]
180    pub keypool_size_hd_internal: usize,
181    pub unlocked_until: Option<u64>,
182    #[serde(rename = "paytxfee", with = "bitcoin::amount::serde::as_btc")]
183    pub pay_tx_fee: Amount,
184    #[serde(rename = "hdseedid")]
185    pub hd_seed_id: Option<bitcoin::bip32::XKeyIdentifier>,
186    pub private_keys_enabled: bool,
187    pub avoid_reuse: Option<bool>,
188    pub scanning: Option<ScanningDetails>,
189}
190
191#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
192#[serde(untagged)]
193pub enum ScanningDetails {
194    Scanning {
195        duration: usize,
196        progress: f32,
197    },
198    /// The bool in this field will always be false.
199    NotScanning(bool),
200}
201
202impl Eq for ScanningDetails {}
203
204#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
205#[serde(rename_all = "camelCase")]
206pub struct GetBlockResult {
207    pub hash: bitcoin::BlockHash,
208    pub confirmations: i32,
209    pub size: usize,
210    pub strippedsize: Option<usize>,
211    pub weight: usize,
212    pub height: usize,
213    pub version: i32,
214    #[serde(default, with = "crate::serde_hex::opt")]
215    pub version_hex: Option<Vec<u8>>,
216    pub merkleroot: bitcoin::hash_types::TxMerkleNode,
217    pub tx: Vec<bitcoin::Txid>,
218    pub time: usize,
219    pub mediantime: Option<usize>,
220    pub nonce: u32,
221    pub bits: String,
222    pub difficulty: f64,
223    #[serde(with = "crate::serde_hex")]
224    pub chainwork: Vec<u8>,
225    pub n_tx: usize,
226    pub previousblockhash: Option<bitcoin::BlockHash>,
227    pub nextblockhash: Option<bitcoin::BlockHash>,
228}
229
230#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
231#[serde(rename_all = "camelCase")]
232pub struct GetBlockHeaderResult {
233    pub hash: bitcoin::BlockHash,
234    pub confirmations: i32,
235    pub height: usize,
236    pub version: Version,
237    #[serde(default, with = "crate::serde_hex::opt")]
238    pub version_hex: Option<Vec<u8>>,
239    #[serde(rename = "merkleroot")]
240    pub merkle_root: bitcoin::hash_types::TxMerkleNode,
241    pub time: usize,
242    #[serde(rename = "mediantime")]
243    pub median_time: Option<usize>,
244    pub nonce: u32,
245    pub bits: String,
246    pub difficulty: f64,
247    #[serde(with = "crate::serde_hex")]
248    pub chainwork: Vec<u8>,
249    pub n_tx: usize,
250    #[serde(rename = "previousblockhash")]
251    pub previous_block_hash: Option<bitcoin::BlockHash>,
252    #[serde(rename = "nextblockhash")]
253    pub next_block_hash: Option<bitcoin::BlockHash>,
254}
255
256#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
257pub struct GetBlockStatsResult {
258    #[serde(rename = "avgfee", with = "bitcoin::amount::serde::as_sat")]
259    pub avg_fee: Amount,
260    #[serde(rename = "avgfeerate", with = "bitcoin::amount::serde::as_sat")]
261    pub avg_fee_rate: Amount,
262    #[serde(rename = "avgtxsize")]
263    pub avg_tx_size: u32,
264    #[serde(rename = "blockhash")]
265    pub block_hash: bitcoin::BlockHash,
266    #[serde(rename = "feerate_percentiles")]
267    pub fee_rate_percentiles: FeeRatePercentiles,
268    pub height: u64,
269    pub ins: usize,
270    #[serde(rename = "maxfee", with = "bitcoin::amount::serde::as_sat")]
271    pub max_fee: Amount,
272    #[serde(rename = "maxfeerate", with = "bitcoin::amount::serde::as_sat")]
273    pub max_fee_rate: Amount,
274    #[serde(rename = "maxtxsize")]
275    pub max_tx_size: u32,
276    #[serde(rename = "medianfee", with = "bitcoin::amount::serde::as_sat")]
277    pub median_fee: Amount,
278    #[serde(rename = "mediantime")]
279    pub median_time: u64,
280    #[serde(rename = "mediantxsize")]
281    pub median_tx_size: u32,
282    #[serde(rename = "minfee", with = "bitcoin::amount::serde::as_sat")]
283    pub min_fee: Amount,
284    #[serde(rename = "minfeerate", with = "bitcoin::amount::serde::as_sat")]
285    pub min_fee_rate: Amount,
286    #[serde(rename = "mintxsize")]
287    pub min_tx_size: u32,
288    pub outs: usize,
289    #[serde(with = "bitcoin::amount::serde::as_sat")]
290    pub subsidy: Amount,
291    #[serde(rename = "swtotal_size")]
292    pub sw_total_size: usize,
293    #[serde(rename = "swtotal_weight")]
294    pub sw_total_weight: usize,
295    #[serde(rename = "swtxs")]
296    pub sw_txs: usize,
297    pub time: u64,
298    #[serde(with = "bitcoin::amount::serde::as_sat")]
299    pub total_out: Amount,
300    pub total_size: usize,
301    pub total_weight: usize,
302    #[serde(rename = "totalfee", with = "bitcoin::amount::serde::as_sat")]
303    pub total_fee: Amount,
304    pub txs: usize,
305    pub utxo_increase: i32,
306    pub utxo_size_inc: i32,
307}
308
309#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
310pub struct GetBlockStatsResultPartial {
311    #[serde(
312        default,
313        rename = "avgfee",
314        with = "bitcoin::amount::serde::as_sat::opt",
315        skip_serializing_if = "Option::is_none"
316    )]
317    pub avg_fee: Option<Amount>,
318    #[serde(
319        default,
320        rename = "avgfeerate",
321        with = "bitcoin::amount::serde::as_sat::opt",
322        skip_serializing_if = "Option::is_none"
323    )]
324    pub avg_fee_rate: Option<Amount>,
325    #[serde(default, rename = "avgtxsize", skip_serializing_if = "Option::is_none")]
326    pub avg_tx_size: Option<u32>,
327    #[serde(default, rename = "blockhash", skip_serializing_if = "Option::is_none")]
328    pub block_hash: Option<bitcoin::BlockHash>,
329    #[serde(default, rename = "feerate_percentiles", skip_serializing_if = "Option::is_none")]
330    pub fee_rate_percentiles: Option<FeeRatePercentiles>,
331    #[serde(default, skip_serializing_if = "Option::is_none")]
332    pub height: Option<u64>,
333    #[serde(default, skip_serializing_if = "Option::is_none")]
334    pub ins: Option<usize>,
335    #[serde(
336        default,
337        rename = "maxfee",
338        with = "bitcoin::amount::serde::as_sat::opt",
339        skip_serializing_if = "Option::is_none"
340    )]
341    pub max_fee: Option<Amount>,
342    #[serde(
343        default,
344        rename = "maxfeerate",
345        with = "bitcoin::amount::serde::as_sat::opt",
346        skip_serializing_if = "Option::is_none"
347    )]
348    pub max_fee_rate: Option<Amount>,
349    #[serde(default, rename = "maxtxsize", skip_serializing_if = "Option::is_none")]
350    pub max_tx_size: Option<u32>,
351    #[serde(
352        default,
353        rename = "medianfee",
354        with = "bitcoin::amount::serde::as_sat::opt",
355        skip_serializing_if = "Option::is_none"
356    )]
357    pub median_fee: Option<Amount>,
358    #[serde(default, rename = "mediantime", skip_serializing_if = "Option::is_none")]
359    pub median_time: Option<u64>,
360    #[serde(default, rename = "mediantxsize", skip_serializing_if = "Option::is_none")]
361    pub median_tx_size: Option<u32>,
362    #[serde(
363        default,
364        rename = "minfee",
365        with = "bitcoin::amount::serde::as_sat::opt",
366        skip_serializing_if = "Option::is_none"
367    )]
368    pub min_fee: Option<Amount>,
369    #[serde(
370        default,
371        rename = "minfeerate",
372        with = "bitcoin::amount::serde::as_sat::opt",
373        skip_serializing_if = "Option::is_none"
374    )]
375    pub min_fee_rate: Option<Amount>,
376    #[serde(default, rename = "mintxsize", skip_serializing_if = "Option::is_none")]
377    pub min_tx_size: Option<u32>,
378    #[serde(default, skip_serializing_if = "Option::is_none")]
379    pub outs: Option<usize>,
380    #[serde(
381        default,
382        with = "bitcoin::amount::serde::as_sat::opt",
383        skip_serializing_if = "Option::is_none"
384    )]
385    pub subsidy: Option<Amount>,
386    #[serde(default, rename = "swtotal_size", skip_serializing_if = "Option::is_none")]
387    pub sw_total_size: Option<usize>,
388    #[serde(default, rename = "swtotal_weight", skip_serializing_if = "Option::is_none")]
389    pub sw_total_weight: Option<usize>,
390    #[serde(default, rename = "swtxs", skip_serializing_if = "Option::is_none")]
391    pub sw_txs: Option<usize>,
392    #[serde(default, skip_serializing_if = "Option::is_none")]
393    pub time: Option<u64>,
394    #[serde(
395        default,
396        with = "bitcoin::amount::serde::as_sat::opt",
397        skip_serializing_if = "Option::is_none"
398    )]
399    pub total_out: Option<Amount>,
400    #[serde(default, skip_serializing_if = "Option::is_none")]
401    pub total_size: Option<usize>,
402    #[serde(default, skip_serializing_if = "Option::is_none")]
403    pub total_weight: Option<usize>,
404    #[serde(
405        default,
406        rename = "totalfee",
407        with = "bitcoin::amount::serde::as_sat::opt",
408        skip_serializing_if = "Option::is_none"
409    )]
410    pub total_fee: Option<Amount>,
411    #[serde(default, skip_serializing_if = "Option::is_none")]
412    pub txs: Option<usize>,
413    #[serde(default, skip_serializing_if = "Option::is_none")]
414    pub utxo_increase: Option<i32>,
415    #[serde(default, skip_serializing_if = "Option::is_none")]
416    pub utxo_size_inc: Option<i32>,
417}
418
419#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
420pub struct FeeRatePercentiles {
421    #[serde(with = "bitcoin::amount::serde::as_sat")]
422    pub fr_10th: Amount,
423    #[serde(with = "bitcoin::amount::serde::as_sat")]
424    pub fr_25th: Amount,
425    #[serde(with = "bitcoin::amount::serde::as_sat")]
426    pub fr_50th: Amount,
427    #[serde(with = "bitcoin::amount::serde::as_sat")]
428    pub fr_75th: Amount,
429    #[serde(with = "bitcoin::amount::serde::as_sat")]
430    pub fr_90th: Amount,
431}
432
433#[derive(Clone)]
434pub enum BlockStatsFields {
435    AverageFee,
436    AverageFeeRate,
437    AverageTxSize,
438    BlockHash,
439    FeeRatePercentiles,
440    Height,
441    Ins,
442    MaxFee,
443    MaxFeeRate,
444    MaxTxSize,
445    MedianFee,
446    MedianTime,
447    MedianTxSize,
448    MinFee,
449    MinFeeRate,
450    MinTxSize,
451    Outs,
452    Subsidy,
453    SegWitTotalSize,
454    SegWitTotalWeight,
455    SegWitTxs,
456    Time,
457    TotalOut,
458    TotalSize,
459    TotalWeight,
460    TotalFee,
461    Txs,
462    UtxoIncrease,
463    UtxoSizeIncrease,
464}
465
466impl BlockStatsFields {
467    fn get_rpc_keyword(&self) -> &str {
468        match *self {
469            BlockStatsFields::AverageFee => "avgfee",
470            BlockStatsFields::AverageFeeRate => "avgfeerate",
471            BlockStatsFields::AverageTxSize => "avgtxsize",
472            BlockStatsFields::BlockHash => "blockhash",
473            BlockStatsFields::FeeRatePercentiles => "feerate_percentiles",
474            BlockStatsFields::Height => "height",
475            BlockStatsFields::Ins => "ins",
476            BlockStatsFields::MaxFee => "maxfee",
477            BlockStatsFields::MaxFeeRate => "maxfeerate",
478            BlockStatsFields::MaxTxSize => "maxtxsize",
479            BlockStatsFields::MedianFee => "medianfee",
480            BlockStatsFields::MedianTime => "mediantime",
481            BlockStatsFields::MedianTxSize => "mediantxsize",
482            BlockStatsFields::MinFee => "minfee",
483            BlockStatsFields::MinFeeRate => "minfeerate",
484            BlockStatsFields::MinTxSize => "minfeerate",
485            BlockStatsFields::Outs => "outs",
486            BlockStatsFields::Subsidy => "subsidy",
487            BlockStatsFields::SegWitTotalSize => "swtotal_size",
488            BlockStatsFields::SegWitTotalWeight => "swtotal_weight",
489            BlockStatsFields::SegWitTxs => "swtxs",
490            BlockStatsFields::Time => "time",
491            BlockStatsFields::TotalOut => "total_out",
492            BlockStatsFields::TotalSize => "total_size",
493            BlockStatsFields::TotalWeight => "total_weight",
494            BlockStatsFields::TotalFee => "totalfee",
495            BlockStatsFields::Txs => "txs",
496            BlockStatsFields::UtxoIncrease => "utxo_increase",
497            BlockStatsFields::UtxoSizeIncrease => "utxo_size_inc",
498        }
499    }
500}
501
502impl fmt::Display for BlockStatsFields {
503    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
504        write!(f, "{}", self.get_rpc_keyword())
505    }
506}
507
508impl From<BlockStatsFields> for serde_json::Value {
509    fn from(bsf: BlockStatsFields) -> Self {
510        Self::from(bsf.to_string())
511    }
512}
513
514#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
515#[serde(rename_all = "camelCase")]
516pub struct GetMiningInfoResult {
517    pub blocks: u32,
518    #[serde(rename = "currentblockweight")]
519    pub current_block_weight: Option<u64>,
520    #[serde(rename = "currentblocktx")]
521    pub current_block_tx: Option<usize>,
522    pub difficulty: f64,
523    #[serde(rename = "networkhashps")]
524    pub network_hash_ps: f64,
525    #[serde(rename = "pooledtx")]
526    pub pooled_tx: usize,
527    #[serde(deserialize_with = "deserialize_bip70_network")]
528    pub chain: Network,
529    pub warnings: StringOrStringArray,
530}
531
532#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
533#[serde(rename_all = "camelCase")]
534pub struct GetRawTransactionResultVinScriptSig {
535    pub asm: String,
536    #[serde(with = "crate::serde_hex")]
537    pub hex: Vec<u8>,
538}
539
540impl GetRawTransactionResultVinScriptSig {
541    pub fn script(&self) -> Result<ScriptBuf, encode::Error> {
542        Ok(ScriptBuf::from(self.hex.clone()))
543    }
544}
545
546#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
547#[serde(rename_all = "camelCase")]
548pub struct GetRawTransactionResultVin {
549    pub sequence: u32,
550    /// The raw scriptSig in case of a coinbase tx.
551    #[serde(default, with = "crate::serde_hex::opt")]
552    pub coinbase: Option<Vec<u8>>,
553    /// Not provided for coinbase txs.
554    pub txid: Option<bitcoin::Txid>,
555    /// Not provided for coinbase txs.
556    pub vout: Option<u32>,
557    /// The scriptSig in case of a non-coinbase tx.
558    pub script_sig: Option<GetRawTransactionResultVinScriptSig>,
559    /// Not provided for coinbase txs.
560    #[serde(default, deserialize_with = "deserialize_hex_array_opt")]
561    pub txinwitness: Option<Vec<Vec<u8>>>,
562}
563
564impl GetRawTransactionResultVin {
565    /// Whether this input is from a coinbase tx.
566    /// The [txid], [vout] and [script_sig] fields are not provided
567    /// for coinbase transactions.
568    pub fn is_coinbase(&self) -> bool {
569        self.coinbase.is_some()
570    }
571}
572
573#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
574#[serde(rename_all = "camelCase")]
575pub struct GetRawTransactionResultVoutScriptPubKey {
576    pub asm: String,
577    #[serde(with = "crate::serde_hex")]
578    pub hex: Vec<u8>,
579    pub req_sigs: Option<usize>,
580    #[serde(rename = "type")]
581    pub type_: Option<ScriptPubkeyType>,
582    // Deprecated in Bitcoin Core 22
583    #[serde(default)]
584    pub addresses: Vec<Address<NetworkUnchecked>>,
585    // Added in Bitcoin Core 22
586    #[serde(default)]
587    pub address: Option<Address<NetworkUnchecked>>,
588}
589
590impl GetRawTransactionResultVoutScriptPubKey {
591    pub fn script(&self) -> Result<ScriptBuf, encode::Error> {
592        Ok(ScriptBuf::from(self.hex.clone()))
593    }
594}
595
596#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
597#[serde(rename_all = "camelCase")]
598pub struct GetRawTransactionResultVout {
599    #[serde(with = "bitcoin::amount::serde::as_btc")]
600    pub value: Amount,
601    pub n: u32,
602    pub script_pub_key: GetRawTransactionResultVoutScriptPubKey,
603}
604
605#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
606#[serde(rename_all = "camelCase")]
607pub struct GetRawTransactionResult {
608    #[serde(rename = "in_active_chain")]
609    pub in_active_chain: Option<bool>,
610    #[serde(with = "crate::serde_hex")]
611    pub hex: Vec<u8>,
612    pub txid: bitcoin::Txid,
613    pub hash: bitcoin::Wtxid,
614    pub size: usize,
615    pub vsize: usize,
616    pub version: u32,
617    pub locktime: u32,
618    pub vin: Vec<GetRawTransactionResultVin>,
619    pub vout: Vec<GetRawTransactionResultVout>,
620    pub blockhash: Option<bitcoin::BlockHash>,
621    pub confirmations: Option<u32>,
622    pub time: Option<usize>,
623    pub blocktime: Option<usize>,
624}
625
626#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
627pub struct GetBlockFilterResult {
628    pub header: bitcoin::hash_types::FilterHash,
629    #[serde(with = "crate::serde_hex")]
630    pub filter: Vec<u8>,
631}
632
633impl GetBlockFilterResult {
634    /// Get the filter.
635    /// Note that this copies the underlying filter data. To prevent this,
636    /// use [into_filter] instead.
637    pub fn to_filter(&self) -> bip158::BlockFilter {
638        bip158::BlockFilter::new(&self.filter)
639    }
640
641    /// Convert the result in the filter type.
642    pub fn into_filter(self) -> bip158::BlockFilter {
643        bip158::BlockFilter {
644            content: self.filter,
645        }
646    }
647}
648
649impl GetRawTransactionResult {
650    /// Whether this tx is a coinbase tx.
651    pub fn is_coinbase(&self) -> bool {
652        self.vin.len() == 1 && self.vin[0].is_coinbase()
653    }
654
655    pub fn transaction(&self) -> Result<Transaction, encode::Error> {
656        Ok(encode::deserialize(&self.hex)?)
657    }
658}
659
660/// Enum to represent the BIP125 replaceable status for a transaction.
661#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
662#[serde(rename_all = "lowercase")]
663pub enum Bip125Replaceable {
664    Yes,
665    No,
666    Unknown,
667}
668
669/// Enum to represent the category of a transaction.
670#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
671#[serde(rename_all = "lowercase")]
672pub enum GetTransactionResultDetailCategory {
673    Send,
674    Receive,
675    Generate,
676    Immature,
677    Orphan,
678}
679
680#[derive(Clone, PartialEq, Eq, Debug, Deserialize)]
681pub struct GetTransactionResultDetail {
682    pub address: Option<Address<NetworkUnchecked>>,
683    pub category: GetTransactionResultDetailCategory,
684    #[serde(with = "bitcoin::amount::serde::as_btc")]
685    pub amount: SignedAmount,
686    pub label: Option<String>,
687    pub vout: u32,
688    #[serde(default, with = "bitcoin::amount::serde::as_btc::opt")]
689    pub fee: Option<SignedAmount>,
690    pub abandoned: Option<bool>,
691}
692
693#[derive(Clone, PartialEq, Eq, Debug, Deserialize)]
694pub struct WalletTxInfo {
695    pub confirmations: i32,
696    pub blockhash: Option<bitcoin::BlockHash>,
697    pub blockindex: Option<usize>,
698    pub blocktime: Option<u64>,
699    pub blockheight: Option<u32>,
700    pub txid: bitcoin::Txid,
701    pub time: u64,
702    pub timereceived: u64,
703    #[serde(rename = "bip125-replaceable")]
704    pub bip125_replaceable: Bip125Replaceable,
705    /// Conflicting transaction ids
706    #[serde(rename = "walletconflicts")]
707    pub wallet_conflicts: Vec<bitcoin::Txid>,
708}
709
710#[derive(Clone, PartialEq, Eq, Debug, Deserialize)]
711pub struct GetTransactionResult {
712    #[serde(flatten)]
713    pub info: WalletTxInfo,
714    #[serde(with = "bitcoin::amount::serde::as_btc")]
715    pub amount: SignedAmount,
716    #[serde(default, with = "bitcoin::amount::serde::as_btc::opt")]
717    pub fee: Option<SignedAmount>,
718    pub details: Vec<GetTransactionResultDetail>,
719    #[serde(with = "crate::serde_hex")]
720    pub hex: Vec<u8>,
721}
722
723impl GetTransactionResult {
724    pub fn transaction(&self) -> Result<Transaction, encode::Error> {
725        Ok(encode::deserialize(&self.hex)?)
726    }
727}
728
729#[derive(Clone, PartialEq, Eq, Debug, Deserialize)]
730pub struct ListTransactionResult {
731    #[serde(flatten)]
732    pub info: WalletTxInfo,
733    #[serde(flatten)]
734    pub detail: GetTransactionResultDetail,
735
736    pub trusted: Option<bool>,
737    pub comment: Option<String>,
738}
739
740#[derive(Clone, PartialEq, Eq, Debug, Deserialize)]
741pub struct ListSinceBlockResult {
742    pub transactions: Vec<ListTransactionResult>,
743    #[serde(default)]
744    pub removed: Vec<ListTransactionResult>,
745    pub lastblock: bitcoin::BlockHash,
746}
747
748#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
749#[serde(rename_all = "camelCase")]
750pub struct GetTxOutResult {
751    pub bestblock: bitcoin::BlockHash,
752    pub confirmations: u32,
753    #[serde(with = "bitcoin::amount::serde::as_btc")]
754    pub value: Amount,
755    pub script_pub_key: GetRawTransactionResultVoutScriptPubKey,
756    pub coinbase: bool,
757}
758
759#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize, Default)]
760#[serde(rename_all = "camelCase")]
761pub struct ListUnspentQueryOptions {
762    #[serde(
763        rename = "minimumAmount",
764        with = "bitcoin::amount::serde::as_btc::opt",
765        skip_serializing_if = "Option::is_none"
766    )]
767    pub minimum_amount: Option<Amount>,
768    #[serde(
769        rename = "maximumAmount",
770        with = "bitcoin::amount::serde::as_btc::opt",
771        skip_serializing_if = "Option::is_none"
772    )]
773    pub maximum_amount: Option<Amount>,
774    #[serde(rename = "maximumCount", skip_serializing_if = "Option::is_none")]
775    pub maximum_count: Option<usize>,
776    #[serde(
777        rename = "minimumSumAmount",
778        with = "bitcoin::amount::serde::as_btc::opt",
779        skip_serializing_if = "Option::is_none"
780    )]
781    pub minimum_sum_amount: Option<Amount>,
782}
783
784#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
785#[serde(rename_all = "camelCase")]
786pub struct ListUnspentResultEntry {
787    pub txid: bitcoin::Txid,
788    pub vout: u32,
789    pub address: Option<Address<NetworkUnchecked>>,
790    pub label: Option<String>,
791    pub redeem_script: Option<ScriptBuf>,
792    pub witness_script: Option<ScriptBuf>,
793    pub script_pub_key: ScriptBuf,
794    #[serde(with = "bitcoin::amount::serde::as_btc")]
795    pub amount: Amount,
796    pub confirmations: u32,
797    pub spendable: bool,
798    pub solvable: bool,
799    #[serde(rename = "desc")]
800    pub descriptor: Option<String>,
801    pub safe: bool,
802}
803
804#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
805#[serde(rename_all = "camelCase")]
806pub struct ListReceivedByAddressResult {
807    #[serde(default, rename = "involvesWatchonly")]
808    pub involved_watch_only: bool,
809    pub address: Address<NetworkUnchecked>,
810    #[serde(with = "bitcoin::amount::serde::as_btc")]
811    pub amount: Amount,
812    pub confirmations: u32,
813    pub label: String,
814    pub txids: Vec<bitcoin::Txid>,
815}
816
817#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
818#[serde(rename_all = "camelCase")]
819pub struct SignRawTransactionResultError {
820    pub txid: bitcoin::Txid,
821    pub vout: u32,
822    pub script_sig: ScriptBuf,
823    pub sequence: u32,
824    pub error: String,
825}
826
827#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
828#[serde(rename_all = "camelCase")]
829pub struct SignRawTransactionResult {
830    #[serde(with = "crate::serde_hex")]
831    pub hex: Vec<u8>,
832    pub complete: bool,
833    pub errors: Option<Vec<SignRawTransactionResultError>>,
834}
835
836impl SignRawTransactionResult {
837    pub fn transaction(&self) -> Result<Transaction, encode::Error> {
838        Ok(encode::deserialize(&self.hex)?)
839    }
840}
841
842#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
843pub struct TestMempoolAcceptResult {
844    pub txid: bitcoin::Txid,
845    pub allowed: bool,
846    #[serde(rename = "reject-reason")]
847    pub reject_reason: Option<String>,
848    /// Virtual transaction size as defined in BIP 141 (only present when 'allowed' is true)
849    /// Added in Bitcoin Core v0.21
850    pub vsize: Option<u64>,
851    /// Transaction fees (only present if 'allowed' is true)
852    /// Added in Bitcoin Core v0.21
853    pub fees: Option<TestMempoolAcceptResultFees>,
854}
855
856#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
857pub struct TestMempoolAcceptResultFees {
858    /// Transaction fee in BTC
859    #[serde(with = "bitcoin::amount::serde::as_btc")]
860    pub base: Amount,
861    // unlike GetMempoolEntryResultFees, this only has the `base` fee
862}
863
864#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
865#[serde(rename_all = "snake_case")]
866pub enum Bip9SoftforkStatus {
867    Defined,
868    Started,
869    LockedIn,
870    Active,
871    Failed,
872}
873
874#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
875pub struct Bip9SoftforkStatistics {
876    pub period: u32,
877    pub threshold: Option<u32>,
878    pub elapsed: u32,
879    pub count: u32,
880    pub possible: Option<bool>,
881}
882
883#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
884pub struct Bip9SoftforkInfo {
885    pub status: Bip9SoftforkStatus,
886    pub bit: Option<u8>,
887    // Can be -1 for 0.18.x inactive ones.
888    pub start_time: i64,
889    pub timeout: u64,
890    pub since: u32,
891    pub statistics: Option<Bip9SoftforkStatistics>,
892}
893
894#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
895#[serde(rename_all = "lowercase")]
896pub enum SoftforkType {
897    Buried,
898    Bip9,
899    #[serde(other)]
900    Other,
901}
902
903/// Status of a softfork
904#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
905pub struct Softfork {
906    #[serde(rename = "type")]
907    pub type_: SoftforkType,
908    pub bip9: Option<Bip9SoftforkInfo>,
909    pub height: Option<u32>,
910    pub active: bool,
911}
912
913#[allow(non_camel_case_types)]
914#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
915#[serde(rename_all = "lowercase")]
916pub enum ScriptPubkeyType {
917    Nonstandard,
918    Pubkey,
919    PubkeyHash,
920    ScriptHash,
921    MultiSig,
922    NullData,
923    Witness_v0_KeyHash,
924    Witness_v0_ScriptHash,
925    Witness_v1_Taproot,
926    Witness_Unknown,
927}
928
929#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
930pub struct GetAddressInfoResultEmbedded {
931    pub address: Address<NetworkUnchecked>,
932    #[serde(rename = "scriptPubKey")]
933    pub script_pub_key: ScriptBuf,
934    #[serde(rename = "is_script")]
935    pub is_script: Option<bool>,
936    #[serde(rename = "is_witness")]
937    pub is_witness: Option<bool>,
938    pub witness_version: Option<u32>,
939    #[serde(with = "crate::serde_hex")]
940    pub witness_program: Vec<u8>,
941    pub script: Option<ScriptPubkeyType>,
942    /// The redeemscript for the p2sh address.
943    #[serde(default, with = "crate::serde_hex::opt")]
944    pub hex: Option<Vec<u8>>,
945    pub pubkeys: Option<Vec<PublicKey>>,
946    #[serde(rename = "sigsrequired")]
947    pub n_signatures_required: Option<usize>,
948    pub pubkey: Option<PublicKey>,
949    #[serde(rename = "is_compressed")]
950    pub is_compressed: Option<bool>,
951    pub label: Option<String>,
952    #[serde(rename = "hdkeypath")]
953    pub hd_key_path: Option<bip32::DerivationPath>,
954    #[serde(rename = "hdseedid")]
955    pub hd_seed_id: Option<bitcoin::bip32::XKeyIdentifier>,
956    #[serde(default)]
957    pub labels: Vec<GetAddressInfoResultLabel>,
958}
959
960#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
961#[serde(rename_all = "lowercase")]
962pub enum GetAddressInfoResultLabelPurpose {
963    Send,
964    Receive,
965}
966
967#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
968#[serde(untagged)]
969pub enum GetAddressInfoResultLabel {
970    Simple(String),
971    WithPurpose {
972        name: String,
973        purpose: GetAddressInfoResultLabelPurpose,
974    },
975}
976
977#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
978pub struct GetAddressInfoResult {
979    pub address: Address<NetworkUnchecked>,
980    #[serde(rename = "scriptPubKey")]
981    pub script_pub_key: ScriptBuf,
982    #[serde(rename = "ismine")]
983    pub is_mine: Option<bool>,
984    #[serde(rename = "iswatchonly")]
985    pub is_watchonly: Option<bool>,
986    #[serde(rename = "isscript")]
987    pub is_script: Option<bool>,
988    #[serde(rename = "iswitness")]
989    pub is_witness: Option<bool>,
990    pub witness_version: Option<u32>,
991    #[serde(default, with = "crate::serde_hex::opt")]
992    pub witness_program: Option<Vec<u8>>,
993    pub script: Option<ScriptPubkeyType>,
994    /// The redeemscript for the p2sh address.
995    #[serde(default, with = "crate::serde_hex::opt")]
996    pub hex: Option<Vec<u8>>,
997    pub pubkeys: Option<Vec<PublicKey>>,
998    #[serde(rename = "sigsrequired")]
999    pub n_signatures_required: Option<usize>,
1000    pub pubkey: Option<PublicKey>,
1001    /// Information about the address embedded in P2SH or P2WSH, if relevant and known.
1002    pub embedded: Option<GetAddressInfoResultEmbedded>,
1003    #[serde(rename = "is_compressed")]
1004    pub is_compressed: Option<bool>,
1005    pub timestamp: Option<u64>,
1006    #[serde(rename = "hdkeypath")]
1007    pub hd_key_path: Option<bip32::DerivationPath>,
1008    #[serde(rename = "hdseedid")]
1009    pub hd_seed_id: Option<bitcoin::bip32::XKeyIdentifier>,
1010    pub labels: Vec<GetAddressInfoResultLabel>,
1011    /// Deprecated in v0.20.0. See `labels` field instead.
1012    #[deprecated(note = "since Core v0.20.0")]
1013    pub label: Option<String>,
1014}
1015
1016/// Models the result of "getblockchaininfo"
1017#[derive(Clone, Debug, Deserialize, Serialize)]
1018pub struct GetBlockchainInfoResult {
1019    /// Current network name as defined in BIP70 (main, test, signet, regtest)
1020    #[serde(deserialize_with = "deserialize_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.
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)]
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    #[serde(with = "bitcoin::amount::serde::as_btc::opt", skip_serializing_if = "Option::is_none")]
1891    pub fee_rate: Option<Amount>,
1892    #[serde(skip_serializing_if = "Option::is_none")]
1893    pub subtract_fee_from_outputs: Option<Vec<u32>>,
1894    #[serde(skip_serializing_if = "Option::is_none")]
1895    pub replaceable: Option<bool>,
1896    #[serde(rename = "conf_target", skip_serializing_if = "Option::is_none")]
1897    pub conf_target: Option<u32>,
1898    #[serde(rename = "estimate_mode", skip_serializing_if = "Option::is_none")]
1899    pub estimate_mode: Option<EstimateMode>,
1900}
1901
1902#[derive(Deserialize, Clone, PartialEq, Eq, Debug)]
1903#[serde(rename_all = "camelCase")]
1904pub struct FundRawTransactionResult {
1905    #[serde(with = "crate::serde_hex")]
1906    pub hex: Vec<u8>,
1907    #[serde(with = "bitcoin::amount::serde::as_btc")]
1908    pub fee: Amount,
1909    #[serde(rename = "changepos")]
1910    pub change_position: i32,
1911}
1912
1913#[derive(Deserialize, Clone, PartialEq, Eq, Debug)]
1914pub struct GetBalancesResultEntry {
1915    #[serde(with = "bitcoin::amount::serde::as_btc")]
1916    pub trusted: Amount,
1917    #[serde(with = "bitcoin::amount::serde::as_btc")]
1918    pub untrusted_pending: Amount,
1919    #[serde(with = "bitcoin::amount::serde::as_btc")]
1920    pub immature: Amount,
1921}
1922
1923#[derive(Deserialize, Clone, PartialEq, Eq, Debug)]
1924#[serde(rename_all = "camelCase")]
1925pub struct GetBalancesResult {
1926    pub mine: GetBalancesResultEntry,
1927    pub watchonly: Option<GetBalancesResultEntry>,
1928}
1929
1930impl FundRawTransactionResult {
1931    pub fn transaction(&self) -> Result<Transaction, encode::Error> {
1932        encode::deserialize(&self.hex)
1933    }
1934}
1935
1936// Used for signrawtransaction argument.
1937#[derive(Serialize, Clone, PartialEq, Debug)]
1938#[serde(rename_all = "camelCase")]
1939pub struct SignRawTransactionInput {
1940    pub txid: bitcoin::Txid,
1941    pub vout: u32,
1942    pub script_pub_key: ScriptBuf,
1943    #[serde(skip_serializing_if = "Option::is_none")]
1944    pub redeem_script: Option<ScriptBuf>,
1945    #[serde(
1946        default,
1947        skip_serializing_if = "Option::is_none",
1948        with = "bitcoin::amount::serde::as_btc::opt"
1949    )]
1950    pub amount: Option<Amount>,
1951}
1952
1953/// Used to represent UTXO set hash type
1954#[derive(Clone, Serialize, PartialEq, Eq, Debug)]
1955#[serde(rename_all = "snake_case")]
1956pub enum TxOutSetHashType {
1957    HashSerialized2,
1958    Muhash,
1959    None,
1960}
1961
1962/// Used to specify a block hash or a height
1963#[derive(Clone, Serialize, PartialEq, Eq, Debug)]
1964#[serde(untagged)]
1965pub enum HashOrHeight {
1966    BlockHash(bitcoin::BlockHash),
1967    Height(u64),
1968}
1969
1970#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1971pub struct GetTxOutSetInfoResult {
1972    /// The block height (index) of the returned statistics
1973    pub height: u64,
1974    /// The hash of the block at which these statistics are calculated
1975    #[serde(rename = "bestblock")]
1976    pub best_block: bitcoin::BlockHash,
1977    /// The number of transactions with unspent outputs (not available when coinstatsindex is used)
1978    #[serde(default, skip_serializing_if = "Option::is_none")]
1979    pub transactions: Option<u64>,
1980    /// The number of unspent transaction outputs
1981    #[serde(rename = "txouts")]
1982    pub tx_outs: u64,
1983    /// A meaningless metric for UTXO set size
1984    pub bogosize: u64,
1985    /// The serialized hash (only present if 'hash_serialized_2' hash_type is chosen)
1986    #[serde(default, skip_serializing_if = "Option::is_none")]
1987    pub hash_serialized_2: Option<sha256::Hash>,
1988    /// The serialized hash (only present if 'muhash' hash_type is chosen)
1989    #[serde(default, skip_serializing_if = "Option::is_none")]
1990    pub muhash: Option<sha256::Hash>,
1991    /// The estimated size of the chainstate on disk (not available when coinstatsindex is used)
1992    #[serde(default, skip_serializing_if = "Option::is_none")]
1993    pub disk_size: Option<u64>,
1994    /// The total amount
1995    #[serde(with = "bitcoin::amount::serde::as_btc")]
1996    pub total_amount: Amount,
1997    /// The total amount of coins permanently excluded from the UTXO set (only available if coinstatsindex is used)
1998    #[serde(
1999        default,
2000        skip_serializing_if = "Option::is_none",
2001        with = "bitcoin::amount::serde::as_btc::opt"
2002    )]
2003    pub total_unspendable_amount: Option<Amount>,
2004    /// Info on amounts in the block at this block height (only available if coinstatsindex is used)
2005    #[serde(default, skip_serializing_if = "Option::is_none")]
2006    pub block_info: Option<BlockInfo>,
2007}
2008
2009/// Info on amounts in the block at the block height of the `gettxoutsetinfo` call (only available if coinstatsindex is used)
2010#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
2011pub struct BlockInfo {
2012    /// Amount of previous outputs spent
2013    #[serde(with = "bitcoin::amount::serde::as_btc")]
2014    pub prevout_spent: Amount,
2015    /// Output size of the coinbase transaction
2016    #[serde(with = "bitcoin::amount::serde::as_btc")]
2017    pub coinbase: Amount,
2018    /// Newly-created outputs
2019    #[serde(with = "bitcoin::amount::serde::as_btc")]
2020    pub new_outputs_ex_coinbase: Amount,
2021    /// Amount of unspendable outputs
2022    #[serde(with = "bitcoin::amount::serde::as_btc")]
2023    pub unspendable: Amount,
2024    /// Detailed view of the unspendable categories
2025    pub unspendables: Unspendables,
2026}
2027
2028/// Detailed view of the unspendable categories
2029#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
2030pub struct Unspendables {
2031    /// Unspendable coins from the Genesis block
2032    #[serde(with = "bitcoin::amount::serde::as_btc")]
2033    pub genesis_block: Amount,
2034    /// Transactions overridden by duplicates (no longer possible with BIP30)
2035    #[serde(with = "bitcoin::amount::serde::as_btc")]
2036    pub bip30: Amount,
2037    /// Amounts sent to scripts that are unspendable (for example OP_RETURN outputs)
2038    #[serde(with = "bitcoin::amount::serde::as_btc")]
2039    pub scripts: Amount,
2040    /// Fee rewards that miners did not claim in their coinbase transaction
2041    #[serde(with = "bitcoin::amount::serde::as_btc")]
2042    pub unclaimed_rewards: Amount,
2043}
2044
2045#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
2046pub struct GetNetTotalsResult {
2047    /// Total bytes received
2048    #[serde(rename = "totalbytesrecv")]
2049    pub total_bytes_recv: u64,
2050    /// Total bytes sent
2051    #[serde(rename = "totalbytessent")]
2052    pub total_bytes_sent: u64,
2053    /// Current UNIX time in milliseconds
2054    #[serde(rename = "timemillis")]
2055    pub time_millis: u64,
2056    /// Upload target statistics
2057    #[serde(rename = "uploadtarget")]
2058    pub upload_target: GetNetTotalsResultUploadTarget,
2059}
2060
2061#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
2062pub struct GetNetTotalsResultUploadTarget {
2063    /// Length of the measuring timeframe in seconds
2064    #[serde(rename = "timeframe")]
2065    pub time_frame: u64,
2066    /// Target in bytes
2067    pub target: u64,
2068    /// True if target is reached
2069    pub target_reached: bool,
2070    /// True if serving historical blocks
2071    pub serve_historical_blocks: bool,
2072    /// Bytes left in current time cycle
2073    pub bytes_left_in_cycle: u64,
2074    /// Seconds left in current time cycle
2075    pub time_left_in_cycle: u64,
2076}
2077
2078/// Used to represent an address type.
2079#[derive(Copy, Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
2080#[serde(rename_all = "kebab-case")]
2081pub enum AddressType {
2082    Legacy,
2083    P2shSegwit,
2084    Bech32,
2085    Bech32m,
2086}
2087
2088/// Used to represent arguments that can either be an address or a public key.
2089#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
2090pub enum PubKeyOrAddress<'a> {
2091    Address(&'a Address),
2092    PubKey(&'a PublicKey),
2093}
2094
2095#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
2096#[serde(untagged)]
2097/// Start a scan of the UTXO set for an [output descriptor](https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md).
2098pub enum ScanTxOutRequest {
2099    /// Scan for a single descriptor
2100    Single(String),
2101    /// Scan for a descriptor with xpubs
2102    Extended {
2103        /// Descriptor
2104        desc: String,
2105        /// Range of the xpub derivations to scan
2106        range: (u64, u64),
2107    },
2108}
2109
2110#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
2111pub struct ScanTxOutResult {
2112    pub success: Option<bool>,
2113    #[serde(rename = "txouts")]
2114    pub tx_outs: Option<u64>,
2115    pub height: Option<u64>,
2116    #[serde(rename = "bestblock")]
2117    pub best_block_hash: Option<bitcoin::BlockHash>,
2118    pub unspents: Vec<Utxo>,
2119    #[serde(with = "bitcoin::amount::serde::as_btc")]
2120    pub total_amount: bitcoin::Amount,
2121}
2122
2123#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
2124#[serde(rename_all = "camelCase")]
2125pub struct Utxo {
2126    pub txid: bitcoin::Txid,
2127    pub vout: u32,
2128    pub script_pub_key: bitcoin::ScriptBuf,
2129    #[serde(rename = "desc")]
2130    pub descriptor: String,
2131    #[serde(with = "bitcoin::amount::serde::as_btc")]
2132    pub amount: bitcoin::Amount,
2133    pub height: u64,
2134}
2135
2136#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
2137pub struct IndexStatus {
2138    pub synced: bool,
2139    pub best_block_height: u32,
2140}
2141
2142#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
2143pub struct GetIndexInfoResult {
2144    pub txindex: Option<IndexStatus>,
2145    pub coinstatsindex: Option<IndexStatus>,
2146    #[serde(rename = "basic block filter index")]
2147    pub basic_block_filter_index: Option<IndexStatus>,
2148}
2149
2150impl<'a> serde::Serialize for PubKeyOrAddress<'a> {
2151    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
2152    where
2153        S: serde::Serializer,
2154    {
2155        match *self {
2156            PubKeyOrAddress::Address(a) => serde::Serialize::serialize(a, serializer),
2157            PubKeyOrAddress::PubKey(k) => serde::Serialize::serialize(k, serializer),
2158        }
2159    }
2160}
2161
2162// Custom deserializer functions.
2163
2164/// deserialize_hex_array_opt deserializes a vector of hex-encoded byte arrays.
2165fn deserialize_hex_array_opt<'de, D>(deserializer: D) -> Result<Option<Vec<Vec<u8>>>, D::Error>
2166where
2167    D: serde::Deserializer<'de>,
2168{
2169    //TODO(stevenroose) Revisit when issue is fixed:
2170    // https://github.com/serde-rs/serde/issues/723
2171
2172    let v: Vec<String> = Vec::deserialize(deserializer)?;
2173    let mut res = Vec::new();
2174    for h in v.into_iter() {
2175        res.push(FromHex::from_hex(&h).map_err(D::Error::custom)?);
2176    }
2177    Ok(Some(res))
2178}
2179
2180/// deserialize_bip70_network deserializes a Bitcoin Core network according to BIP70
2181/// The accepted input variants are: {"main", "test", "signet", "regtest"}
2182fn deserialize_bip70_network<'de, D>(deserializer: D) -> Result<Network, D::Error>
2183where
2184    D: serde::Deserializer<'de>,
2185{
2186    struct NetworkVisitor;
2187    impl<'de> serde::de::Visitor<'de> for NetworkVisitor {
2188        type Value = Network;
2189
2190        fn visit_str<E: serde::de::Error>(self, s: &str) -> Result<Self::Value, E> {
2191            Network::from_core_arg(s).map_err(|_| {
2192                E::invalid_value(
2193                    serde::de::Unexpected::Str(s),
2194                    &"bitcoin network encoded as a string",
2195                )
2196            })
2197        }
2198
2199        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
2200            write!(formatter, "bitcoin network encoded as a string")
2201        }
2202    }
2203
2204    deserializer.deserialize_str(NetworkVisitor)
2205}
2206
2207#[cfg(test)]
2208mod tests {
2209    use super::*;
2210
2211    #[test]
2212    fn test_softfork_type() {
2213        let buried: SoftforkType = serde_json::from_str("\"buried\"").unwrap();
2214        assert_eq!(buried, SoftforkType::Buried);
2215        let bip9: SoftforkType = serde_json::from_str("\"bip9\"").unwrap();
2216        assert_eq!(bip9, SoftforkType::Bip9);
2217        let other: SoftforkType = serde_json::from_str("\"bip8\"").unwrap();
2218        assert_eq!(other, SoftforkType::Other);
2219    }
2220}