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