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