digibyte_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 = "digibyte_rpc_json"]
17#![crate_type = "rlib"]
18
19pub extern crate digibyte;
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 digibyte::consensus::encode;
28use digibyte::hashes::hex::{FromHex, ToHex};
29use digibyte::hashes::sha256;
30use digibyte::util::{bip158, bip32};
31use digibyte::{Address, Amount, PrivateKey, PublicKey, Script, SignedAmount, Transaction};
32use serde::de::Error as SerdeError;
33use serde::{Deserialize, Serialize};
34
35//TODO(stevenroose) consider using a Time type
36
37/// A module used for serde serialization of bytes in hexadecimal format.
38///
39/// The module is compatible with the serde attribute.
40pub mod serde_hex {
41    use digibyte::hashes::hex::{FromHex, ToHex};
42    use serde::de::Error;
43    use serde::{Deserializer, Serializer};
44
45    pub fn serialize<S: Serializer>(b: &Vec<u8>, s: S) -> Result<S::Ok, S::Error> {
46        s.serialize_str(&b.to_hex())
47    }
48
49    pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result<Vec<u8>, D::Error> {
50        let hex_str: String = ::serde::Deserialize::deserialize(d)?;
51        Ok(FromHex::from_hex(&hex_str).map_err(D::Error::custom)?)
52    }
53
54    pub mod opt {
55        use digibyte::hashes::hex::{FromHex, ToHex};
56        use serde::de::Error;
57        use serde::{Deserializer, Serializer};
58
59        pub fn serialize<S: Serializer>(b: &Option<Vec<u8>>, s: S) -> Result<S::Ok, S::Error> {
60            match *b {
61                None => s.serialize_none(),
62                Some(ref b) => s.serialize_str(&b.to_hex()),
63            }
64        }
65
66        pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result<Option<Vec<u8>>, D::Error> {
67            let hex_str: String = ::serde::Deserialize::deserialize(d)?;
68            Ok(Some(FromHex::from_hex(&hex_str).map_err(D::Error::custom)?))
69        }
70    }
71}
72
73#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
74pub struct GetNetworkInfoResultNetwork {
75    pub name: String,
76    pub limited: bool,
77    pub reachable: bool,
78    pub proxy: String,
79    pub proxy_randomize_credentials: bool,
80}
81
82#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
83pub struct GetNetworkInfoResultAddress {
84    pub address: String,
85    pub port: usize,
86    pub score: usize,
87}
88
89#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
90pub struct GetNetworkInfoResult {
91    pub version: usize,
92    pub subversion: String,
93    #[serde(rename = "protocolversion")]
94    pub protocol_version: usize,
95    #[serde(rename = "localservices")]
96    pub local_services: String,
97    #[serde(rename = "localrelay")]
98    pub local_relay: bool,
99    #[serde(rename = "timeoffset")]
100    pub time_offset: isize,
101    pub connections: usize,
102    /// The number of inbound connections
103    /// Added in Bitcoin Core v0.21
104    pub connections_in: Option<usize>,
105    /// The number of outbound connections
106    /// Added in Bitcoin Core v0.21
107    pub connections_out: Option<usize>,
108    #[serde(rename = "networkactive")]
109    pub network_active: bool,
110    pub networks: Vec<GetNetworkInfoResultNetwork>,
111    #[serde(rename = "relayfee", with = "digibyte::util::amount::serde::as_dgb")]
112    pub relay_fee: Amount,
113    #[serde(rename = "incrementalfee", with = "digibyte::util::amount::serde::as_dgb")]
114    pub incremental_fee: Amount,
115    #[serde(rename = "localaddresses")]
116    pub local_addresses: Vec<GetNetworkInfoResultAddress>,
117    pub warnings: String,
118}
119
120#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
121#[serde(rename_all = "camelCase")]
122pub struct AddMultiSigAddressResult {
123    pub address: Address,
124    pub redeem_script: Script,
125}
126
127#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
128pub struct LoadWalletResult {
129    pub name: String,
130    pub warning: Option<String>,
131}
132
133#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
134pub struct GetWalletInfoResult {
135    #[serde(rename = "walletname")]
136    pub wallet_name: String,
137    #[serde(rename = "walletversion")]
138    pub wallet_version: u32,
139    #[serde(with = "digibyte::util::amount::serde::as_dgb")]
140    pub balance: Amount,
141    #[serde(with = "digibyte::util::amount::serde::as_dgb")]
142    pub unconfirmed_balance: Amount,
143    #[serde(with = "digibyte::util::amount::serde::as_dgb")]
144    pub immature_balance: Amount,
145    #[serde(rename = "txcount")]
146    pub tx_count: usize,
147    #[serde(rename = "keypoololdest")]
148    pub keypool_oldest: usize,
149    #[serde(rename = "keypoolsize")]
150    pub keypool_size: usize,
151    #[serde(rename = "keypoolsize_hd_internal")]
152    pub keypool_size_hd_internal: usize,
153    pub unlocked_until: Option<u64>,
154    #[serde(rename = "paytxfee", with = "digibyte::util::amount::serde::as_dgb")]
155    pub pay_tx_fee: Amount,
156    #[serde(rename = "hdseedid")]
157    pub hd_seed_id: Option<digibyte::XpubIdentifier>,
158    pub private_keys_enabled: bool,
159    pub avoid_reuse: Option<bool>,
160    pub scanning: Option<ScanningDetails>,
161}
162
163#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
164#[serde(untagged)]
165pub enum ScanningDetails {
166    Scanning {
167        duration: usize,
168        progress: f32,
169    },
170    /// The bool in this field will always be false.
171    NotScanning(bool),
172}
173
174impl Eq for ScanningDetails {}
175
176#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
177#[serde(rename_all = "camelCase")]
178pub struct GetBlockResult {
179    pub hash: digibyte::BlockHash,
180    pub confirmations: i32,
181    pub size: usize,
182    pub strippedsize: Option<usize>,
183    pub weight: usize,
184    pub height: usize,
185    pub version: i32,
186    #[serde(default, with = "::serde_hex::opt")]
187    pub version_hex: Option<Vec<u8>>,
188    pub merkleroot: digibyte::TxMerkleNode,
189    pub tx: Vec<digibyte::Txid>,
190    pub time: usize,
191    pub mediantime: Option<usize>,
192    pub nonce: u32,
193    pub bits: String,
194    pub difficulty: f64,
195    #[serde(with = "::serde_hex")]
196    pub chainwork: Vec<u8>,
197    pub n_tx: usize,
198    pub previousblockhash: Option<digibyte::BlockHash>,
199    pub nextblockhash: Option<digibyte::BlockHash>,
200}
201
202#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
203#[serde(rename_all = "camelCase")]
204pub struct GetBlockTxResult {
205    pub hash: digibyte::BlockHash,
206    pub confirmations: i32,
207    pub size: usize,
208    pub strippedsize: Option<usize>,
209    pub weight: usize,
210    pub height: usize,
211    pub version: i32,
212    #[serde(default, with = "::serde_hex::opt")]
213    pub version_hex: Option<Vec<u8>>,
214    pub merkleroot: digibyte::TxMerkleNode,
215    pub tx: Vec<GetRawTransactionResult>,
216    pub time: usize,
217    pub mediantime: Option<usize>,
218    pub nonce: u32,
219    pub bits: String,
220    pub difficulty: f64,
221    #[serde(with = "::serde_hex")]
222    pub chainwork: Vec<u8>,
223    pub n_tx: usize,
224    pub previousblockhash: Option<digibyte::BlockHash>,
225    pub nextblockhash: Option<digibyte::BlockHash>,
226}
227
228#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
229#[serde(rename_all = "camelCase")]
230pub struct GetBlockHeaderResult {
231    pub hash: digibyte::BlockHash,
232    pub confirmations: i32,
233    pub height: usize,
234    pub version: i32,
235    #[serde(default, with = "::serde_hex::opt")]
236    pub version_hex: Option<Vec<u8>>,
237    #[serde(rename = "merkleroot")]
238    pub merkle_root: digibyte::TxMerkleNode,
239    pub time: usize,
240    #[serde(rename = "mediantime")]
241    pub median_time: Option<usize>,
242    pub nonce: u32,
243    pub bits: String,
244    pub difficulty: f64,
245    #[serde(with = "::serde_hex")]
246    pub chainwork: Vec<u8>,
247    pub n_tx: usize,
248    #[serde(rename = "previousblockhash")]
249    pub previous_block_hash: Option<digibyte::BlockHash>,
250    #[serde(rename = "nextblockhash")]
251    pub next_block_hash: Option<digibyte::BlockHash>,
252}
253
254#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
255#[serde(rename_all = "camelCase")]
256pub struct GetMiningInfoResult {
257    pub blocks: u32,
258    #[serde(rename = "currentblockweight")]
259    pub current_block_weight: Option<u64>,
260    #[serde(rename = "currentblocktx")]
261    pub current_block_tx: Option<usize>,
262    pub difficulty: f64,
263    #[serde(rename = "networkhashps")]
264    pub network_hash_ps: f64,
265    #[serde(rename = "pooledtx")]
266    pub pooled_tx: usize,
267    pub chain: String,
268    pub warnings: String,
269}
270
271#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
272#[serde(rename_all = "camelCase")]
273pub struct GetRawTransactionResultVinScriptSig {
274    pub asm: String,
275    #[serde(with = "::serde_hex")]
276    pub hex: Vec<u8>,
277}
278
279impl GetRawTransactionResultVinScriptSig {
280    pub fn script(&self) -> Result<Script, encode::Error> {
281        Ok(Script::from(self.hex.clone()))
282    }
283}
284
285#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
286#[serde(rename_all = "camelCase")]
287pub struct GetRawTransactionResultVin {
288    pub sequence: u32,
289    /// The raw scriptSig in case of a coinbase tx.
290    #[serde(default, with = "::serde_hex::opt")]
291    pub coinbase: Option<Vec<u8>>,
292    /// Not provided for coinbase txs.
293    pub txid: Option<digibyte::Txid>,
294    /// Not provided for coinbase txs.
295    pub vout: Option<u32>,
296    /// The scriptSig in case of a non-coinbase tx.
297    pub script_sig: Option<GetRawTransactionResultVinScriptSig>,
298    /// Not provided for coinbase txs.
299    #[serde(default, deserialize_with = "deserialize_hex_array_opt")]
300    pub txinwitness: Option<Vec<Vec<u8>>>,
301}
302
303impl GetRawTransactionResultVin {
304    /// Whether this input is from a coinbase tx.
305    /// The [txid], [vout] and [script_sig] fields are not provided
306    /// for coinbase transactions.
307    pub fn is_coinbase(&self) -> bool {
308        self.coinbase.is_some()
309    }
310}
311
312#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
313#[serde(rename_all = "camelCase")]
314pub struct GetRawTransactionResultVoutScriptPubKey {
315    pub asm: String,
316    #[serde(with = "::serde_hex")]
317    pub hex: Vec<u8>,
318    pub req_sigs: Option<usize>,
319    #[serde(rename = "type")]
320    pub type_: Option<ScriptPubkeyType>,
321    pub addresses: Option<Vec<Address>>,
322}
323
324impl GetRawTransactionResultVoutScriptPubKey {
325    pub fn script(&self) -> Result<Script, encode::Error> {
326        Ok(Script::from(self.hex.clone()))
327    }
328}
329
330#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
331#[serde(rename_all = "camelCase")]
332pub struct GetRawTransactionResultVout {
333    #[serde(with = "digibyte::util::amount::serde::as_dgb")]
334    pub value: Amount,
335    pub n: u32,
336    pub script_pub_key: GetRawTransactionResultVoutScriptPubKey,
337}
338
339#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
340#[serde(rename_all = "camelCase")]
341pub struct GetRawTransactionResult {
342    #[serde(rename = "in_active_chain")]
343    pub in_active_chain: Option<bool>,
344    #[serde(with = "::serde_hex")]
345    pub hex: Vec<u8>,
346    pub txid: digibyte::Txid,
347    pub hash: digibyte::Wtxid,
348    pub size: usize,
349    pub vsize: usize,
350    pub version: u32,
351    pub locktime: u32,
352    pub vin: Vec<GetRawTransactionResultVin>,
353    pub vout: Vec<GetRawTransactionResultVout>,
354    pub blockhash: Option<digibyte::BlockHash>,
355    pub confirmations: Option<u32>,
356    pub time: Option<usize>,
357    pub blocktime: Option<usize>,
358}
359
360#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
361pub struct GetBlockFilterResult {
362    pub header: digibyte::FilterHash,
363    #[serde(with = "::serde_hex")]
364    pub filter: Vec<u8>,
365}
366
367impl GetBlockFilterResult {
368    /// Get the filter.
369    /// Note that this copies the underlying filter data. To prevent this,
370    /// use [into_filter] instead.
371    pub fn to_filter(&self) -> bip158::BlockFilter {
372        bip158::BlockFilter::new(&self.filter)
373    }
374
375    /// Convert the result in the filter type.
376    pub fn into_filter(self) -> bip158::BlockFilter {
377        bip158::BlockFilter {
378            content: self.filter,
379        }
380    }
381}
382
383impl GetRawTransactionResult {
384    /// Whether this tx is a coinbase tx.
385    pub fn is_coinbase(&self) -> bool {
386        self.vin.len() == 1 && self.vin[0].is_coinbase()
387    }
388
389    pub fn transaction(&self) -> Result<Transaction, encode::Error> {
390        Ok(encode::deserialize(&self.hex)?)
391    }
392}
393
394/// Enum to represent the BIP125 replaceable status for a transaction.
395#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
396#[serde(rename_all = "lowercase")]
397pub enum Bip125Replaceable {
398    Yes,
399    No,
400    Unknown,
401}
402
403/// Enum to represent the category of a transaction.
404#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
405#[serde(rename_all = "lowercase")]
406pub enum GetTransactionResultDetailCategory {
407    Send,
408    Receive,
409    Generate,
410    Immature,
411    Orphan,
412}
413
414#[derive(Clone, PartialEq, Eq, Debug, Deserialize)]
415pub struct GetTransactionResultDetail {
416    pub address: Option<Address>,
417    pub category: GetTransactionResultDetailCategory,
418    #[serde(with = "digibyte::util::amount::serde::as_dgb")]
419    pub amount: SignedAmount,
420    pub label: Option<String>,
421    pub vout: u32,
422    #[serde(default, with = "digibyte::util::amount::serde::as_dgb::opt")]
423    pub fee: Option<SignedAmount>,
424    pub abandoned: Option<bool>,
425}
426
427#[derive(Clone, PartialEq, Eq, Debug, Deserialize)]
428pub struct WalletTxInfo {
429    pub confirmations: i32,
430    pub blockhash: Option<digibyte::BlockHash>,
431    pub blockindex: Option<usize>,
432    pub blocktime: Option<u64>,
433    pub blockheight: Option<u32>,
434    pub txid: digibyte::Txid,
435    pub time: u64,
436    pub timereceived: u64,
437    #[serde(rename = "bip125-replaceable")]
438    pub bip125_replaceable: Bip125Replaceable,
439    /// Conflicting transaction ids
440    #[serde(rename = "walletconflicts")]
441    pub wallet_conflicts: Vec<digibyte::Txid>,
442}
443
444#[derive(Clone, PartialEq, Eq, Debug, Deserialize)]
445pub struct GetTransactionResult {
446    #[serde(flatten)]
447    pub info: WalletTxInfo,
448    #[serde(with = "digibyte::util::amount::serde::as_dgb")]
449    pub amount: SignedAmount,
450    #[serde(default, with = "digibyte::util::amount::serde::as_dgb::opt")]
451    pub fee: Option<SignedAmount>,
452    pub details: Vec<GetTransactionResultDetail>,
453    #[serde(with = "::serde_hex")]
454    pub hex: Vec<u8>,
455}
456
457impl GetTransactionResult {
458    pub fn transaction(&self) -> Result<Transaction, encode::Error> {
459        Ok(encode::deserialize(&self.hex)?)
460    }
461}
462
463#[derive(Clone, PartialEq, Eq, Debug, Deserialize)]
464pub struct ListTransactionResult {
465    #[serde(flatten)]
466    pub info: WalletTxInfo,
467    #[serde(flatten)]
468    pub detail: GetTransactionResultDetail,
469
470    pub trusted: Option<bool>,
471    pub comment: Option<String>,
472}
473
474#[derive(Clone, PartialEq, Eq, Debug, Deserialize)]
475pub struct ListSinceBlockResult {
476    pub transactions: Vec<ListTransactionResult>,
477    #[serde(default)]
478    pub removed: Vec<ListTransactionResult>,
479    pub lastblock: digibyte::BlockHash,
480}
481
482#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
483#[serde(rename_all = "camelCase")]
484pub struct GetTxOutResult {
485    pub bestblock: digibyte::BlockHash,
486    pub confirmations: u32,
487    #[serde(with = "digibyte::util::amount::serde::as_dgb")]
488    pub value: Amount,
489    pub script_pub_key: GetRawTransactionResultVoutScriptPubKey,
490    pub coinbase: bool,
491}
492
493#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize, Default)]
494#[serde(rename_all = "camelCase")]
495pub struct ListUnspentQueryOptions {
496    #[serde(
497        rename = "minimumAmount",
498        with = "digibyte::util::amount::serde::as_dgb::opt",
499        skip_serializing_if = "Option::is_none"
500    )]
501    pub minimum_amount: Option<Amount>,
502    #[serde(
503        rename = "maximumAmount",
504        with = "digibyte::util::amount::serde::as_dgb::opt",
505        skip_serializing_if = "Option::is_none"
506    )]
507    pub maximum_amount: Option<Amount>,
508    #[serde(rename = "maximumCount", skip_serializing_if = "Option::is_none")]
509    pub maximum_count: Option<usize>,
510    #[serde(
511        rename = "minimumSumAmount",
512        with = "digibyte::util::amount::serde::as_dgb::opt",
513        skip_serializing_if = "Option::is_none"
514    )]
515    pub minimum_sum_amount: Option<Amount>,
516}
517
518#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
519#[serde(rename_all = "camelCase")]
520pub struct ListUnspentResultEntry {
521    pub txid: digibyte::Txid,
522    pub vout: u32,
523    pub address: Option<Address>,
524    pub label: Option<String>,
525    pub redeem_script: Option<Script>,
526    pub witness_script: Option<Script>,
527    pub script_pub_key: Script,
528    #[serde(with = "digibyte::util::amount::serde::as_dgb")]
529    pub amount: Amount,
530    pub confirmations: u32,
531    pub spendable: bool,
532    pub solvable: bool,
533    #[serde(rename = "desc")]
534    pub descriptor: Option<String>,
535    pub safe: bool,
536}
537
538#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
539#[serde(rename_all = "camelCase")]
540pub struct ListReceivedByAddressResult {
541    #[serde(default, rename = "involvesWatchonly")]
542    pub involved_watch_only: bool,
543    pub address: Address,
544    #[serde(with = "digibyte::util::amount::serde::as_dgb")]
545    pub amount: Amount,
546    pub confirmations: u32,
547    pub label: String,
548    pub txids: Vec<digibyte::Txid>,
549}
550
551#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
552#[serde(rename_all = "camelCase")]
553pub struct SignRawTransactionResultError {
554    pub txid: digibyte::Txid,
555    pub vout: u32,
556    pub script_sig: Script,
557    pub sequence: u32,
558    pub error: String,
559}
560
561#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
562#[serde(rename_all = "camelCase")]
563pub struct SignRawTransactionResult {
564    #[serde(with = "::serde_hex")]
565    pub hex: Vec<u8>,
566    pub complete: bool,
567    pub errors: Option<Vec<SignRawTransactionResultError>>,
568}
569
570impl SignRawTransactionResult {
571    pub fn transaction(&self) -> Result<Transaction, encode::Error> {
572        Ok(encode::deserialize(&self.hex)?)
573    }
574}
575
576#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
577pub struct TestMempoolAcceptResult {
578    pub txid: digibyte::Txid,
579    pub allowed: bool,
580    #[serde(rename = "reject-reason")]
581    pub reject_reason: Option<String>,
582    /// Virtual transaction size as defined in BIP 141 (only present when 'allowed' is true)
583    /// Added in Bitcoin Core v0.21
584    pub vsize: Option<u64>,
585    /// Transaction fees (only present if 'allowed' is true)
586    /// Added in Bitcoin Core v0.21
587    pub fees: Option<TestMempoolAcceptResultFees>,
588}
589
590#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
591pub struct TestMempoolAcceptResultFees {
592    /// Transaction fee in BTC
593    #[serde(with = "digibyte::util::amount::serde::as_dgb")]
594    pub base: Amount,
595    // unlike GetMempoolEntryResultFees, this only has the `base` fee
596}
597
598#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
599#[serde(rename_all = "snake_case")]
600pub enum Bip9SoftforkStatus {
601    Defined,
602    Started,
603    LockedIn,
604    Active,
605    Failed,
606}
607
608#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
609pub struct Bip9SoftforkStatistics {
610    pub period: u32,
611    pub threshold: u32,
612    pub elapsed: u32,
613    pub count: u32,
614    pub possible: bool,
615}
616
617#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
618pub struct Bip9SoftforkInfo {
619    pub status: Bip9SoftforkStatus,
620    pub bit: Option<u8>,
621    // Can be -1 for 0.18.x inactive ones.
622    pub start_time: i64,
623    pub timeout: u64,
624    pub since: u32,
625    pub statistics: Option<Bip9SoftforkStatistics>,
626}
627
628#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
629#[serde(rename_all = "lowercase")]
630pub enum SoftforkType {
631    Buried,
632    Bip9,
633}
634
635/// Status of a softfork
636#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
637pub struct Softfork {
638    #[serde(rename = "type")]
639    pub type_: SoftforkType,
640    pub bip9: Option<Bip9SoftforkInfo>,
641    pub height: Option<u32>,
642    pub active: bool,
643}
644
645#[allow(non_camel_case_types)]
646#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
647#[serde(rename_all = "lowercase")]
648pub enum ScriptPubkeyType {
649    Nonstandard,
650    Pubkey,
651    PubkeyHash,
652    ScriptHash,
653    MultiSig,
654    NullData,
655    Witness_v0_KeyHash,
656    Witness_v0_ScriptHash,
657    Witness_Unknown,
658}
659
660#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
661pub struct GetAddressInfoResultEmbedded {
662    pub address: Address,
663    #[serde(rename = "scriptPubKey")]
664    pub script_pub_key: Script,
665    #[serde(rename = "is_script")]
666    pub is_script: Option<bool>,
667    #[serde(rename = "is_witness")]
668    pub is_witness: Option<bool>,
669    pub witness_version: Option<u32>,
670    #[serde(with = "::serde_hex")]
671    pub witness_program: Vec<u8>,
672    pub script: Option<ScriptPubkeyType>,
673    /// The redeemscript for the p2sh address.
674    #[serde(default, with = "::serde_hex::opt")]
675    pub hex: Option<Vec<u8>>,
676    pub pubkeys: Option<Vec<PublicKey>>,
677    #[serde(rename = "sigsrequired")]
678    pub n_signatures_required: Option<usize>,
679    pub pubkey: Option<PublicKey>,
680    #[serde(rename = "is_compressed")]
681    pub is_compressed: Option<bool>,
682    pub label: Option<String>,
683    #[serde(rename = "hdkeypath")]
684    pub hd_key_path: Option<bip32::DerivationPath>,
685    #[serde(rename = "hdseedid")]
686    pub hd_seed_id: Option<digibyte::XpubIdentifier>,
687    #[serde(default)]
688    pub labels: Vec<GetAddressInfoResultLabel>,
689}
690
691#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
692#[serde(rename_all = "lowercase")]
693pub enum GetAddressInfoResultLabelPurpose {
694    Send,
695    Receive,
696}
697
698#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
699#[serde(untagged)]
700pub enum GetAddressInfoResultLabel {
701    Simple(String),
702    WithPurpose {
703        name: String,
704        purpose: GetAddressInfoResultLabelPurpose,
705    },
706}
707
708#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
709pub struct GetAddressInfoResult {
710    pub address: Address,
711    #[serde(rename = "scriptPubKey")]
712    pub script_pub_key: Script,
713    #[serde(rename = "ismine")]
714    pub is_mine: Option<bool>,
715    #[serde(rename = "iswatchonly")]
716    pub is_watchonly: Option<bool>,
717    #[serde(rename = "isscript")]
718    pub is_script: Option<bool>,
719    #[serde(rename = "iswitness")]
720    pub is_witness: Option<bool>,
721    pub witness_version: Option<u32>,
722    #[serde(default, with = "::serde_hex::opt")]
723    pub witness_program: Option<Vec<u8>>,
724    pub script: Option<ScriptPubkeyType>,
725    /// The redeemscript for the p2sh address.
726    #[serde(default, with = "::serde_hex::opt")]
727    pub hex: Option<Vec<u8>>,
728    pub pubkeys: Option<Vec<PublicKey>>,
729    #[serde(rename = "sigsrequired")]
730    pub n_signatures_required: Option<usize>,
731    pub pubkey: Option<PublicKey>,
732    /// Information about the address embedded in P2SH or P2WSH, if relevant and known.
733    pub embedded: Option<GetAddressInfoResultEmbedded>,
734    #[serde(rename = "is_compressed")]
735    pub is_compressed: Option<bool>,
736    pub timestamp: Option<u64>,
737    #[serde(rename = "hdkeypath")]
738    pub hd_key_path: Option<bip32::DerivationPath>,
739    #[serde(rename = "hdseedid")]
740    pub hd_seed_id: Option<digibyte::XpubIdentifier>,
741    pub labels: Vec<GetAddressInfoResultLabel>,
742    /// Deprecated in v0.20.0. See `labels` field instead.
743    #[deprecated(note = "since Core v0.20.0")]
744    pub label: Option<String>,
745}
746
747/// Models the result of "getblockchaininfo"
748#[derive(Clone, Debug, Deserialize, Serialize)]
749pub struct GetBlockchainInfoResult {
750    /// Current network name as defined in BIP70 (main, test, regtest)
751    pub chain: String,
752    /// The current number of blocks processed in the server
753    pub blocks: u64,
754    /// The current number of headers we have validated
755    pub headers: u64,
756    /// The hash of the currently best block
757    #[serde(rename = "bestblockhash")]
758    pub best_block_hash: digibyte::BlockHash,
759    /// The current difficulty
760    pub difficulty: f64,
761    /// Median time for the current best block
762    #[serde(rename = "mediantime")]
763    pub median_time: u64,
764    /// Estimate of verification progress [0..1]
765    #[serde(rename = "verificationprogress")]
766    pub verification_progress: f64,
767    /// Estimate of whether this node is in Initial Block Download mode
768    #[serde(rename = "initialblockdownload")]
769    pub initial_block_download: bool,
770    /// Total amount of work in active chain, in hexadecimal
771    #[serde(rename = "chainwork", with = "::serde_hex")]
772    pub chain_work: Vec<u8>,
773    /// The estimated size of the block and undo files on disk
774    pub size_on_disk: u64,
775    /// If the blocks are subject to pruning
776    pub pruned: bool,
777    /// Lowest-height complete block stored (only present if pruning is enabled)
778    #[serde(rename = "pruneheight")]
779    pub prune_height: Option<u64>,
780    /// Whether automatic pruning is enabled (only present if pruning is enabled)
781    pub automatic_pruning: Option<bool>,
782    /// The target size used by pruning (only present if automatic pruning is enabled)
783    pub prune_target_size: Option<u64>,
784    /// Status of softforks in progress
785    #[serde(default)]
786    pub softforks: HashMap<String, Softfork>,
787    /// Any network and blockchain warnings.
788    pub warnings: String,
789}
790
791#[derive(Clone, PartialEq, Eq, Debug)]
792pub enum ImportMultiRequestScriptPubkey<'a> {
793    Address(&'a Address),
794    Script(&'a Script),
795}
796
797#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
798pub struct GetMempoolEntryResult {
799    /// Virtual transaction size as defined in BIP 141. This is different from actual serialized
800    /// size for witness transactions as witness data is discounted.
801    #[serde(alias = "size")]
802    pub vsize: u64,
803    /// Transaction weight as defined in BIP 141. Added in Core v0.19.0.
804    pub weight: Option<u64>,
805    /// Local time transaction entered pool in seconds since 1 Jan 1970 GMT
806    pub time: u64,
807    /// Block height when transaction entered pool
808    pub height: u64,
809    /// Number of in-mempool descendant transactions (including this one)
810    #[serde(rename = "descendantcount")]
811    pub descendant_count: u64,
812    /// Virtual transaction size of in-mempool descendants (including this one)
813    #[serde(rename = "descendantsize")]
814    pub descendant_size: u64,
815    /// Number of in-mempool ancestor transactions (including this one)
816    #[serde(rename = "ancestorcount")]
817    pub ancestor_count: u64,
818    /// Virtual transaction size of in-mempool ancestors (including this one)
819    #[serde(rename = "ancestorsize")]
820    pub ancestor_size: u64,
821    /// Hash of serialized transaction, including witness data
822    pub wtxid: digibyte::Txid,
823    /// Fee information
824    pub fees: GetMempoolEntryResultFees,
825    /// Unconfirmed transactions used as inputs for this transaction
826    pub depends: Vec<digibyte::Txid>,
827    /// Unconfirmed transactions spending outputs from this transaction
828    #[serde(rename = "spentby")]
829    pub spent_by: Vec<digibyte::Txid>,
830    /// Whether this transaction could be replaced due to BIP125 (replace-by-fee)
831    #[serde(rename = "bip125-replaceable")]
832    pub bip125_replaceable: bool,
833    /// Whether this transaction is currently unbroadcast (initial broadcast not yet acknowledged by any peers)
834    /// Added in Bitcoin Core v0.21
835    pub unbroadcast: Option<bool>,
836}
837
838#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
839pub struct GetMempoolEntryResultFees {
840    /// Transaction fee in BTC
841    #[serde(with = "digibyte::util::amount::serde::as_dgb")]
842    pub base: Amount,
843    /// Transaction fee with fee deltas used for mining priority in BTC
844    #[serde(with = "digibyte::util::amount::serde::as_dgb")]
845    pub modified: Amount,
846    /// Modified fees (see above) of in-mempool ancestors (including this one) in BTC
847    #[serde(with = "digibyte::util::amount::serde::as_dgb")]
848    pub ancestor: Amount,
849    /// Modified fees (see above) of in-mempool descendants (including this one) in BTC
850    #[serde(with = "digibyte::util::amount::serde::as_dgb")]
851    pub descendant: Amount,
852}
853
854impl<'a> serde::Serialize for ImportMultiRequestScriptPubkey<'a> {
855    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
856    where
857        S: serde::Serializer,
858    {
859        match *self {
860            ImportMultiRequestScriptPubkey::Address(ref addr) => {
861                #[derive(Serialize)]
862                struct Tmp<'a> {
863                    pub address: &'a Address,
864                };
865                serde::Serialize::serialize(
866                    &Tmp {
867                        address: addr,
868                    },
869                    serializer,
870                )
871            }
872            ImportMultiRequestScriptPubkey::Script(script) => {
873                serializer.serialize_str(&script.as_bytes().to_hex())
874            }
875        }
876    }
877}
878
879/// A import request for importmulti.
880///
881/// Note: unlike in bitcoind, `timestamp` defaults to 0.
882#[derive(Clone, PartialEq, Eq, Debug, Default, Serialize)]
883pub struct ImportMultiRequest<'a> {
884    pub timestamp: ImportMultiRescanSince,
885    /// If using descriptor, do not also provide address/scriptPubKey, scripts, or pubkeys.
886    #[serde(rename = "desc", skip_serializing_if = "Option::is_none")]
887    pub descriptor: Option<&'a str>,
888    #[serde(rename = "scriptPubKey", skip_serializing_if = "Option::is_none")]
889    pub script_pubkey: Option<ImportMultiRequestScriptPubkey<'a>>,
890    #[serde(rename = "redeemscript", skip_serializing_if = "Option::is_none")]
891    pub redeem_script: Option<&'a Script>,
892    #[serde(rename = "witnessscript", skip_serializing_if = "Option::is_none")]
893    pub witness_script: Option<&'a Script>,
894    #[serde(skip_serializing_if = "<[_]>::is_empty")]
895    pub pubkeys: &'a [PublicKey],
896    #[serde(skip_serializing_if = "<[_]>::is_empty")]
897    pub keys: &'a [PrivateKey],
898    #[serde(skip_serializing_if = "Option::is_none")]
899    pub range: Option<(usize, usize)>,
900    #[serde(skip_serializing_if = "Option::is_none")]
901    pub internal: Option<bool>,
902    #[serde(skip_serializing_if = "Option::is_none")]
903    pub watchonly: Option<bool>,
904    #[serde(skip_serializing_if = "Option::is_none")]
905    pub label: Option<&'a str>,
906    #[serde(skip_serializing_if = "Option::is_none")]
907    pub keypool: Option<bool>,
908}
909
910#[derive(Clone, PartialEq, Eq, Debug, Default, Deserialize, Serialize)]
911pub struct ImportMultiOptions {
912    #[serde(skip_serializing_if = "Option::is_none")]
913    pub rescan: Option<bool>,
914}
915
916#[derive(Clone, PartialEq, Eq, Copy, Debug)]
917pub enum ImportMultiRescanSince {
918    Now,
919    Timestamp(u64),
920}
921
922impl serde::Serialize for ImportMultiRescanSince {
923    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
924    where
925        S: serde::Serializer,
926    {
927        match *self {
928            ImportMultiRescanSince::Now => serializer.serialize_str("now"),
929            ImportMultiRescanSince::Timestamp(timestamp) => serializer.serialize_u64(timestamp),
930        }
931    }
932}
933
934impl<'de> serde::Deserialize<'de> for ImportMultiRescanSince {
935    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
936    where
937        D: serde::Deserializer<'de>,
938    {
939        use serde::de;
940        use std::fmt;
941        struct Visitor;
942        impl<'de> de::Visitor<'de> for Visitor {
943            type Value = ImportMultiRescanSince;
944
945            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
946                write!(formatter, "unix timestamp or 'now'")
947            }
948
949            fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
950            where
951                E: de::Error,
952            {
953                Ok(ImportMultiRescanSince::Timestamp(value))
954            }
955
956            fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
957            where
958                E: de::Error,
959            {
960                if value == "now" {
961                    Ok(ImportMultiRescanSince::Now)
962                } else {
963                    Err(de::Error::custom(format!(
964                        "invalid str '{}', expecting 'now' or unix timestamp",
965                        value
966                    )))
967                }
968            }
969        }
970        deserializer.deserialize_any(Visitor)
971    }
972}
973
974impl Default for ImportMultiRescanSince {
975    fn default() -> Self {
976        ImportMultiRescanSince::Timestamp(0)
977    }
978}
979
980impl From<u64> for ImportMultiRescanSince {
981    fn from(timestamp: u64) -> Self {
982        ImportMultiRescanSince::Timestamp(timestamp)
983    }
984}
985
986impl From<Option<u64>> for ImportMultiRescanSince {
987    fn from(timestamp: Option<u64>) -> Self {
988        timestamp.map_or(ImportMultiRescanSince::Now, ImportMultiRescanSince::Timestamp)
989    }
990}
991
992#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
993pub struct ImportMultiResultError {
994    pub code: i64,
995    pub message: String,
996}
997
998#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
999pub struct ImportMultiResult {
1000    pub success: bool,
1001    #[serde(default)]
1002    pub warnings: Vec<String>,
1003    pub error: Option<ImportMultiResultError>,
1004}
1005
1006/// Progress toward rejecting pre-softfork blocks
1007#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1008pub struct RejectStatus {
1009    /// `true` if threshold reached
1010    pub status: bool,
1011}
1012
1013/// Models the result of "getpeerinfo"
1014#[derive(Clone, Debug, Deserialize, Serialize)]
1015pub struct GetPeerInfoResult {
1016    /// Peer index
1017    pub id: u64,
1018    /// The IP address and port of the peer
1019    // TODO: use a type for addr
1020    pub addr: String,
1021    /// Bind address of the connection to the peer
1022    // TODO: use a type for addrbind
1023    pub addrbind: String,
1024    /// Local address as reported by the peer
1025    // TODO: use a type for addrlocal
1026    pub addrlocal: Option<String>,
1027    /// Network (ipv4, ipv6, or onion) the peer connected throug
1028    /// Added in Bitcoin Core v0.21
1029    pub network: Option<GetPeerInfoResultNetwork>,
1030    /// The services offered
1031    // TODO: use a type for services
1032    pub services: String,
1033    /// Whether peer has asked us to relay transactions to it
1034    pub relaytxes: bool,
1035    /// The time in seconds since epoch (Jan 1 1970 GMT) of the last send
1036    pub lastsend: u64,
1037    /// The time in seconds since epoch (Jan 1 1970 GMT) of the last receive
1038    pub lastrecv: u64,
1039    /// The time in seconds since epoch (Jan 1 1970 GMT) of the last valid transaction received from this peer
1040    /// Added in Bitcoin Core v0.21
1041    pub last_transaction: Option<u64>,
1042    /// The time in seconds since epoch (Jan 1 1970 GMT) of the last block received from this peer
1043    /// Added in Bitcoin Core v0.21
1044    pub last_block: Option<u64>,
1045    /// The total bytes sent
1046    pub bytessent: u64,
1047    /// The total bytes received
1048    pub bytesrecv: u64,
1049    /// The connection time in seconds since epoch (Jan 1 1970 GMT)
1050    pub conntime: u64,
1051    /// The time offset in seconds
1052    pub timeoffset: i64,
1053    /// ping time (if available)
1054    pub pingtime: Option<f64>,
1055    /// minimum observed ping time (if any at all)
1056    pub minping: Option<f64>,
1057    /// ping wait (if non-zero)
1058    pub pingwait: Option<f64>,
1059    /// The peer version, such as 70001
1060    pub version: u64,
1061    /// The string version
1062    pub subver: String,
1063    /// Inbound (true) or Outbound (false)
1064    pub inbound: bool,
1065    /// Whether connection was due to `addnode`/`-connect` or if it was an
1066    /// automatic/inbound connection
1067    /// Deprecated in Bitcoin Core v0.21
1068    pub addnode: Option<bool>,
1069    /// The starting height (block) of the peer
1070    pub startingheight: i64,
1071    /// The ban score
1072    /// Deprecated in Bitcoin Core v0.21
1073    pub banscore: Option<i64>,
1074    /// The last header we have in common with this peer
1075    pub synced_headers: i64,
1076    /// The last block we have in common with this peer
1077    pub synced_blocks: i64,
1078    /// The heights of blocks we're currently asking from this peer
1079    pub inflight: Vec<u64>,
1080    /// Whether the peer is whitelisted
1081    /// Deprecated in Bitcoin Core v0.21
1082    pub whitelisted: Option<bool>,
1083    #[serde(rename = "minfeefilter", default, with = "digibyte::util::amount::serde::as_dgb::opt")]
1084    pub min_fee_filter: Option<Amount>,
1085    /// The total bytes sent aggregated by message type
1086    pub bytessent_per_msg: HashMap<String, u64>,
1087    /// The total bytes received aggregated by message type
1088    pub bytesrecv_per_msg: HashMap<String, u64>,
1089    /// The type of the connection
1090    /// Added in Bitcoin Core v0.21
1091    pub connection_type: Option<GetPeerInfoResultConnectionType>,
1092}
1093
1094#[derive(Copy, Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
1095#[serde(rename_all = "lowercase")]
1096pub enum GetPeerInfoResultNetwork {
1097    Ipv4,
1098    Ipv6,
1099    Onion,
1100    // this is undocumented upstream
1101    Unroutable,
1102}
1103
1104#[derive(Copy, Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
1105#[serde(rename_all = "kebab-case")]
1106pub enum GetPeerInfoResultConnectionType {
1107    OutboundFullRelay,
1108    BlockRelayOnly,
1109    Inbound,
1110    Manual,
1111    AddrFetch,
1112    Feeler,
1113}
1114
1115/// Models the result of "estimatesmartfee"
1116#[derive(Clone, Debug, Deserialize, Serialize)]
1117pub struct EstimateSmartFeeResult {
1118    /// Estimate fee rate in BTC/kB.
1119    #[serde(
1120        default,
1121        rename = "feerate",
1122        skip_serializing_if = "Option::is_none",
1123        with = "digibyte::util::amount::serde::as_dgb::opt"
1124    )]
1125    pub fee_rate: Option<Amount>,
1126    /// Errors encountered during processing.
1127    pub errors: Option<Vec<String>>,
1128    /// Block number where estimate was found.
1129    pub blocks: i64,
1130}
1131
1132/// Models the result of "waitfornewblock", and "waitforblock"
1133#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1134pub struct BlockRef {
1135    pub hash: digibyte::BlockHash,
1136    pub height: u64,
1137}
1138
1139/// Models the result of "getdescriptorinfo"
1140#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1141pub struct GetDescriptorInfoResult {
1142    pub descriptor: String,
1143    pub checksum: String,
1144    #[serde(rename = "isrange")]
1145    pub is_range: bool,
1146    #[serde(rename = "issolvable")]
1147    pub is_solvable: bool,
1148    #[serde(rename = "hasprivatekeys")]
1149    pub has_private_keys: bool,
1150}
1151
1152/// Models the result of "walletcreatefundedpsbt"
1153#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1154pub struct WalletCreateFundedPsbtResult {
1155    pub psbt: String,
1156    #[serde(with = "digibyte::util::amount::serde::as_dgb")]
1157    pub fee: Amount,
1158    #[serde(rename = "changepos")]
1159    pub change_position: i32,
1160}
1161
1162/// Models the result of "walletprocesspsbt"
1163#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1164pub struct WalletProcessPsbtResult {
1165    pub psbt: String,
1166    pub complete: bool,
1167}
1168
1169/// Models the request for "walletcreatefundedpsbt"
1170#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize, Default)]
1171pub struct WalletCreateFundedPsbtOptions {
1172    /// For a transaction with existing inputs, automatically include more if they are not enough (default true).
1173    /// Added in Bitcoin Core v0.21
1174    #[serde(skip_serializing_if = "Option::is_none")]
1175    pub add_inputs: Option<bool>,
1176    #[serde(rename = "changeAddress", skip_serializing_if = "Option::is_none")]
1177    pub change_address: Option<Address>,
1178    #[serde(rename = "changePosition", skip_serializing_if = "Option::is_none")]
1179    pub change_position: Option<u16>,
1180    #[serde(skip_serializing_if = "Option::is_none")]
1181    pub change_type: Option<AddressType>,
1182    #[serde(rename = "includeWatching", skip_serializing_if = "Option::is_none")]
1183    pub include_watching: Option<bool>,
1184    #[serde(rename = "lockUnspents", skip_serializing_if = "Option::is_none")]
1185    pub lock_unspent: Option<bool>,
1186    #[serde(
1187        rename = "feeRate",
1188        skip_serializing_if = "Option::is_none",
1189        with = "digibyte::util::amount::serde::as_dgb::opt"
1190    )]
1191    pub fee_rate: Option<Amount>,
1192    #[serde(rename = "subtractFeeFromOutputs", skip_serializing_if = "Vec::is_empty")]
1193    pub subtract_fee_from_outputs: Vec<u16>,
1194    #[serde(skip_serializing_if = "Option::is_none")]
1195    pub replaceable: Option<bool>,
1196    #[serde(skip_serializing_if = "Option::is_none")]
1197    pub conf_target: Option<u16>,
1198    #[serde(skip_serializing_if = "Option::is_none")]
1199    pub estimate_mode: Option<EstimateMode>,
1200}
1201
1202/// Models the result of "finalizepsbt"
1203#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1204pub struct FinalizePsbtResult {
1205    pub psbt: Option<String>,
1206    #[serde(default, with = "::serde_hex::opt")]
1207    pub hex: Option<Vec<u8>>,
1208    pub complete: bool,
1209}
1210
1211/// Models the result of "getchaintips"
1212pub type GetChainTipsResult = Vec<GetChainTipsResultTip>;
1213
1214/// Models a single chain tip for the result of "getchaintips"
1215#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1216pub struct GetChainTipsResultTip {
1217    /// Block height of the chain tip
1218    pub height: u64,
1219    /// Header hash of the chain tip
1220    pub hash: digibyte::BlockHash,
1221    /// Length of the branch (number of blocks since the last common block)
1222    #[serde(rename = "branchlen")]
1223    pub branch_length: usize,
1224    /// Status of the tip as seen by Bitcoin Core
1225    pub status: GetChainTipsResultStatus,
1226}
1227
1228#[derive(Copy, Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
1229#[serde(rename_all = "lowercase")]
1230pub enum GetChainTipsResultStatus {
1231    /// The branch contains at least one invalid block
1232    Invalid,
1233    /// Not all blocks for this branch are available, but the headers are valid
1234    #[serde(rename = "headers-only")]
1235    HeadersOnly,
1236    /// All blocks are available for this branch, but they were never fully validated
1237    #[serde(rename = "valid-headers")]
1238    ValidHeaders,
1239    /// This branch is not part of the active chain, but is fully validated
1240    #[serde(rename = "valid-fork")]
1241    ValidFork,
1242    /// This is the tip of the active main chain, which is certainly valid
1243    Active,
1244}
1245
1246impl FinalizePsbtResult {
1247    pub fn transaction(&self) -> Option<Result<Transaction, encode::Error>> {
1248        self.hex.as_ref().map(|h| encode::deserialize(h))
1249    }
1250}
1251
1252// Custom types for input arguments.
1253
1254#[derive(Serialize, Deserialize, Debug, Clone, Copy, Eq, PartialEq, Hash)]
1255#[serde(rename_all = "UPPERCASE")]
1256pub enum EstimateMode {
1257    Unset,
1258    Economical,
1259    Conservative,
1260}
1261
1262/// A wrapper around bitcoin::SigHashType that will be serialized
1263/// according to what the RPC expects.
1264pub struct SigHashType(digibyte::SigHashType);
1265
1266impl From<digibyte::SigHashType> for SigHashType {
1267    fn from(sht: digibyte::SigHashType) -> SigHashType {
1268        SigHashType(sht)
1269    }
1270}
1271
1272impl serde::Serialize for SigHashType {
1273    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1274    where
1275        S: serde::Serializer,
1276    {
1277        serializer.serialize_str(match self.0 {
1278            digibyte::SigHashType::All => "ALL",
1279            digibyte::SigHashType::None => "NONE",
1280            digibyte::SigHashType::Single => "SINGLE",
1281            digibyte::SigHashType::AllPlusAnyoneCanPay => "ALL|ANYONECANPAY",
1282            digibyte::SigHashType::NonePlusAnyoneCanPay => "NONE|ANYONECANPAY",
1283            digibyte::SigHashType::SinglePlusAnyoneCanPay => "SINGLE|ANYONECANPAY",
1284        })
1285    }
1286}
1287
1288// Used for createrawtransaction argument.
1289#[derive(Serialize, Clone, PartialEq, Eq, Debug)]
1290#[serde(rename_all = "camelCase")]
1291pub struct CreateRawTransactionInput {
1292    pub txid: digibyte::Txid,
1293    pub vout: u32,
1294    #[serde(skip_serializing_if = "Option::is_none")]
1295    pub sequence: Option<u32>,
1296}
1297
1298#[derive(Serialize, Clone, PartialEq, Eq, Debug, Default)]
1299#[serde(rename_all = "camelCase")]
1300pub struct FundRawTransactionOptions {
1301    /// For a transaction with existing inputs, automatically include more if they are not enough (default true).
1302    /// Added in Bitcoin Core v0.21
1303    #[serde(rename = "add_inputs", skip_serializing_if = "Option::is_none")]
1304    pub add_inputs: Option<bool>,
1305    #[serde(skip_serializing_if = "Option::is_none")]
1306    pub change_address: Option<Address>,
1307    #[serde(skip_serializing_if = "Option::is_none")]
1308    pub change_position: Option<u32>,
1309    #[serde(rename = "change_type", skip_serializing_if = "Option::is_none")]
1310    pub change_type: Option<AddressType>,
1311    #[serde(skip_serializing_if = "Option::is_none")]
1312    pub include_watching: Option<bool>,
1313    #[serde(skip_serializing_if = "Option::is_none")]
1314    pub lock_unspents: Option<bool>,
1315    #[serde(
1316        with = "digibyte::util::amount::serde::as_dgb::opt",
1317        skip_serializing_if = "Option::is_none"
1318    )]
1319    pub fee_rate: Option<Amount>,
1320    #[serde(skip_serializing_if = "Option::is_none")]
1321    pub subtract_fee_from_outputs: Option<Vec<u32>>,
1322    #[serde(skip_serializing_if = "Option::is_none")]
1323    pub replaceable: Option<bool>,
1324    #[serde(rename = "conf_target", skip_serializing_if = "Option::is_none")]
1325    pub conf_target: Option<u32>,
1326    #[serde(rename = "estimate_mode", skip_serializing_if = "Option::is_none")]
1327    pub estimate_mode: Option<EstimateMode>,
1328}
1329
1330#[derive(Deserialize, Clone, PartialEq, Eq, Debug)]
1331#[serde(rename_all = "camelCase")]
1332pub struct FundRawTransactionResult {
1333    #[serde(with = "::serde_hex")]
1334    pub hex: Vec<u8>,
1335    #[serde(with = "digibyte::util::amount::serde::as_dgb")]
1336    pub fee: Amount,
1337    #[serde(rename = "changepos")]
1338    pub change_position: i32,
1339}
1340
1341#[derive(Deserialize, Clone, PartialEq, Eq, Debug)]
1342pub struct GetBalancesResultEntry {
1343    #[serde(with = "digibyte::util::amount::serde::as_dgb")]
1344    pub trusted: Amount,
1345    #[serde(with = "digibyte::util::amount::serde::as_dgb")]
1346    pub untrusted_pending: Amount,
1347    #[serde(with = "digibyte::util::amount::serde::as_dgb")]
1348    pub immature: Amount,
1349}
1350
1351#[derive(Deserialize, Clone, PartialEq, Eq, Debug)]
1352#[serde(rename_all = "camelCase")]
1353pub struct GetBalancesResult {
1354    pub mine: GetBalancesResultEntry,
1355    pub watchonly: Option<GetBalancesResultEntry>,
1356}
1357
1358impl FundRawTransactionResult {
1359    pub fn transaction(&self) -> Result<Transaction, encode::Error> {
1360        encode::deserialize(&self.hex)
1361    }
1362}
1363
1364// Used for signrawtransaction argument.
1365#[derive(Serialize, Clone, PartialEq, Debug)]
1366#[serde(rename_all = "camelCase")]
1367pub struct SignRawTransactionInput {
1368    pub txid: digibyte::Txid,
1369    pub vout: u32,
1370    pub script_pub_key: Script,
1371    #[serde(skip_serializing_if = "Option::is_none")]
1372    pub redeem_script: Option<Script>,
1373    #[serde(
1374        default,
1375        skip_serializing_if = "Option::is_none",
1376        with = "digibyte::util::amount::serde::as_dgb::opt"
1377    )]
1378    pub amount: Option<Amount>,
1379}
1380
1381#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1382pub struct GetTxOutSetInfoResult {
1383    /// The current block height (index)
1384    pub height: u64,
1385    /// The hash of the block at the tip of the chain
1386    #[serde(rename = "bestblock")]
1387    pub best_block: digibyte::BlockHash,
1388    /// The number of transactions with unspent outputs
1389    pub transactions: u64,
1390    /// The number of unspent transaction outputs
1391    #[serde(rename = "txouts")]
1392    pub tx_outs: u64,
1393    /// A meaningless metric for UTXO set size
1394    pub bogosize: u64,
1395    /// The serialized hash
1396    pub hash_serialized_2: sha256::Hash,
1397    /// The estimated size of the chainstate on disk
1398    pub disk_size: u64,
1399    /// The total amount
1400    #[serde(with = "digibyte::util::amount::serde::as_dgb")]
1401    pub total_amount: Amount,
1402}
1403
1404#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1405pub struct GetNetTotalsResult {
1406    /// Total bytes received
1407    #[serde(rename = "totalbytesrecv")]
1408    pub total_bytes_recv: u64,
1409    /// Total bytes sent
1410    #[serde(rename = "totalbytessent")]
1411    pub total_bytes_sent: u64,
1412    /// Current UNIX time in milliseconds
1413    #[serde(rename = "timemillis")]
1414    pub time_millis: u64,
1415    /// Upload target statistics
1416    #[serde(rename = "uploadtarget")]
1417    pub upload_target: GetNetTotalsResultUploadTarget,
1418}
1419
1420#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1421pub struct GetNetTotalsResultUploadTarget {
1422    /// Length of the measuring timeframe in seconds
1423    #[serde(rename = "timeframe")]
1424    pub time_frame: u64,
1425    /// Target in bytes
1426    pub target: u64,
1427    /// True if target is reached
1428    pub target_reached: bool,
1429    /// True if serving historical blocks
1430    pub serve_historical_blocks: bool,
1431    /// Bytes left in current time cycle
1432    pub bytes_left_in_cycle: u64,
1433    /// Seconds left in current time cycle
1434    pub time_left_in_cycle: u64,
1435}
1436
1437/// Used to represent an address type.
1438#[derive(Copy, Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
1439#[serde(rename_all = "kebab-case")]
1440pub enum AddressType {
1441    Legacy,
1442    P2shSegwit,
1443    Bech32,
1444}
1445
1446/// Used to represent arguments that can either be an address or a public key.
1447#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
1448pub enum PubKeyOrAddress<'a> {
1449    Address(&'a Address),
1450    PubKey(&'a PublicKey),
1451}
1452
1453#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
1454#[serde(untagged)]
1455/// Start a scan of the UTXO set for an [output descriptor](https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md).
1456pub enum ScanTxOutRequest {
1457    /// Scan for a single descriptor
1458    Single(String),
1459    /// Scan for a descriptor with xpubs
1460    Extended {
1461        /// Descriptor
1462        desc: String,
1463        /// Range of the xpub derivations to scan
1464        range: (u64, u64),
1465    },
1466}
1467
1468#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
1469pub struct ScanTxOutResult {
1470    pub success: Option<bool>,
1471    #[serde(rename = "txouts")]
1472    pub tx_outs: Option<u64>,
1473    pub height: Option<u64>,
1474    #[serde(rename = "bestblock")]
1475    pub best_block_hash: Option<digibyte::BlockHash>,
1476    pub unspents: Vec<Utxo>,
1477    #[serde(with = "digibyte::util::amount::serde::as_dgb")]
1478    pub total_amount: digibyte::Amount,
1479}
1480
1481#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
1482#[serde(rename_all = "camelCase")]
1483pub struct Utxo {
1484    pub txid: digibyte::Txid,
1485    pub vout: u32,
1486    pub script_pub_key: digibyte::Script,
1487    #[serde(rename = "desc")]
1488    pub descriptor: String,
1489    #[serde(with = "digibyte::util::amount::serde::as_dgb")]
1490    pub amount: digibyte::Amount,
1491    pub height: u64,
1492}
1493
1494impl<'a> serde::Serialize for PubKeyOrAddress<'a> {
1495    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1496    where
1497        S: serde::Serializer,
1498    {
1499        match *self {
1500            PubKeyOrAddress::Address(a) => serde::Serialize::serialize(a, serializer),
1501            PubKeyOrAddress::PubKey(k) => serde::Serialize::serialize(k, serializer),
1502        }
1503    }
1504}
1505
1506// Custom deserializer functions.
1507
1508/// deserialize_hex_array_opt deserializes a vector of hex-encoded byte arrays.
1509fn deserialize_hex_array_opt<'de, D>(deserializer: D) -> Result<Option<Vec<Vec<u8>>>, D::Error>
1510where
1511    D: serde::Deserializer<'de>,
1512{
1513    //TODO(stevenroose) Revisit when issue is fixed:
1514    // https://github.com/serde-rs/serde/issues/723
1515
1516    let v: Vec<String> = Vec::deserialize(deserializer)?;
1517    let mut res = Vec::new();
1518    for h in v.into_iter() {
1519        res.push(FromHex::from_hex(&h).map_err(D::Error::custom)?);
1520    }
1521    Ok(Some(res))
1522}