Skip to main content

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