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