Skip to main content

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