Skip to main content

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