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