1#![crate_name = "bitgesellcore_rpc_json"]
17#![crate_type = "rlib"]
18
19pub extern crate bitcoin;
20#[allow(unused)]
21#[macro_use] extern crate serde;
23extern crate serde_json;
24
25use std::collections::HashMap;
26
27
28use bitcoin::address::NetworkUnchecked;
29use bitcoin::block::Version;
30use bitcoin::consensus::encode;
31use bitcoin::hashes::hex::FromHex;
32use bitcoin::hashes::sha256;
33use bitcoin::{Address, Amount, PrivateKey, PublicKey, SignedAmount, Transaction, ScriptBuf, Script, bip158, bip32, Network};
34use serde::de::Error as SerdeError;
35use serde::{Deserialize, Serialize};
36use std::fmt;
37
38pub mod serde_hex {
44    use bitcoin::hashes::hex::FromHex;
45    use bitcoin_private::hex::exts::DisplayHex;
46    use serde::de::Error;
47    use serde::{Deserializer, Serializer};
48
49    pub fn serialize<S: Serializer>(b: &Vec<u8>, s: S) -> Result<S::Ok, S::Error> {
50        s.serialize_str(&b.to_lower_hex_string())
51    }
52
53    pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result<Vec<u8>, D::Error> {
54        let hex_str: String = ::serde::Deserialize::deserialize(d)?;
55        Ok(FromHex::from_hex(&hex_str).map_err(D::Error::custom)?)
56    }
57
58    pub mod opt {
59        use bitcoin::hashes::hex::FromHex;
60        use bitcoin_private::hex::exts::DisplayHex;
61        use serde::de::Error;
62        use serde::{Deserializer, Serializer};
63
64        pub fn serialize<S: Serializer>(b: &Option<Vec<u8>>, s: S) -> Result<S::Ok, S::Error> {
65            match *b {
66                None => s.serialize_none(),
67                Some(ref b) => s.serialize_str(&b.to_lower_hex_string()),
68            }
69        }
70
71        pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result<Option<Vec<u8>>, D::Error> {
72            let hex_str: String = ::serde::Deserialize::deserialize(d)?;
73            Ok(Some(FromHex::from_hex(&hex_str).map_err(D::Error::custom)?))
74        }
75    }
76}
77
78#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
79pub struct GetNetworkInfoResultNetwork {
80    pub name: String,
81    pub limited: bool,
82    pub reachable: bool,
83    pub proxy: String,
84    pub proxy_randomize_credentials: bool,
85}
86
87#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
88pub struct GetNetworkInfoResultAddress {
89    pub address: String,
90    pub port: usize,
91    pub score: usize,
92}
93
94#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
95pub struct GetNetworkInfoResult {
96    pub version: usize,
97    pub subversion: String,
98    #[serde(rename = "protocolversion")]
99    pub protocol_version: usize,
100    #[serde(rename = "localservices")]
101    pub local_services: String,
102    #[serde(rename = "localrelay")]
103    pub local_relay: bool,
104    #[serde(rename = "timeoffset")]
105    pub time_offset: isize,
106    pub connections: usize,
107    pub connections_in: Option<usize>,
110    pub connections_out: Option<usize>,
113    #[serde(rename = "networkactive")]
114    pub network_active: bool,
115    pub networks: Vec<GetNetworkInfoResultNetwork>,
116    #[serde(rename = "relayfee", with = "bitcoin::amount::serde::as_btc")]
117    pub relay_fee: Amount,
118    #[serde(rename = "incrementalfee", with = "bitcoin::amount::serde::as_btc")]
119    pub incremental_fee: Amount,
120    #[serde(rename = "localaddresses")]
121    pub local_addresses: Vec<GetNetworkInfoResultAddress>,
122    pub warnings: String,
123}
124
125#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
126#[serde(rename_all = "camelCase")]
127pub struct AddMultiSigAddressResult {
128    pub address: Address<NetworkUnchecked>,
129    pub redeem_script: ScriptBuf,
130}
131
132#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
133pub struct LoadWalletResult {
134    pub name: String,
135    pub warning: Option<String>,
136}
137
138#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
139pub struct UnloadWalletResult {
140    pub warning: Option<String>,
141}
142
143#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
144pub struct ListWalletDirResult {
145    pub wallets: Vec<ListWalletDirItem>,
146}
147
148#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
149pub struct ListWalletDirItem {
150    pub name: String,
151}
152
153#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
154pub struct GetWalletInfoResult {
155    #[serde(rename = "walletname")]
156    pub wallet_name: String,
157    #[serde(rename = "walletversion")]
158    pub wallet_version: u32,
159    #[serde(with = "bitcoin::amount::serde::as_btc")]
160    pub balance: Amount,
161    #[serde(with = "bitcoin::amount::serde::as_btc")]
162    pub unconfirmed_balance: Amount,
163    #[serde(with = "bitcoin::amount::serde::as_btc")]
164    pub immature_balance: Amount,
165    #[serde(rename = "txcount")]
166    pub tx_count: usize,
167    #[serde(rename = "keypoololdest")]
168    pub keypool_oldest: Option<usize>,
169    #[serde(rename = "keypoolsize")]
170    pub keypool_size: usize,
171    #[serde(rename = "keypoolsize_hd_internal")]
172    pub keypool_size_hd_internal: usize,
173    pub unlocked_until: Option<u64>,
174    #[serde(rename = "paytxfee", with = "bitcoin::amount::serde::as_btc")]
175    pub pay_tx_fee: Amount,
176    #[serde(rename = "hdseedid")]
177    pub hd_seed_id: Option<bitcoin::hash_types::XpubIdentifier>,
178    pub private_keys_enabled: bool,
179    pub avoid_reuse: Option<bool>,
180    pub scanning: Option<ScanningDetails>,
181}
182
183#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
184#[serde(untagged)]
185pub enum ScanningDetails {
186    Scanning {
187        duration: usize,
188        progress: f32,
189    },
190    NotScanning(bool),
192}
193
194impl Eq for ScanningDetails {}
195
196#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
197#[serde(rename_all = "camelCase")]
198pub struct GetBlockResult {
199    pub hash: bitcoin::BlockHash,
200    pub confirmations: i32,
201    pub size: usize,
202    pub strippedsize: Option<usize>,
203    pub weight: usize,
204    pub height: usize,
205    pub version: i32,
206    #[serde(default, with = "crate::serde_hex::opt")]
207    pub version_hex: Option<Vec<u8>>,
208    pub merkleroot: bitcoin::hash_types::TxMerkleNode,
209    pub tx: Vec<bitcoin::Txid>,
210    pub time: usize,
211    pub mediantime: Option<usize>,
212    pub nonce: u32,
213    pub bits: String,
214    pub difficulty: f64,
215    #[serde(with = "crate::serde_hex")]
216    pub chainwork: Vec<u8>,
217    pub n_tx: usize,
218    pub previousblockhash: Option<bitcoin::BlockHash>,
219    pub nextblockhash: Option<bitcoin::BlockHash>,
220}
221
222#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
223#[serde(rename_all = "camelCase")]
224pub struct GetBlockHeaderResult {
225    pub hash: bitcoin::BlockHash,
226    pub confirmations: i32,
227    pub height: usize,
228    pub version: Version,
229    #[serde(default, with = "crate::serde_hex::opt")]
230    pub version_hex: Option<Vec<u8>>,
231    #[serde(rename = "merkleroot")]
232    pub merkle_root: bitcoin::hash_types::TxMerkleNode,
233    pub time: usize,
234    #[serde(rename = "mediantime")]
235    pub median_time: Option<usize>,
236    pub nonce: u32,
237    pub bits: String,
238    pub difficulty: f64,
239    #[serde(with = "crate::serde_hex")]
240    pub chainwork: Vec<u8>,
241    pub n_tx: usize,
242    #[serde(rename = "previousblockhash")]
243    pub previous_block_hash: Option<bitcoin::BlockHash>,
244    #[serde(rename = "nextblockhash")]
245    pub next_block_hash: Option<bitcoin::BlockHash>,
246}
247
248#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
249pub struct GetBlockStatsResult {
250    #[serde(rename = "avgfee", with = "bitcoin::amount::serde::as_sat")]
251    pub avg_fee: Amount,
252    #[serde(rename = "avgfeerate", with = "bitcoin::amount::serde::as_sat")]
253    pub avg_fee_rate: Amount,
254    #[serde(rename = "avgtxsize")]
255    pub avg_tx_size: u32,
256    #[serde(rename = "blockhash")]
257    pub block_hash: bitcoin::BlockHash,
258    #[serde(rename = "feerate_percentiles")]
259    pub fee_rate_percentiles: FeeRatePercentiles,
260    pub height: u64,
261    pub ins: usize,
262    #[serde(rename = "maxfee", with = "bitcoin::amount::serde::as_sat")]
263    pub max_fee: Amount,
264    #[serde(rename = "maxfeerate", with = "bitcoin::amount::serde::as_sat")]
265    pub max_fee_rate: Amount,
266    #[serde(rename = "maxtxsize")]
267    pub max_tx_size: u32,
268    #[serde(rename = "medianfee", with = "bitcoin::amount::serde::as_sat")]
269    pub median_fee: Amount,
270    #[serde(rename = "mediantime")]
271    pub median_time: u64,
272    #[serde(rename = "mediantxsize")]
273    pub median_tx_size: u32,
274    #[serde(rename = "minfee", with = "bitcoin::amount::serde::as_sat")]
275    pub min_fee: Amount,
276    #[serde(rename = "minfeerate", with = "bitcoin::amount::serde::as_sat")]
277    pub min_fee_rate: Amount,
278    #[serde(rename = "mintxsize")]
279    pub min_tx_size: u32,
280    pub outs: usize,
281    #[serde(with = "bitcoin::amount::serde::as_sat")]
282    pub subsidy: Amount,
283    #[serde(rename = "swtotal_size")]
284    pub sw_total_size: usize,
285    #[serde(rename = "swtotal_weight")]
286    pub sw_total_weight: usize,
287    #[serde(rename = "swtxs")]
288    pub sw_txs: usize,
289    pub time: u64,
290    #[serde(with = "bitcoin::amount::serde::as_sat")]
291    pub total_out: Amount,
292    pub total_size: usize,
293    pub total_weight: usize,
294    #[serde(rename = "totalfee", with = "bitcoin::amount::serde::as_sat")]
295    pub total_fee: Amount,
296    pub txs: usize,
297    pub utxo_increase: i32,
298    pub utxo_size_inc: i32,
299}
300
301#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
302pub struct GetBlockStatsResultPartial {
303    #[serde(
304        default,
305        rename = "avgfee",
306        with = "bitcoin::amount::serde::as_sat::opt",
307        skip_serializing_if = "Option::is_none"
308    )]
309    pub avg_fee: Option<Amount>,
310    #[serde(
311        default,
312        rename = "avgfeerate",
313        with = "bitcoin::amount::serde::as_sat::opt",
314        skip_serializing_if = "Option::is_none"
315    )]
316    pub avg_fee_rate: Option<Amount>,
317    #[serde(default, rename = "avgtxsize", skip_serializing_if = "Option::is_none")]
318    pub avg_tx_size: Option<u32>,
319    #[serde(default, rename = "blockhash", skip_serializing_if = "Option::is_none")]
320    pub block_hash: Option<bitcoin::BlockHash>,
321    #[serde(default, rename = "feerate_percentiles", skip_serializing_if = "Option::is_none")]
322    pub fee_rate_percentiles: Option<FeeRatePercentiles>,
323    #[serde(default, skip_serializing_if = "Option::is_none")]
324    pub height: Option<u64>,
325    #[serde(default, skip_serializing_if = "Option::is_none")]
326    pub ins: Option<usize>,
327    #[serde(
328        default,
329        rename = "maxfee",
330        with = "bitcoin::amount::serde::as_sat::opt",
331        skip_serializing_if = "Option::is_none"
332    )]
333    pub max_fee: Option<Amount>,
334    #[serde(
335        default,
336        rename = "maxfeerate",
337        with = "bitcoin::amount::serde::as_sat::opt",
338        skip_serializing_if = "Option::is_none"
339    )]
340    pub max_fee_rate: Option<Amount>,
341    #[serde(default, rename = "maxtxsize", skip_serializing_if = "Option::is_none")]
342    pub max_tx_size: Option<u32>,
343    #[serde(
344        default,
345        rename = "medianfee",
346        with = "bitcoin::amount::serde::as_sat::opt",
347        skip_serializing_if = "Option::is_none"
348    )]
349    pub median_fee: Option<Amount>,
350    #[serde(default, rename = "mediantime", skip_serializing_if = "Option::is_none")]
351    pub median_time: Option<u64>,
352    #[serde(default, rename = "mediantxsize", skip_serializing_if = "Option::is_none")]
353    pub median_tx_size: Option<u32>,
354    #[serde(
355        default,
356        rename = "minfee",
357        with = "bitcoin::amount::serde::as_sat::opt",
358        skip_serializing_if = "Option::is_none"
359    )]
360    pub min_fee: Option<Amount>,
361    #[serde(
362        default,
363        rename = "minfeerate",
364        with = "bitcoin::amount::serde::as_sat::opt",
365        skip_serializing_if = "Option::is_none"
366    )]
367    pub min_fee_rate: Option<Amount>,
368    #[serde(default, rename = "mintxsize", skip_serializing_if = "Option::is_none")]
369    pub min_tx_size: Option<u32>,
370    #[serde(default, skip_serializing_if = "Option::is_none")]
371    pub outs: Option<usize>,
372    #[serde(
373        default,
374        with = "bitcoin::amount::serde::as_sat::opt",
375        skip_serializing_if = "Option::is_none"
376    )]
377    pub subsidy: Option<Amount>,
378    #[serde(default, rename = "swtotal_size", skip_serializing_if = "Option::is_none")]
379    pub sw_total_size: Option<usize>,
380    #[serde(default, rename = "swtotal_weight", skip_serializing_if = "Option::is_none")]
381    pub sw_total_weight: Option<usize>,
382    #[serde(default, rename = "swtxs", skip_serializing_if = "Option::is_none")]
383    pub sw_txs: Option<usize>,
384    #[serde(default, skip_serializing_if = "Option::is_none")]
385    pub time: Option<u64>,
386    #[serde(
387        default,
388        with = "bitcoin::amount::serde::as_sat::opt",
389        skip_serializing_if = "Option::is_none"
390    )]
391    pub total_out: Option<Amount>,
392    #[serde(default, skip_serializing_if = "Option::is_none")]
393    pub total_size: Option<usize>,
394    #[serde(default, skip_serializing_if = "Option::is_none")]
395    pub total_weight: Option<usize>,
396    #[serde(
397        default,
398        rename = "totalfee",
399        with = "bitcoin::amount::serde::as_sat::opt",
400        skip_serializing_if = "Option::is_none"
401    )]
402    pub total_fee: Option<Amount>,
403    #[serde(default, skip_serializing_if = "Option::is_none")]
404    pub txs: Option<usize>,
405    #[serde(default, skip_serializing_if = "Option::is_none")]
406    pub utxo_increase: Option<i32>,
407    #[serde(default, skip_serializing_if = "Option::is_none")]
408    pub utxo_size_inc: Option<i32>,
409}
410
411#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
412pub struct FeeRatePercentiles {
413    #[serde(with = "bitcoin::amount::serde::as_sat")]
414    pub fr_10th: Amount,
415    #[serde(with = "bitcoin::amount::serde::as_sat")]
416    pub fr_25th: Amount,
417    #[serde(with = "bitcoin::amount::serde::as_sat")]
418    pub fr_50th: Amount,
419    #[serde(with = "bitcoin::amount::serde::as_sat")]
420    pub fr_75th: Amount,
421    #[serde(with = "bitcoin::amount::serde::as_sat")]
422    pub fr_90th: Amount,
423}
424
425#[derive(Clone)]
426pub enum BlockStatsFields {
427    AverageFee,
428    AverageFeeRate,
429    AverageTxSize,
430    BlockHash,
431    FeeRatePercentiles,
432    Height,
433    Ins,
434    MaxFee,
435    MaxFeeRate,
436    MaxTxSize,
437    MedianFee,
438    MedianTime,
439    MedianTxSize,
440    MinFee,
441    MinFeeRate,
442    MinTxSize,
443    Outs,
444    Subsidy,
445    SegWitTotalSize,
446    SegWitTotalWeight,
447    SegWitTxs,
448    Time,
449    TotalOut,
450    TotalSize,
451    TotalWeight,
452    TotalFee,
453    Txs,
454    UtxoIncrease,
455    UtxoSizeIncrease,
456}
457
458impl BlockStatsFields {
459    fn get_rpc_keyword(&self) -> &str {
460        match *self {
461            BlockStatsFields::AverageFee => "avgfee",
462            BlockStatsFields::AverageFeeRate => "avgfeerate",
463            BlockStatsFields::AverageTxSize => "avgtxsize",
464            BlockStatsFields::BlockHash => "blockhash",
465            BlockStatsFields::FeeRatePercentiles => "feerate_percentiles",
466            BlockStatsFields::Height => "height",
467            BlockStatsFields::Ins => "ins",
468            BlockStatsFields::MaxFee => "maxfee",
469            BlockStatsFields::MaxFeeRate => "maxfeerate",
470            BlockStatsFields::MaxTxSize => "maxtxsize",
471            BlockStatsFields::MedianFee => "medianfee",
472            BlockStatsFields::MedianTime => "mediantime",
473            BlockStatsFields::MedianTxSize => "mediantxsize",
474            BlockStatsFields::MinFee => "minfee",
475            BlockStatsFields::MinFeeRate => "minfeerate",
476            BlockStatsFields::MinTxSize => "minfeerate",
477            BlockStatsFields::Outs => "outs",
478            BlockStatsFields::Subsidy => "subsidy",
479            BlockStatsFields::SegWitTotalSize => "swtotal_size",
480            BlockStatsFields::SegWitTotalWeight => "swtotal_weight",
481            BlockStatsFields::SegWitTxs => "swtxs",
482            BlockStatsFields::Time => "time",
483            BlockStatsFields::TotalOut => "total_out",
484            BlockStatsFields::TotalSize => "total_size",
485            BlockStatsFields::TotalWeight => "total_weight",
486            BlockStatsFields::TotalFee => "totalfee",
487            BlockStatsFields::Txs => "txs",
488            BlockStatsFields::UtxoIncrease => "utxo_increase",
489            BlockStatsFields::UtxoSizeIncrease => "utxo_size_inc",
490        }
491    }
492}
493
494impl fmt::Display for BlockStatsFields {
495    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
496        write!(f, "{}", self.get_rpc_keyword())
497    }
498}
499
500impl From<BlockStatsFields> for serde_json::Value {
501    fn from(bsf: BlockStatsFields) -> Self {
502        Self::from(bsf.to_string())
503    }
504}
505
506#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
507#[serde(rename_all = "camelCase")]
508pub struct GetMiningInfoResult {
509    pub blocks: u32,
510    #[serde(rename = "currentblockweight")]
511    pub current_block_weight: Option<u64>,
512    #[serde(rename = "currentblocktx")]
513    pub current_block_tx: Option<usize>,
514    pub difficulty: f64,
515    #[serde(rename = "networkhashps")]
516    pub network_hash_ps: f64,
517    #[serde(rename = "pooledtx")]
518    pub pooled_tx: usize,
519    #[serde(deserialize_with = "deserialize_bip70_network")]
520    pub chain: Network,
521    pub warnings: String,
522}
523
524#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
525#[serde(rename_all = "camelCase")]
526pub struct GetRawTransactionResultVinScriptSig {
527    pub asm: String,
528    #[serde(with = "crate::serde_hex")]
529    pub hex: Vec<u8>,
530}
531
532impl GetRawTransactionResultVinScriptSig {
533    pub fn script(&self) -> Result<ScriptBuf, encode::Error> {
534        Ok(ScriptBuf::from(self.hex.clone()))
535    }
536}
537
538#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
539#[serde(rename_all = "camelCase")]
540pub struct GetRawTransactionResultVin {
541    pub sequence: u32,
542    #[serde(default, with = "crate::serde_hex::opt")]
544    pub coinbase: Option<Vec<u8>>,
545    pub txid: Option<bitcoin::Txid>,
547    pub vout: Option<u32>,
549    pub script_sig: Option<GetRawTransactionResultVinScriptSig>,
551    #[serde(default, deserialize_with = "deserialize_hex_array_opt")]
553    pub txinwitness: Option<Vec<Vec<u8>>>,
554}
555
556impl GetRawTransactionResultVin {
557    pub fn is_coinbase(&self) -> bool {
561        self.coinbase.is_some()
562    }
563}
564
565#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
566#[serde(rename_all = "camelCase")]
567pub struct GetRawTransactionResultVoutScriptPubKey {
568    pub asm: String,
569    #[serde(with = "crate::serde_hex")]
570    pub hex: Vec<u8>,
571    pub req_sigs: Option<usize>,
572    #[serde(rename = "type")]
573    pub type_: Option<ScriptPubkeyType>,
574    #[serde(default)]
576    pub addresses: Vec<Address<NetworkUnchecked>>,
577    #[serde(default)]
579    pub address: Option<Address<NetworkUnchecked>>,
580}
581
582impl GetRawTransactionResultVoutScriptPubKey {
583    pub fn script(&self) -> Result<ScriptBuf, encode::Error> {
584        Ok(ScriptBuf::from(self.hex.clone()))
585    }
586}
587
588#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
589#[serde(rename_all = "camelCase")]
590pub struct GetRawTransactionResultVout {
591    #[serde(with = "bitcoin::amount::serde::as_btc")]
592    pub value: Amount,
593    pub n: u32,
594    pub script_pub_key: GetRawTransactionResultVoutScriptPubKey,
595}
596
597#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
598#[serde(rename_all = "camelCase")]
599pub struct GetRawTransactionResult {
600    #[serde(rename = "in_active_chain")]
601    pub in_active_chain: Option<bool>,
602    #[serde(with = "crate::serde_hex")]
603    pub hex: Vec<u8>,
604    pub txid: bitcoin::Txid,
605    pub hash: bitcoin::Wtxid,
606    pub size: usize,
607    pub vsize: usize,
608    pub version: u32,
609    pub locktime: u32,
610    pub vin: Vec<GetRawTransactionResultVin>,
611    pub vout: Vec<GetRawTransactionResultVout>,
612    pub blockhash: Option<bitcoin::BlockHash>,
613    pub confirmations: Option<u32>,
614    pub time: Option<usize>,
615    pub blocktime: Option<usize>,
616}
617
618#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
619pub struct GetBlockFilterResult {
620    pub header: bitcoin::hash_types::FilterHash,
621    #[serde(with = "crate::serde_hex")]
622    pub filter: Vec<u8>,
623}
624
625impl GetBlockFilterResult {
626    pub fn to_filter(&self) -> bip158::BlockFilter {
630        bip158::BlockFilter::new(&self.filter)
631    }
632
633    pub fn into_filter(self) -> bip158::BlockFilter {
635        bip158::BlockFilter {
636            content: self.filter,
637        }
638    }
639}
640
641impl GetRawTransactionResult {
642    pub fn is_coinbase(&self) -> bool {
644        self.vin.len() == 1 && self.vin[0].is_coinbase()
645    }
646
647    pub fn transaction(&self) -> Result<Transaction, encode::Error> {
648        Ok(encode::deserialize(&self.hex)?)
649    }
650}
651
652#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
654#[serde(rename_all = "lowercase")]
655pub enum Bip125Replaceable {
656    Yes,
657    No,
658    Unknown,
659}
660
661#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
663#[serde(rename_all = "lowercase")]
664pub enum GetTransactionResultDetailCategory {
665    Send,
666    Receive,
667    Generate,
668    Immature,
669    Orphan,
670}
671
672#[derive(Clone, PartialEq, Eq, Debug, Deserialize)]
673pub struct GetTransactionResultDetail {
674    pub address: Option<Address<NetworkUnchecked>>,
675    pub category: GetTransactionResultDetailCategory,
676    #[serde(with = "bitcoin::amount::serde::as_btc")]
677    pub amount: SignedAmount,
678    pub label: Option<String>,
679    pub vout: u32,
680    #[serde(default, with = "bitcoin::amount::serde::as_btc::opt")]
681    pub fee: Option<SignedAmount>,
682    pub abandoned: Option<bool>,
683}
684
685#[derive(Clone, PartialEq, Eq, Debug, Deserialize)]
686pub struct WalletTxInfo {
687    pub confirmations: i32,
688    pub blockhash: Option<bitcoin::BlockHash>,
689    pub blockindex: Option<usize>,
690    pub blocktime: Option<u64>,
691    pub blockheight: Option<u32>,
692    pub txid: bitcoin::Txid,
693    pub time: u64,
694    pub timereceived: u64,
695    #[serde(rename = "bip125-replaceable")]
696    pub bip125_replaceable: Bip125Replaceable,
697    #[serde(rename = "walletconflicts")]
699    pub wallet_conflicts: Vec<bitcoin::Txid>,
700}
701
702#[derive(Clone, PartialEq, Eq, Debug, Deserialize)]
703pub struct GetTransactionResult {
704    #[serde(flatten)]
705    pub info: WalletTxInfo,
706    #[serde(with = "bitcoin::amount::serde::as_btc")]
707    pub amount: SignedAmount,
708    #[serde(default, with = "bitcoin::amount::serde::as_btc::opt")]
709    pub fee: Option<SignedAmount>,
710    pub details: Vec<GetTransactionResultDetail>,
711    #[serde(with = "crate::serde_hex")]
712    pub hex: Vec<u8>,
713}
714
715impl GetTransactionResult {
716    pub fn transaction(&self) -> Result<Transaction, encode::Error> {
717        Ok(encode::deserialize(&self.hex)?)
718    }
719}
720
721#[derive(Clone, PartialEq, Eq, Debug, Deserialize)]
722pub struct ListTransactionResult {
723    #[serde(flatten)]
724    pub info: WalletTxInfo,
725    #[serde(flatten)]
726    pub detail: GetTransactionResultDetail,
727
728    pub trusted: Option<bool>,
729    pub comment: Option<String>,
730}
731
732#[derive(Clone, PartialEq, Eq, Debug, Deserialize)]
733pub struct ListSinceBlockResult {
734    pub transactions: Vec<ListTransactionResult>,
735    #[serde(default)]
736    pub removed: Vec<ListTransactionResult>,
737    pub lastblock: bitcoin::BlockHash,
738}
739
740#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
741#[serde(rename_all = "camelCase")]
742pub struct GetTxOutResult {
743    pub bestblock: bitcoin::BlockHash,
744    pub confirmations: u32,
745    #[serde(with = "bitcoin::amount::serde::as_btc")]
746    pub value: Amount,
747    pub script_pub_key: GetRawTransactionResultVoutScriptPubKey,
748    pub coinbase: bool,
749}
750
751#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize, Default)]
752#[serde(rename_all = "camelCase")]
753pub struct ListUnspentQueryOptions {
754    #[serde(
755        rename = "minimumAmount",
756        with = "bitcoin::amount::serde::as_btc::opt",
757        skip_serializing_if = "Option::is_none"
758    )]
759    pub minimum_amount: Option<Amount>,
760    #[serde(
761        rename = "maximumAmount",
762        with = "bitcoin::amount::serde::as_btc::opt",
763        skip_serializing_if = "Option::is_none"
764    )]
765    pub maximum_amount: Option<Amount>,
766    #[serde(rename = "maximumCount", skip_serializing_if = "Option::is_none")]
767    pub maximum_count: Option<usize>,
768    #[serde(
769        rename = "minimumSumAmount",
770        with = "bitcoin::amount::serde::as_btc::opt",
771        skip_serializing_if = "Option::is_none"
772    )]
773    pub minimum_sum_amount: Option<Amount>,
774}
775
776#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
777#[serde(rename_all = "camelCase")]
778pub struct ListUnspentResultEntry {
779    pub txid: bitcoin::Txid,
780    pub vout: u32,
781    pub address: Option<Address<NetworkUnchecked>>,
782    pub label: Option<String>,
783    pub redeem_script: Option<ScriptBuf>,
784    pub witness_script: Option<ScriptBuf>,
785    pub script_pub_key: ScriptBuf,
786    #[serde(with = "bitcoin::amount::serde::as_btc")]
787    pub amount: Amount,
788    pub confirmations: u32,
789    pub spendable: bool,
790    pub solvable: bool,
791    #[serde(rename = "desc")]
792    pub descriptor: Option<String>,
793    pub safe: bool,
794}
795
796#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
797#[serde(rename_all = "camelCase")]
798pub struct ListReceivedByAddressResult {
799    #[serde(default, rename = "involvesWatchonly")]
800    pub involved_watch_only: bool,
801    pub address: Address<NetworkUnchecked>,
802    #[serde(with = "bitcoin::amount::serde::as_btc")]
803    pub amount: Amount,
804    pub confirmations: u32,
805    pub label: String,
806    pub txids: Vec<bitcoin::Txid>,
807}
808
809#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
810#[serde(rename_all = "camelCase")]
811pub struct SignRawTransactionResultError {
812    pub txid: bitcoin::Txid,
813    pub vout: u32,
814    pub script_sig: ScriptBuf,
815    pub sequence: u32,
816    pub error: String,
817}
818
819#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
820#[serde(rename_all = "camelCase")]
821pub struct SignRawTransactionResult {
822    #[serde(with = "crate::serde_hex")]
823    pub hex: Vec<u8>,
824    pub complete: bool,
825    pub errors: Option<Vec<SignRawTransactionResultError>>,
826}
827
828impl SignRawTransactionResult {
829    pub fn transaction(&self) -> Result<Transaction, encode::Error> {
830        Ok(encode::deserialize(&self.hex)?)
831    }
832}
833
834#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
835pub struct TestMempoolAcceptResult {
836    pub txid: bitcoin::Txid,
837    pub allowed: bool,
838    #[serde(rename = "reject-reason")]
839    pub reject_reason: Option<String>,
840    pub vsize: Option<u64>,
843    pub fees: Option<TestMempoolAcceptResultFees>,
846}
847
848#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
849pub struct TestMempoolAcceptResultFees {
850    #[serde(with = "bitcoin::amount::serde::as_btc")]
852    pub base: Amount,
853    }
855
856#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
857#[serde(rename_all = "snake_case")]
858pub enum Bip9SoftforkStatus {
859    Defined,
860    Started,
861    LockedIn,
862    Active,
863    Failed,
864}
865
866#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
867pub struct Bip9SoftforkStatistics {
868    pub period: u32,
869    pub threshold: Option<u32>,
870    pub elapsed: u32,
871    pub count: u32,
872    pub possible: Option<bool>,
873}
874
875#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
876pub struct Bip9SoftforkInfo {
877    pub status: Bip9SoftforkStatus,
878    pub bit: Option<u8>,
879    pub start_time: i64,
881    pub timeout: u64,
882    pub since: u32,
883    pub statistics: Option<Bip9SoftforkStatistics>,
884}
885
886#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
887#[serde(rename_all = "lowercase")]
888pub enum SoftforkType {
889    Buried,
890    Bip9,
891    #[serde(other)]
892    Other,
893}
894
895#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
897pub struct Softfork {
898    #[serde(rename = "type")]
899    pub type_: SoftforkType,
900    pub bip9: Option<Bip9SoftforkInfo>,
901    pub height: Option<u32>,
902    pub active: bool,
903}
904
905#[allow(non_camel_case_types)]
906#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
907#[serde(rename_all = "lowercase")]
908pub enum ScriptPubkeyType {
909    Nonstandard,
910    Pubkey,
911    PubkeyHash,
912    ScriptHash,
913    MultiSig,
914    NullData,
915    Witness_v0_KeyHash,
916    Witness_v0_ScriptHash,
917    Witness_v1_Taproot,
918    Witness_Unknown,
919}
920
921#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
922pub struct GetAddressInfoResultEmbedded {
923    pub address: Address<NetworkUnchecked>,
924    #[serde(rename = "scriptPubKey")]
925    pub script_pub_key: ScriptBuf,
926    #[serde(rename = "is_script")]
927    pub is_script: Option<bool>,
928    #[serde(rename = "is_witness")]
929    pub is_witness: Option<bool>,
930    pub witness_version: Option<u32>,
931    #[serde(with = "crate::serde_hex")]
932    pub witness_program: Vec<u8>,
933    pub script: Option<ScriptPubkeyType>,
934    #[serde(default, with = "crate::serde_hex::opt")]
936    pub hex: Option<Vec<u8>>,
937    pub pubkeys: Option<Vec<PublicKey>>,
938    #[serde(rename = "sigsrequired")]
939    pub n_signatures_required: Option<usize>,
940    pub pubkey: Option<PublicKey>,
941    #[serde(rename = "is_compressed")]
942    pub is_compressed: Option<bool>,
943    pub label: Option<String>,
944    #[serde(rename = "hdkeypath")]
945    pub hd_key_path: Option<bip32::DerivationPath>,
946    #[serde(rename = "hdseedid")]
947    pub hd_seed_id: Option<bitcoin::hash_types::XpubIdentifier>,
948    #[serde(default)]
949    pub labels: Vec<GetAddressInfoResultLabel>,
950}
951
952#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
953#[serde(rename_all = "lowercase")]
954pub enum GetAddressInfoResultLabelPurpose {
955    Send,
956    Receive,
957}
958
959#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
960#[serde(untagged)]
961pub enum GetAddressInfoResultLabel {
962    Simple(String),
963    WithPurpose {
964        name: String,
965        purpose: GetAddressInfoResultLabelPurpose,
966    },
967}
968
969#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
970pub struct GetAddressInfoResult {
971    pub address: Address<NetworkUnchecked>,
972    #[serde(rename = "scriptPubKey")]
973    pub script_pub_key: ScriptBuf,
974    #[serde(rename = "ismine")]
975    pub is_mine: Option<bool>,
976    #[serde(rename = "iswatchonly")]
977    pub is_watchonly: Option<bool>,
978    #[serde(rename = "isscript")]
979    pub is_script: Option<bool>,
980    #[serde(rename = "iswitness")]
981    pub is_witness: Option<bool>,
982    pub witness_version: Option<u32>,
983    #[serde(default, with = "crate::serde_hex::opt")]
984    pub witness_program: Option<Vec<u8>>,
985    pub script: Option<ScriptPubkeyType>,
986    #[serde(default, with = "crate::serde_hex::opt")]
988    pub hex: Option<Vec<u8>>,
989    pub pubkeys: Option<Vec<PublicKey>>,
990    #[serde(rename = "sigsrequired")]
991    pub n_signatures_required: Option<usize>,
992    pub pubkey: Option<PublicKey>,
993    pub embedded: Option<GetAddressInfoResultEmbedded>,
995    #[serde(rename = "is_compressed")]
996    pub is_compressed: Option<bool>,
997    pub timestamp: Option<u64>,
998    #[serde(rename = "hdkeypath")]
999    pub hd_key_path: Option<bip32::DerivationPath>,
1000    #[serde(rename = "hdseedid")]
1001    pub hd_seed_id: Option<bitcoin::hash_types::XpubIdentifier>,
1002    pub labels: Vec<GetAddressInfoResultLabel>,
1003    #[deprecated(note = "since Core v0.20.0")]
1005    pub label: Option<String>,
1006}
1007
1008#[derive(Clone, Debug, Deserialize, Serialize)]
1010pub struct GetBlockchainInfoResult {
1011    #[serde(deserialize_with = "deserialize_bip70_network")]
1013    pub chain: Network,
1014    pub blocks: u64,
1016    pub headers: u64,
1018    #[serde(rename = "bestblockhash")]
1020    pub best_block_hash: bitcoin::BlockHash,
1021    pub difficulty: f64,
1023    #[serde(rename = "mediantime")]
1025    pub median_time: u64,
1026    #[serde(rename = "verificationprogress")]
1028    pub verification_progress: f64,
1029    #[serde(rename = "initialblockdownload")]
1031    pub initial_block_download: bool,
1032    #[serde(rename = "chainwork", with = "crate::serde_hex")]
1034    pub chain_work: Vec<u8>,
1035    pub size_on_disk: u64,
1037    pub pruned: bool,
1039    #[serde(rename = "pruneheight")]
1041    pub prune_height: Option<u64>,
1042    pub automatic_pruning: Option<bool>,
1044    pub prune_target_size: Option<u64>,
1046    #[serde(default)]
1048    pub softforks: HashMap<String, Softfork>,
1049    pub warnings: String,
1051}
1052
1053#[derive(Clone, PartialEq, Eq, Debug)]
1054pub enum ImportMultiRequestScriptPubkey<'a> {
1055    Address(&'a Address),
1056    Script(&'a Script),
1057}
1058
1059#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1060pub struct GetMempoolInfoResult {
1061    pub loaded: Option<bool>,
1063    pub size: usize,
1065    pub bytes: usize,
1067    pub usage: usize,
1069    #[serde(default, with = "bitcoin::amount::serde::as_btc::opt")]
1071    pub total_fee: Option<Amount>,
1072    #[serde(rename = "maxmempool")]
1074    pub max_mempool: usize,
1075    #[serde(rename = "mempoolminfee", with = "bitcoin::amount::serde::as_btc")]
1077    pub mempool_min_fee: Amount,
1078    #[serde(rename = "minrelaytxfee", with = "bitcoin::amount::serde::as_btc")]
1080    pub min_relay_tx_fee: Amount,
1081    #[serde(rename = "incrementalrelayfee", default, with = "bitcoin::amount::serde::as_btc::opt")]
1083    pub incremental_relay_fee: Option<Amount>,
1084    #[serde(rename = "unbroadcastcount")]
1086    pub unbroadcast_count: Option<usize>,
1087    #[serde(rename = "fullrbf")]
1089    pub full_rbf: Option<bool>,
1090}
1091
1092#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1093pub struct GetMempoolEntryResult {
1094    #[serde(alias = "size")]
1097    pub vsize: u64,
1098    pub weight: Option<u64>,
1100    pub time: u64,
1102    pub height: u64,
1104    #[serde(rename = "descendantcount")]
1106    pub descendant_count: u64,
1107    #[serde(rename = "descendantsize")]
1109    pub descendant_size: u64,
1110    #[serde(rename = "ancestorcount")]
1112    pub ancestor_count: u64,
1113    #[serde(rename = "ancestorsize")]
1115    pub ancestor_size: u64,
1116    pub wtxid: bitcoin::Txid,
1118    pub fees: GetMempoolEntryResultFees,
1120    pub depends: Vec<bitcoin::Txid>,
1122    #[serde(rename = "spentby")]
1124    pub spent_by: Vec<bitcoin::Txid>,
1125    #[serde(rename = "bip125-replaceable")]
1127    pub bip125_replaceable: bool,
1128    pub unbroadcast: Option<bool>,
1131}
1132
1133#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1134pub struct GetMempoolEntryResultFees {
1135    #[serde(with = "bitcoin::amount::serde::as_btc")]
1137    pub base: Amount,
1138    #[serde(with = "bitcoin::amount::serde::as_btc")]
1140    pub modified: Amount,
1141    #[serde(with = "bitcoin::amount::serde::as_btc")]
1143    pub ancestor: Amount,
1144    #[serde(with = "bitcoin::amount::serde::as_btc")]
1146    pub descendant: Amount,
1147}
1148
1149impl<'a> serde::Serialize for ImportMultiRequestScriptPubkey<'a> {
1150    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1151    where
1152        S: serde::Serializer,
1153    {
1154        match *self {
1155            ImportMultiRequestScriptPubkey::Address(ref addr) => {
1156                #[derive(Serialize)]
1157                struct Tmp<'a> {
1158                    pub address: &'a Address,
1159                }
1160                serde::Serialize::serialize(
1161                    &Tmp {
1162                        address: addr,
1163                    },
1164                    serializer,
1165                )
1166            }
1167            ImportMultiRequestScriptPubkey::Script(script) => {
1168                serializer.serialize_str(&script.to_hex_string())
1169            }
1170        }
1171    }
1172}
1173
1174#[derive(Clone, PartialEq, Eq, Debug, Default, Serialize)]
1178pub struct ImportMultiRequest<'a> {
1179    pub timestamp: Timestamp,
1180    #[serde(rename = "desc", skip_serializing_if = "Option::is_none")]
1182    pub descriptor: Option<&'a str>,
1183    #[serde(rename = "scriptPubKey", skip_serializing_if = "Option::is_none")]
1184    pub script_pubkey: Option<ImportMultiRequestScriptPubkey<'a>>,
1185    #[serde(rename = "redeemscript", skip_serializing_if = "Option::is_none")]
1186    pub redeem_script: Option<&'a Script>,
1187    #[serde(rename = "witnessscript", skip_serializing_if = "Option::is_none")]
1188    pub witness_script: Option<&'a Script>,
1189    #[serde(skip_serializing_if = "<[_]>::is_empty")]
1190    pub pubkeys: &'a [PublicKey],
1191    #[serde(skip_serializing_if = "<[_]>::is_empty")]
1192    pub keys: &'a [PrivateKey],
1193    #[serde(skip_serializing_if = "Option::is_none")]
1194    pub range: Option<(usize, usize)>,
1195    #[serde(skip_serializing_if = "Option::is_none")]
1196    pub internal: Option<bool>,
1197    #[serde(skip_serializing_if = "Option::is_none")]
1198    pub watchonly: Option<bool>,
1199    #[serde(skip_serializing_if = "Option::is_none")]
1200    pub label: Option<&'a str>,
1201    #[serde(skip_serializing_if = "Option::is_none")]
1202    pub keypool: Option<bool>,
1203}
1204
1205#[derive(Clone, PartialEq, Eq, Debug, Default, Deserialize, Serialize)]
1206pub struct ImportMultiOptions {
1207    #[serde(skip_serializing_if = "Option::is_none")]
1208    pub rescan: Option<bool>,
1209}
1210
1211#[derive(Clone, PartialEq, Eq, Copy, Debug)]
1212pub enum Timestamp {
1213    Now,
1214    Time(u64),
1215}
1216
1217impl serde::Serialize for Timestamp {
1218    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1219    where
1220        S: serde::Serializer,
1221    {
1222        match *self {
1223            Timestamp::Now => serializer.serialize_str("now"),
1224            Timestamp::Time(timestamp) => serializer.serialize_u64(timestamp),
1225        }
1226    }
1227}
1228
1229impl<'de> serde::Deserialize<'de> for Timestamp {
1230    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1231    where
1232        D: serde::Deserializer<'de>,
1233    {
1234        use serde::de;
1235        struct Visitor;
1236        impl<'de> de::Visitor<'de> for Visitor {
1237            type Value = Timestamp;
1238
1239            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
1240                write!(formatter, "unix timestamp or 'now'")
1241            }
1242
1243            fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
1244            where
1245                E: de::Error,
1246            {
1247                Ok(Timestamp::Time(value))
1248            }
1249
1250            fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
1251            where
1252                E: de::Error,
1253            {
1254                if value == "now" {
1255                    Ok(Timestamp::Now)
1256                } else {
1257                    Err(de::Error::custom(format!(
1258                        "invalid str '{}', expecting 'now' or unix timestamp",
1259                        value
1260                    )))
1261                }
1262            }
1263        }
1264        deserializer.deserialize_any(Visitor)
1265    }
1266}
1267
1268impl Default for Timestamp {
1269    fn default() -> Self {
1270        Timestamp::Time(0)
1271    }
1272}
1273
1274impl From<u64> for Timestamp {
1275    fn from(t: u64) -> Self {
1276        Timestamp::Time(t)
1277    }
1278}
1279
1280impl From<Option<u64>> for Timestamp {
1281    fn from(timestamp: Option<u64>) -> Self {
1282        timestamp.map_or(Timestamp::Now, Timestamp::Time)
1283    }
1284}
1285
1286#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1287pub struct ImportMultiResultError {
1288    pub code: i64,
1289    pub message: String,
1290}
1291
1292#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1293pub struct ImportMultiResult {
1294    pub success: bool,
1295    #[serde(default)]
1296    pub warnings: Vec<String>,
1297    pub error: Option<ImportMultiResultError>,
1298}
1299
1300#[derive(Clone, PartialEq, Eq, Debug, Default, Deserialize, Serialize)]
1302pub struct ImportDescriptors {
1303    #[serde(rename = "desc")]
1304    pub descriptor: String,
1305    pub timestamp: Timestamp,
1306    #[serde(skip_serializing_if = "Option::is_none")]
1307    pub active: Option<bool>,
1308    #[serde(skip_serializing_if = "Option::is_none")]
1309    pub range: Option<(usize, usize)>,
1310    #[serde(skip_serializing_if = "Option::is_none")]
1311    pub next_index: Option<usize>,
1312    #[serde(skip_serializing_if = "Option::is_none")]
1313    pub internal: Option<bool>,
1314    #[serde(skip_serializing_if = "Option::is_none")]
1315    pub label: Option<String>,
1316}
1317
1318#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1320pub struct RejectStatus {
1321    pub status: bool,
1323}
1324
1325#[derive(Clone, Debug, Deserialize, Serialize)]
1327pub struct GetPeerInfoResult {
1328    pub id: u64,
1330    pub addr: String,
1333    pub addrbind: String,
1336    pub addrlocal: Option<String>,
1339    pub network: Option<GetPeerInfoResultNetwork>,
1342    pub services: String,
1345    pub relaytxes: bool,
1347    pub lastsend: u64,
1349    pub lastrecv: u64,
1351    pub last_transaction: Option<u64>,
1354    pub last_block: Option<u64>,
1357    pub bytessent: u64,
1359    pub bytesrecv: u64,
1361    pub conntime: u64,
1363    pub timeoffset: i64,
1365    pub pingtime: Option<f64>,
1367    pub minping: Option<f64>,
1369    pub pingwait: Option<f64>,
1371    pub version: u64,
1373    pub subver: String,
1375    pub inbound: bool,
1377    pub addnode: Option<bool>,
1381    pub startingheight: i64,
1383    pub banscore: Option<i64>,
1386    pub synced_headers: i64,
1388    pub synced_blocks: i64,
1390    pub inflight: Vec<u64>,
1392    pub whitelisted: Option<bool>,
1395    #[serde(rename = "minfeefilter", default, with = "bitcoin::amount::serde::as_btc::opt")]
1396    pub min_fee_filter: Option<Amount>,
1397    pub bytessent_per_msg: HashMap<String, u64>,
1399    pub bytesrecv_per_msg: HashMap<String, u64>,
1401    pub connection_type: Option<GetPeerInfoResultConnectionType>,
1404}
1405
1406#[derive(Copy, Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
1407#[serde(rename_all = "snake_case")]
1408pub enum GetPeerInfoResultNetwork {
1409    Ipv4,
1410    Ipv6,
1411    Onion,
1412    #[deprecated]
1413    Unroutable,
1414    NotPubliclyRoutable,
1415    I2p,
1416    Cjdns,
1417    Internal,
1418}
1419
1420#[derive(Copy, Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
1421#[serde(rename_all = "kebab-case")]
1422pub enum GetPeerInfoResultConnectionType {
1423    OutboundFullRelay,
1424    BlockRelayOnly,
1425    Inbound,
1426    Manual,
1427    AddrFetch,
1428    Feeler,
1429}
1430
1431#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1432pub struct GetAddedNodeInfoResult {
1433    #[serde(rename = "addednode")]
1435    pub added_node: String,
1436    pub connected: bool,
1438    pub addresses: Vec<GetAddedNodeInfoResultAddress>,
1440}
1441
1442#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1443pub struct GetAddedNodeInfoResultAddress {
1444    pub address: String,
1446    pub connected: GetAddedNodeInfoResultAddressType,
1448}
1449
1450#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1451#[serde(rename_all = "lowercase")]
1452pub enum GetAddedNodeInfoResultAddressType {
1453    Inbound,
1454    Outbound,
1455}
1456
1457#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1458pub struct GetNodeAddressesResult {
1459    pub time: u64,
1461    pub services: usize,
1463    pub address: String,
1465    pub port: u16,
1467}
1468
1469#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1470pub struct ListBannedResult {
1471    pub address: String,
1472    pub banned_until: u64,
1473    pub ban_created: u64,
1474}
1475
1476#[derive(Clone, Debug, Deserialize, Serialize)]
1478pub struct EstimateSmartFeeResult {
1479    #[serde(
1481        default,
1482        rename = "feerate",
1483        skip_serializing_if = "Option::is_none",
1484        with = "bitcoin::amount::serde::as_btc::opt"
1485    )]
1486    pub fee_rate: Option<Amount>,
1487    pub errors: Option<Vec<String>>,
1489    pub blocks: i64,
1491}
1492
1493#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1495pub struct BlockRef {
1496    pub hash: bitcoin::BlockHash,
1497    pub height: u64,
1498}
1499
1500#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1502pub struct GetDescriptorInfoResult {
1503    pub descriptor: String,
1504    pub checksum: Option<String>,
1505    #[serde(rename = "isrange")]
1506    pub is_range: bool,
1507    #[serde(rename = "issolvable")]
1508    pub is_solvable: bool,
1509    #[serde(rename = "hasprivatekeys")]
1510    pub has_private_keys: bool,
1511}
1512
1513#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1515pub struct GetBlockTemplateOptions {
1516    pub mode: GetBlockTemplateModes,
1517    pub rules: Vec<GetBlockTemplateRules>,
1519    pub capabilities: Vec<GetBlockTemplateCapabilities>,
1521}
1522
1523#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1525#[serde(rename_all = "lowercase")]
1526pub enum GetBlockTemplateCapabilities {
1527    }
1529
1530#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1533#[serde(rename_all = "lowercase")]
1534pub enum GetBlockTemplateRules {
1535    SegWit,
1536    Signet,
1537    Csv,
1538    Taproot,
1539}
1540
1541#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1543#[serde(rename_all = "lowercase")]
1544pub enum GetBlockTemplateModes {
1545    Template,
1548    }
1551
1552#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1554pub struct GetBlockTemplateResult {
1555    #[serde(with = "crate::serde_hex")]
1557    pub bits: Vec<u8>,
1558    #[serde(rename = "previousblockhash")]
1560    pub previous_block_hash: bitcoin::BlockHash,
1561    #[serde(rename = "curtime")]
1565    pub current_time: u64,
1566    pub height: u64,
1568    #[serde(rename = "sigoplimit")]
1570    pub sigop_limit: u32,
1571    #[serde(rename = "sizelimit")]
1573    pub size_limit: u32,
1574    #[serde(rename = "weightlimit")]
1576    pub weight_limit: u32,
1577    pub version: u32,
1579    pub rules: Vec<GetBlockTemplateResultRules>,
1581    pub capabilities: Vec<GetBlockTemplateResultCapabilities>,
1583    #[serde(rename = "vbavailable")]
1585    pub version_bits_available: HashMap<String, u32>,
1586    #[serde(rename = "vbrequired")]
1588    pub version_bits_required: u32,
1589    pub longpollid: String,
1591    pub transactions: Vec<GetBlockTemplateResultTransaction>,
1593    #[serde(default, with = "bitcoin::script::ScriptBuf")]
1595    pub signet_challenge: bitcoin::script::ScriptBuf,
1596    #[serde(with = "bitcoin::script::ScriptBuf", default)]
1600    pub default_witness_commitment: bitcoin::script::ScriptBuf,
1601    pub coinbaseaux: HashMap<String, String>,
1608    #[serde(rename = "coinbasevalue", with = "bitcoin::amount::serde::as_sat", default)]
1610    pub coinbase_value: Amount,
1611    #[serde(with = "crate::serde_hex")]
1613    pub target: Vec<u8>,
1614    #[serde(rename = "mintime")]
1617    pub min_time: u64,
1618    pub mutable: Vec<GetBlockTemplateResulMutations>,
1621    #[serde(with = "crate::serde_hex", rename = "noncerange")]
1623    pub nonce_range: Vec<u8>,
1624}
1625
1626#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1628pub struct GetBlockTemplateResultTransaction {
1629    pub txid: bitcoin::Txid,
1631    #[serde(rename = "hash")]
1633    pub wtxid: bitcoin::Wtxid,
1634    #[serde(with = "crate::serde_hex", rename = "data")]
1636    pub raw_tx: Vec<u8>,
1637    #[serde(with = "bitcoin::amount::serde::as_sat")]
1639    pub fee: Amount,
1640    pub sigops: u32,
1642    pub weight: usize,
1644    pub depends: Vec<u32>,
1648}
1649
1650impl GetBlockTemplateResultTransaction {
1651    pub fn transaction(&self) -> Result<Transaction, encode::Error> {
1652        encode::deserialize(&self.raw_tx)
1653    }
1654}
1655
1656#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1658#[serde(rename_all = "lowercase")]
1659pub enum GetBlockTemplateResultCapabilities {
1660    Proposal,
1661}
1662
1663#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1666#[serde(rename_all = "lowercase")]
1667pub enum GetBlockTemplateResultRules {
1668    #[serde(alias = "!segwit")]
1671    SegWit,
1672    #[serde(alias = "!signet")]
1675    Signet,
1676    Csv,
1679    Taproot,
1682    Testdummy,
1685}
1686
1687#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1692#[serde(rename_all = "lowercase")]
1693pub enum GetBlockTemplateResulMutations {
1694    Time,
1696    Transactions,
1698    #[serde(rename = "prevblock")]
1702    PreviousBlock,
1703}
1704
1705#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1707pub struct WalletCreateFundedPsbtResult {
1708    pub psbt: String,
1709    #[serde(with = "bitcoin::amount::serde::as_btc")]
1710    pub fee: Amount,
1711    #[serde(rename = "changepos")]
1712    pub change_position: i32,
1713}
1714
1715#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1717pub struct WalletProcessPsbtResult {
1718    pub psbt: String,
1719    pub complete: bool,
1720}
1721
1722#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize, Default)]
1724pub struct WalletCreateFundedPsbtOptions {
1725    #[serde(skip_serializing_if = "Option::is_none")]
1728    pub add_inputs: Option<bool>,
1729    #[serde(rename = "changeAddress", skip_serializing_if = "Option::is_none")]
1730    pub change_address: Option<Address<NetworkUnchecked>>,
1731    #[serde(rename = "changePosition", skip_serializing_if = "Option::is_none")]
1732    pub change_position: Option<u16>,
1733    #[serde(skip_serializing_if = "Option::is_none")]
1734    pub change_type: Option<AddressType>,
1735    #[serde(rename = "includeWatching", skip_serializing_if = "Option::is_none")]
1736    pub include_watching: Option<bool>,
1737    #[serde(rename = "lockUnspents", skip_serializing_if = "Option::is_none")]
1738    pub lock_unspent: Option<bool>,
1739    #[serde(
1740        rename = "feeRate",
1741        skip_serializing_if = "Option::is_none",
1742        with = "bitcoin::amount::serde::as_btc::opt"
1743    )]
1744    pub fee_rate: Option<Amount>,
1745    #[serde(rename = "subtractFeeFromOutputs", skip_serializing_if = "Vec::is_empty")]
1746    pub subtract_fee_from_outputs: Vec<u16>,
1747    #[serde(skip_serializing_if = "Option::is_none")]
1748    pub replaceable: Option<bool>,
1749    #[serde(skip_serializing_if = "Option::is_none")]
1750    pub conf_target: Option<u16>,
1751    #[serde(skip_serializing_if = "Option::is_none")]
1752    pub estimate_mode: Option<EstimateMode>,
1753}
1754
1755#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1757pub struct FinalizePsbtResult {
1758    pub psbt: Option<String>,
1759    #[serde(default, with = "crate::serde_hex::opt")]
1760    pub hex: Option<Vec<u8>>,
1761    pub complete: bool,
1762}
1763
1764#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1766pub struct DecodeRawTransactionResult {
1767    pub txid: bitcoin::Txid,
1768    pub hash: bitcoin::Wtxid,
1769    pub size: u32,
1770    pub vsize: u32,
1771    pub weight: u32,
1772    pub version: u32,
1773    pub locktime: u32,
1774    pub vin: Vec<GetRawTransactionResultVin>,
1775    pub vout: Vec<GetRawTransactionResultVout>,
1776}
1777
1778pub type GetChainTipsResult = Vec<GetChainTipsResultTip>;
1780
1781#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1783pub struct GetChainTipsResultTip {
1784    pub height: u64,
1786    pub hash: bitcoin::BlockHash,
1788    #[serde(rename = "branchlen")]
1790    pub branch_length: usize,
1791    pub status: GetChainTipsResultStatus,
1793}
1794
1795#[derive(Copy, Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
1796#[serde(rename_all = "lowercase")]
1797pub enum GetChainTipsResultStatus {
1798    Invalid,
1800    #[serde(rename = "headers-only")]
1802    HeadersOnly,
1803    #[serde(rename = "valid-headers")]
1805    ValidHeaders,
1806    #[serde(rename = "valid-fork")]
1808    ValidFork,
1809    Active,
1811}
1812
1813impl FinalizePsbtResult {
1814    pub fn transaction(&self) -> Option<Result<Transaction, encode::Error>> {
1815        self.hex.as_ref().map(|h| encode::deserialize(h))
1816    }
1817}
1818
1819#[derive(Serialize, Deserialize, Debug, Clone, Copy, Eq, PartialEq, Hash)]
1822#[serde(rename_all = "UPPERCASE")]
1823pub enum EstimateMode {
1824    Unset,
1825    Economical,
1826    Conservative,
1827}
1828
1829pub struct SigHashType(bitcoin::sighash::EcdsaSighashType);
1832
1833impl From<bitcoin::sighash::EcdsaSighashType> for SigHashType {
1834    fn from(sht: bitcoin::sighash::EcdsaSighashType) -> SigHashType {
1835        SigHashType(sht)
1836    }
1837}
1838
1839impl serde::Serialize for SigHashType {
1840    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1841    where
1842        S: serde::Serializer,
1843    {
1844        serializer.serialize_str(match self.0 {
1845            bitcoin::sighash::EcdsaSighashType::All => "ALL",
1846            bitcoin::sighash::EcdsaSighashType::None => "NONE",
1847            bitcoin::sighash::EcdsaSighashType::Single => "SINGLE",
1848            bitcoin::sighash::EcdsaSighashType::AllPlusAnyoneCanPay => "ALL|ANYONECANPAY",
1849            bitcoin::sighash::EcdsaSighashType::NonePlusAnyoneCanPay => "NONE|ANYONECANPAY",
1850            bitcoin::sighash::EcdsaSighashType::SinglePlusAnyoneCanPay => "SINGLE|ANYONECANPAY",
1851        })
1852    }
1853}
1854
1855#[derive(Serialize, Clone, PartialEq, Eq, Debug)]
1857#[serde(rename_all = "camelCase")]
1858pub struct CreateRawTransactionInput {
1859    pub txid: bitcoin::Txid,
1860    pub vout: u32,
1861    #[serde(skip_serializing_if = "Option::is_none")]
1862    pub sequence: Option<u32>,
1863}
1864
1865#[derive(Serialize, Clone, PartialEq, Eq, Debug, Default)]
1866#[serde(rename_all = "camelCase")]
1867pub struct FundRawTransactionOptions {
1868    #[serde(rename = "add_inputs", skip_serializing_if = "Option::is_none")]
1871    pub add_inputs: Option<bool>,
1872    #[serde(skip_serializing_if = "Option::is_none")]
1873    pub change_address: Option<Address>,
1874    #[serde(skip_serializing_if = "Option::is_none")]
1875    pub change_position: Option<u32>,
1876    #[serde(rename = "change_type", skip_serializing_if = "Option::is_none")]
1877    pub change_type: Option<AddressType>,
1878    #[serde(skip_serializing_if = "Option::is_none")]
1879    pub include_watching: Option<bool>,
1880    #[serde(skip_serializing_if = "Option::is_none")]
1881    pub lock_unspents: Option<bool>,
1882    #[serde(
1883        with = "bitcoin::amount::serde::as_btc::opt",
1884        skip_serializing_if = "Option::is_none"
1885    )]
1886    pub fee_rate: Option<Amount>,
1887    #[serde(skip_serializing_if = "Option::is_none")]
1888    pub subtract_fee_from_outputs: Option<Vec<u32>>,
1889    #[serde(skip_serializing_if = "Option::is_none")]
1890    pub replaceable: Option<bool>,
1891    #[serde(rename = "conf_target", skip_serializing_if = "Option::is_none")]
1892    pub conf_target: Option<u32>,
1893    #[serde(rename = "estimate_mode", skip_serializing_if = "Option::is_none")]
1894    pub estimate_mode: Option<EstimateMode>,
1895}
1896
1897#[derive(Deserialize, Clone, PartialEq, Eq, Debug)]
1898#[serde(rename_all = "camelCase")]
1899pub struct FundRawTransactionResult {
1900    #[serde(with = "crate::serde_hex")]
1901    pub hex: Vec<u8>,
1902    #[serde(with = "bitcoin::amount::serde::as_btc")]
1903    pub fee: Amount,
1904    #[serde(rename = "changepos")]
1905    pub change_position: i32,
1906}
1907
1908#[derive(Deserialize, Clone, PartialEq, Eq, Debug)]
1909pub struct GetBalancesResultEntry {
1910    #[serde(with = "bitcoin::amount::serde::as_btc")]
1911    pub trusted: Amount,
1912    #[serde(with = "bitcoin::amount::serde::as_btc")]
1913    pub untrusted_pending: Amount,
1914    #[serde(with = "bitcoin::amount::serde::as_btc")]
1915    pub immature: Amount,
1916}
1917
1918#[derive(Deserialize, Clone, PartialEq, Eq, Debug)]
1919#[serde(rename_all = "camelCase")]
1920pub struct GetBalancesResult {
1921    pub mine: GetBalancesResultEntry,
1922    pub watchonly: Option<GetBalancesResultEntry>,
1923}
1924
1925impl FundRawTransactionResult {
1926    pub fn transaction(&self) -> Result<Transaction, encode::Error> {
1927        encode::deserialize(&self.hex)
1928    }
1929}
1930
1931#[derive(Serialize, Clone, PartialEq, Debug)]
1933#[serde(rename_all = "camelCase")]
1934pub struct SignRawTransactionInput {
1935    pub txid: bitcoin::Txid,
1936    pub vout: u32,
1937    pub script_pub_key: ScriptBuf,
1938    #[serde(skip_serializing_if = "Option::is_none")]
1939    pub redeem_script: Option<ScriptBuf>,
1940    #[serde(
1941        default,
1942        skip_serializing_if = "Option::is_none",
1943        with = "bitcoin::amount::serde::as_btc::opt"
1944    )]
1945    pub amount: Option<Amount>,
1946}
1947
1948#[derive(Clone, Serialize, PartialEq, Eq, Debug)]
1950#[serde(rename_all = "snake_case")]
1951pub enum TxOutSetHashType {
1952    HashSerialized2,
1953    Muhash,
1954    None,
1955}
1956
1957#[derive(Clone, Serialize, PartialEq, Eq, Debug)]
1959#[serde(untagged)]
1960pub enum HashOrHeight {
1961    BlockHash(bitcoin::BlockHash),
1962    Height(u64),
1963}
1964
1965#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1966pub struct GetTxOutSetInfoResult {
1967    pub height: u64,
1969    #[serde(rename = "bestblock")]
1971    pub best_block: bitcoin::BlockHash,
1972    #[serde(default, skip_serializing_if = "Option::is_none")]
1974    pub transactions: Option<u64>,
1975    #[serde(rename = "txouts")]
1977    pub tx_outs: u64,
1978    pub bogosize: u64,
1980    #[serde(default, skip_serializing_if = "Option::is_none")]
1982    pub hash_serialized_2: Option<sha256::Hash>,
1983    #[serde(default, skip_serializing_if = "Option::is_none")]
1985    pub muhash: Option<sha256::Hash>,
1986    #[serde(default, skip_serializing_if = "Option::is_none")]
1988    pub disk_size: Option<u64>,
1989    #[serde(with = "bitcoin::amount::serde::as_btc")]
1991    pub total_amount: Amount,
1992    #[serde(
1994        default,
1995        skip_serializing_if = "Option::is_none",
1996        with = "bitcoin::amount::serde::as_btc::opt"
1997    )]
1998    pub total_unspendable_amount: Option<Amount>,
1999    #[serde(default, skip_serializing_if = "Option::is_none")]
2001    pub block_info: Option<BlockInfo>,
2002}
2003
2004#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
2006pub struct BlockInfo {
2007    #[serde(with = "bitcoin::amount::serde::as_btc")]
2009    pub prevout_spent: Amount,
2010    #[serde(with = "bitcoin::amount::serde::as_btc")]
2012    pub coinbase: Amount,
2013    #[serde(with = "bitcoin::amount::serde::as_btc")]
2015    pub new_outputs_ex_coinbase: Amount,
2016    #[serde(with = "bitcoin::amount::serde::as_btc")]
2018    pub unspendable: Amount,
2019    pub unspendables: Unspendables,
2021}
2022
2023#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
2025pub struct Unspendables {
2026    #[serde(with = "bitcoin::amount::serde::as_btc")]
2028    pub genesis_block: Amount,
2029    #[serde(with = "bitcoin::amount::serde::as_btc")]
2031    pub bip30: Amount,
2032    #[serde(with = "bitcoin::amount::serde::as_btc")]
2034    pub scripts: Amount,
2035    #[serde(with = "bitcoin::amount::serde::as_btc")]
2037    pub unclaimed_rewards: Amount,
2038}
2039
2040#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
2041pub struct GetNetTotalsResult {
2042    #[serde(rename = "totalbytesrecv")]
2044    pub total_bytes_recv: u64,
2045    #[serde(rename = "totalbytessent")]
2047    pub total_bytes_sent: u64,
2048    #[serde(rename = "timemillis")]
2050    pub time_millis: u64,
2051    #[serde(rename = "uploadtarget")]
2053    pub upload_target: GetNetTotalsResultUploadTarget,
2054}
2055
2056#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
2057pub struct GetNetTotalsResultUploadTarget {
2058    #[serde(rename = "timeframe")]
2060    pub time_frame: u64,
2061    pub target: u64,
2063    pub target_reached: bool,
2065    pub serve_historical_blocks: bool,
2067    pub bytes_left_in_cycle: u64,
2069    pub time_left_in_cycle: u64,
2071}
2072
2073#[derive(Copy, Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
2075#[serde(rename_all = "kebab-case")]
2076pub enum AddressType {
2077    Legacy,
2078    P2shSegwit,
2079    Bech32,
2080    Bech32m,
2081}
2082
2083#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
2085pub enum PubKeyOrAddress<'a> {
2086    Address(&'a Address),
2087    PubKey(&'a PublicKey),
2088}
2089
2090#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
2091#[serde(untagged)]
2092pub enum ScanTxOutRequest {
2094    Single(String),
2096    Extended {
2098        desc: String,
2100        range: (u64, u64),
2102    },
2103}
2104
2105#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
2106pub struct ScanTxOutResult {
2107    pub success: Option<bool>,
2108    #[serde(rename = "txouts")]
2109    pub tx_outs: Option<u64>,
2110    pub height: Option<u64>,
2111    #[serde(rename = "bestblock")]
2112    pub best_block_hash: Option<bitcoin::BlockHash>,
2113    pub unspents: Vec<Utxo>,
2114    #[serde(with = "bitcoin::amount::serde::as_btc")]
2115    pub total_amount: bitcoin::Amount,
2116}
2117
2118#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
2119#[serde(rename_all = "camelCase")]
2120pub struct Utxo {
2121    pub txid: bitcoin::Txid,
2122    pub vout: u32,
2123    pub script_pub_key: bitcoin::ScriptBuf,
2124    #[serde(rename = "desc")]
2125    pub descriptor: String,
2126    #[serde(with = "bitcoin::amount::serde::as_btc")]
2127    pub amount: bitcoin::Amount,
2128    pub height: u64,
2129}
2130
2131#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
2132pub struct IndexStatus {
2133    pub synced: bool,
2134    pub best_block_height: u32,
2135}
2136
2137#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
2138pub struct GetIndexInfoResult {
2139    pub txindex: Option<IndexStatus>,
2140    pub coinstatsindex: Option<IndexStatus>,
2141    #[serde(rename = "basic block filter index")]
2142    pub basic_block_filter_index: Option<IndexStatus>,
2143}
2144
2145impl<'a> serde::Serialize for PubKeyOrAddress<'a> {
2146    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
2147    where
2148        S: serde::Serializer,
2149    {
2150        match *self {
2151            PubKeyOrAddress::Address(a) => serde::Serialize::serialize(a, serializer),
2152            PubKeyOrAddress::PubKey(k) => serde::Serialize::serialize(k, serializer),
2153        }
2154    }
2155}
2156
2157fn deserialize_hex_array_opt<'de, D>(deserializer: D) -> Result<Option<Vec<Vec<u8>>>, D::Error>
2161where
2162    D: serde::Deserializer<'de>,
2163{
2164    let v: Vec<String> = Vec::deserialize(deserializer)?;
2168    let mut res = Vec::new();
2169    for h in v.into_iter() {
2170        res.push(FromHex::from_hex(&h).map_err(D::Error::custom)?);
2171    }
2172    Ok(Some(res))
2173}
2174
2175fn deserialize_bip70_network<'de, D>(deserializer: D) -> Result<Network, D::Error> 
2178where
2179    D: serde::Deserializer<'de>,
2180{
2181    struct NetworkVisitor;
2182    impl<'de> serde::de::Visitor<'de> for NetworkVisitor {
2183        type Value = Network;
2184
2185        fn visit_str<E: serde::de::Error>(self, s: &str) -> Result<Self::Value, E> {
2186            Network::from_core_arg(s)
2187                .map_err(|_| E::invalid_value(serde::de::Unexpected::Str(s), &"bitcoin network encoded as a string"))
2188        }
2189
2190        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
2191            write!(formatter, "bitcoin network encoded as a string")
2192        }
2193    }
2194
2195    deserializer.deserialize_str(NetworkVisitor)
2196}
2197
2198#[cfg(test)]
2199mod tests {
2200    use super::*;
2201
2202    #[test]
2203    fn test_softfork_type() {
2204        let buried: SoftforkType = serde_json::from_str("\"buried\"").unwrap();
2205        assert_eq!(buried, SoftforkType::Buried);
2206        let bip9: SoftforkType = serde_json::from_str("\"bip9\"").unwrap();
2207        assert_eq!(bip9, SoftforkType::Bip9);
2208        let other: SoftforkType = serde_json::from_str("\"bip8\"").unwrap();
2209        assert_eq!(other, SoftforkType::Other);
2210    }
2211}