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