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 #[serde(serialize_with = "serialize_bip70_network")]
1021 pub chain: Network,
1022 pub blocks: u64,
1024 pub headers: u64,
1026 #[serde(rename = "bestblockhash")]
1028 pub best_block_hash: bitcoin::BlockHash,
1029 pub difficulty: f64,
1031 #[serde(rename = "mediantime")]
1033 pub median_time: u64,
1034 #[serde(rename = "verificationprogress")]
1036 pub verification_progress: f64,
1037 #[serde(rename = "initialblockdownload")]
1039 pub initial_block_download: bool,
1040 #[serde(rename = "chainwork", with = "crate::serde_hex")]
1042 pub chain_work: Vec<u8>,
1043 pub size_on_disk: u64,
1045 pub pruned: bool,
1047 #[serde(rename = "pruneheight")]
1049 pub prune_height: Option<u64>,
1050 pub automatic_pruning: Option<bool>,
1052 pub prune_target_size: Option<u64>,
1054 #[serde(default)]
1056 pub softforks: HashMap<String, Softfork>,
1057 pub warnings: StringOrStringArray,
1059}
1060
1061#[derive(Clone, PartialEq, Eq, Debug)]
1062pub enum ImportMultiRequestScriptPubkey<'a> {
1063 Address(&'a Address),
1064 Script(&'a Script),
1065}
1066
1067#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1068pub struct GetMempoolInfoResult {
1069 pub loaded: Option<bool>,
1071 pub size: usize,
1073 pub bytes: usize,
1075 pub usage: usize,
1077 #[serde(default, with = "bitcoin::amount::serde::as_btc::opt")]
1079 pub total_fee: Option<Amount>,
1080 #[serde(rename = "maxmempool")]
1082 pub max_mempool: usize,
1083 #[serde(rename = "mempoolminfee", with = "bitcoin::amount::serde::as_btc")]
1085 pub mempool_min_fee: Amount,
1086 #[serde(rename = "minrelaytxfee", with = "bitcoin::amount::serde::as_btc")]
1088 pub min_relay_tx_fee: Amount,
1089 #[serde(rename = "incrementalrelayfee", default, with = "bitcoin::amount::serde::as_btc::opt")]
1091 pub incremental_relay_fee: Option<Amount>,
1092 #[serde(rename = "unbroadcastcount")]
1094 pub unbroadcast_count: Option<usize>,
1095 #[serde(rename = "fullrbf")]
1097 pub full_rbf: Option<bool>,
1098}
1099
1100#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1101pub struct GetMempoolEntryResult {
1102 #[serde(alias = "size")]
1105 pub vsize: u64,
1106 pub weight: Option<u64>,
1108 pub time: u64,
1110 pub height: u64,
1112 #[serde(rename = "descendantcount")]
1114 pub descendant_count: u64,
1115 #[serde(rename = "descendantsize")]
1117 pub descendant_size: u64,
1118 #[serde(rename = "ancestorcount")]
1120 pub ancestor_count: u64,
1121 #[serde(rename = "ancestorsize")]
1123 pub ancestor_size: u64,
1124 pub wtxid: bitcoin::Txid,
1126 pub fees: GetMempoolEntryResultFees,
1128 pub depends: Vec<bitcoin::Txid>,
1130 #[serde(rename = "spentby")]
1132 pub spent_by: Vec<bitcoin::Txid>,
1133 #[serde(rename = "bip125-replaceable")]
1135 pub bip125_replaceable: bool,
1136 pub unbroadcast: Option<bool>,
1139}
1140
1141#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1142pub struct GetMempoolEntryResultFees {
1143 #[serde(with = "bitcoin::amount::serde::as_btc")]
1145 pub base: Amount,
1146 #[serde(with = "bitcoin::amount::serde::as_btc")]
1148 pub modified: Amount,
1149 #[serde(with = "bitcoin::amount::serde::as_btc")]
1151 pub ancestor: Amount,
1152 #[serde(with = "bitcoin::amount::serde::as_btc")]
1154 pub descendant: Amount,
1155}
1156
1157impl<'a> serde::Serialize for ImportMultiRequestScriptPubkey<'a> {
1158 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1159 where
1160 S: serde::Serializer,
1161 {
1162 match *self {
1163 ImportMultiRequestScriptPubkey::Address(ref addr) => {
1164 #[derive(Serialize)]
1165 struct Tmp<'a> {
1166 pub address: &'a Address,
1167 }
1168 serde::Serialize::serialize(
1169 &Tmp {
1170 address: addr,
1171 },
1172 serializer,
1173 )
1174 }
1175 ImportMultiRequestScriptPubkey::Script(script) => {
1176 serializer.serialize_str(&script.to_hex_string())
1177 }
1178 }
1179 }
1180}
1181
1182#[derive(Clone, PartialEq, Eq, Debug, Default, Serialize)]
1186pub struct ImportMultiRequest<'a> {
1187 pub timestamp: Timestamp,
1188 #[serde(rename = "desc", skip_serializing_if = "Option::is_none")]
1190 pub descriptor: Option<&'a str>,
1191 #[serde(rename = "scriptPubKey", skip_serializing_if = "Option::is_none")]
1192 pub script_pubkey: Option<ImportMultiRequestScriptPubkey<'a>>,
1193 #[serde(rename = "redeemscript", skip_serializing_if = "Option::is_none")]
1194 pub redeem_script: Option<&'a Script>,
1195 #[serde(rename = "witnessscript", skip_serializing_if = "Option::is_none")]
1196 pub witness_script: Option<&'a Script>,
1197 #[serde(skip_serializing_if = "<[_]>::is_empty")]
1198 pub pubkeys: &'a [PublicKey],
1199 #[serde(skip_serializing_if = "<[_]>::is_empty")]
1200 pub keys: &'a [PrivateKey],
1201 #[serde(skip_serializing_if = "Option::is_none")]
1202 pub range: Option<(usize, usize)>,
1203 #[serde(skip_serializing_if = "Option::is_none")]
1204 pub internal: Option<bool>,
1205 #[serde(skip_serializing_if = "Option::is_none")]
1206 pub watchonly: Option<bool>,
1207 #[serde(skip_serializing_if = "Option::is_none")]
1208 pub label: Option<&'a str>,
1209 #[serde(skip_serializing_if = "Option::is_none")]
1210 pub keypool: Option<bool>,
1211}
1212
1213#[derive(Clone, PartialEq, Eq, Debug, Default, Deserialize, Serialize)]
1214pub struct ImportMultiOptions {
1215 #[serde(skip_serializing_if = "Option::is_none")]
1216 pub rescan: Option<bool>,
1217}
1218
1219#[derive(Clone, PartialEq, Eq, Copy, Debug)]
1220pub enum Timestamp {
1221 Now,
1222 Time(u64),
1223}
1224
1225impl serde::Serialize for Timestamp {
1226 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1227 where
1228 S: serde::Serializer,
1229 {
1230 match *self {
1231 Timestamp::Now => serializer.serialize_str("now"),
1232 Timestamp::Time(timestamp) => serializer.serialize_u64(timestamp),
1233 }
1234 }
1235}
1236
1237impl<'de> serde::Deserialize<'de> for Timestamp {
1238 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1239 where
1240 D: serde::Deserializer<'de>,
1241 {
1242 use serde::de;
1243 struct Visitor;
1244 impl<'de> de::Visitor<'de> for Visitor {
1245 type Value = Timestamp;
1246
1247 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
1248 write!(formatter, "unix timestamp or 'now'")
1249 }
1250
1251 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
1252 where
1253 E: de::Error,
1254 {
1255 Ok(Timestamp::Time(value))
1256 }
1257
1258 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
1259 where
1260 E: de::Error,
1261 {
1262 if value == "now" {
1263 Ok(Timestamp::Now)
1264 } else {
1265 Err(de::Error::custom(format!(
1266 "invalid str '{}', expecting 'now' or unix timestamp",
1267 value
1268 )))
1269 }
1270 }
1271 }
1272 deserializer.deserialize_any(Visitor)
1273 }
1274}
1275
1276impl Default for Timestamp {
1277 fn default() -> Self {
1278 Timestamp::Time(0)
1279 }
1280}
1281
1282impl From<u64> for Timestamp {
1283 fn from(t: u64) -> Self {
1284 Timestamp::Time(t)
1285 }
1286}
1287
1288impl From<Option<u64>> for Timestamp {
1289 fn from(timestamp: Option<u64>) -> Self {
1290 timestamp.map_or(Timestamp::Now, Timestamp::Time)
1291 }
1292}
1293
1294#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1295pub struct ImportMultiResultError {
1296 pub code: i64,
1297 pub message: String,
1298}
1299
1300#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1301pub struct ImportMultiResult {
1302 pub success: bool,
1303 #[serde(default)]
1304 pub warnings: Vec<String>,
1305 pub error: Option<ImportMultiResultError>,
1306}
1307
1308#[derive(Clone, PartialEq, Eq, Debug, Default, Deserialize, Serialize)]
1310pub struct ImportDescriptors {
1311 #[serde(rename = "desc")]
1312 pub descriptor: String,
1313 pub timestamp: Timestamp,
1314 #[serde(skip_serializing_if = "Option::is_none")]
1315 pub active: Option<bool>,
1316 #[serde(skip_serializing_if = "Option::is_none")]
1317 pub range: Option<(usize, usize)>,
1318 #[serde(skip_serializing_if = "Option::is_none")]
1319 pub next_index: Option<usize>,
1320 #[serde(skip_serializing_if = "Option::is_none")]
1321 pub internal: Option<bool>,
1322 #[serde(skip_serializing_if = "Option::is_none")]
1323 pub label: Option<String>,
1324}
1325
1326#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1328pub struct RejectStatus {
1329 pub status: bool,
1331}
1332
1333#[derive(Clone, Debug, Deserialize, Serialize)]
1335pub struct GetPeerInfoResult {
1336 pub id: u64,
1338 pub addr: String,
1341 pub addrbind: String,
1344 pub addrlocal: Option<String>,
1347 pub network: Option<GetPeerInfoResultNetwork>,
1350 pub services: String,
1353 pub relaytxes: bool,
1355 pub lastsend: u64,
1357 pub lastrecv: u64,
1359 pub last_transaction: Option<u64>,
1362 pub last_block: Option<u64>,
1365 pub bytessent: u64,
1367 pub bytesrecv: u64,
1369 pub conntime: u64,
1371 pub timeoffset: i64,
1373 pub pingtime: Option<f64>,
1375 pub minping: Option<f64>,
1377 pub pingwait: Option<f64>,
1379 pub version: u64,
1381 pub subver: String,
1383 pub inbound: bool,
1385 pub addnode: Option<bool>,
1389 pub startingheight: i64,
1391 pub banscore: Option<i64>,
1394 pub synced_headers: i64,
1396 pub synced_blocks: i64,
1398 pub inflight: Vec<u64>,
1400 pub whitelisted: Option<bool>,
1403 #[serde(rename = "minfeefilter", default, with = "bitcoin::amount::serde::as_btc::opt")]
1404 pub min_fee_filter: Option<Amount>,
1405 pub bytessent_per_msg: HashMap<String, u64>,
1407 pub bytesrecv_per_msg: HashMap<String, u64>,
1409 pub connection_type: Option<GetPeerInfoResultConnectionType>,
1412}
1413
1414#[derive(Copy, Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
1415#[serde(rename_all = "snake_case")]
1416pub enum GetPeerInfoResultNetwork {
1417 Ipv4,
1418 Ipv6,
1419 Onion,
1420 #[deprecated]
1421 Unroutable,
1422 NotPubliclyRoutable,
1423 I2p,
1424 Cjdns,
1425 Internal,
1426}
1427
1428#[derive(Copy, Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
1429#[serde(rename_all = "kebab-case")]
1430pub enum GetPeerInfoResultConnectionType {
1431 OutboundFullRelay,
1432 BlockRelayOnly,
1433 Inbound,
1434 Manual,
1435 AddrFetch,
1436 Feeler,
1437}
1438
1439#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1440pub struct GetAddedNodeInfoResult {
1441 #[serde(rename = "addednode")]
1443 pub added_node: String,
1444 pub connected: bool,
1446 pub addresses: Vec<GetAddedNodeInfoResultAddress>,
1448}
1449
1450#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1451pub struct GetAddedNodeInfoResultAddress {
1452 pub address: String,
1454 pub connected: GetAddedNodeInfoResultAddressType,
1456}
1457
1458#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1459#[serde(rename_all = "lowercase")]
1460pub enum GetAddedNodeInfoResultAddressType {
1461 Inbound,
1462 Outbound,
1463}
1464
1465#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1466pub struct GetNodeAddressesResult {
1467 pub time: u64,
1469 pub services: usize,
1471 pub address: String,
1473 pub port: u16,
1475}
1476
1477#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1478pub struct ListBannedResult {
1479 pub address: String,
1480 pub banned_until: u64,
1481 pub ban_created: u64,
1482}
1483
1484#[derive(Clone, Debug, Deserialize, Serialize)]
1486pub struct EstimateSmartFeeResult {
1487 #[serde(
1489 default,
1490 rename = "feerate",
1491 skip_serializing_if = "Option::is_none",
1492 with = "bitcoin::amount::serde::as_btc::opt"
1493 )]
1494 pub fee_rate: Option<Amount>,
1495 pub errors: Option<Vec<String>>,
1497 pub blocks: i64,
1499}
1500
1501#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1503pub struct BlockRef {
1504 pub hash: bitcoin::BlockHash,
1505 pub height: u64,
1506}
1507
1508#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1510pub struct GetDescriptorInfoResult {
1511 pub descriptor: String,
1512 pub checksum: Option<String>,
1513 #[serde(rename = "isrange")]
1514 pub is_range: bool,
1515 #[serde(rename = "issolvable")]
1516 pub is_solvable: bool,
1517 #[serde(rename = "hasprivatekeys")]
1518 pub has_private_keys: bool,
1519}
1520
1521#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1523pub struct GetBlockTemplateOptions {
1524 pub mode: GetBlockTemplateModes,
1525 pub rules: Vec<GetBlockTemplateRules>,
1527 pub capabilities: Vec<GetBlockTemplateCapabilities>,
1529}
1530
1531#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1533#[serde(rename_all = "lowercase")]
1534pub enum GetBlockTemplateCapabilities {
1535 }
1537
1538#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1541#[serde(rename_all = "lowercase")]
1542pub enum GetBlockTemplateRules {
1543 SegWit,
1544 Signet,
1545 Csv,
1546 Taproot,
1547}
1548
1549#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1551#[serde(rename_all = "lowercase")]
1552pub enum GetBlockTemplateModes {
1553 Template,
1556 }
1559
1560#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1562pub struct GetBlockTemplateResult {
1563 #[serde(with = "crate::serde_hex")]
1565 pub bits: Vec<u8>,
1566 #[serde(rename = "previousblockhash")]
1568 pub previous_block_hash: bitcoin::BlockHash,
1569 #[serde(rename = "curtime")]
1573 pub current_time: u64,
1574 pub height: u64,
1576 #[serde(rename = "sigoplimit")]
1578 pub sigop_limit: u32,
1579 #[serde(rename = "sizelimit")]
1581 pub size_limit: u32,
1582 #[serde(rename = "weightlimit")]
1584 pub weight_limit: u32,
1585 pub version: u32,
1587 pub rules: Vec<GetBlockTemplateResultRules>,
1589 pub capabilities: Vec<GetBlockTemplateResultCapabilities>,
1591 #[serde(rename = "vbavailable")]
1593 pub version_bits_available: HashMap<String, u32>,
1594 #[serde(rename = "vbrequired")]
1596 pub version_bits_required: u32,
1597 pub longpollid: String,
1599 pub transactions: Vec<GetBlockTemplateResultTransaction>,
1601 #[serde(default, with = "bitcoin::script::ScriptBuf")]
1603 pub signet_challenge: bitcoin::script::ScriptBuf,
1604 #[serde(with = "bitcoin::script::ScriptBuf", default)]
1608 pub default_witness_commitment: bitcoin::script::ScriptBuf,
1609 pub coinbaseaux: HashMap<String, String>,
1616 #[serde(rename = "coinbasevalue", with = "bitcoin::amount::serde::as_sat", default)]
1618 pub coinbase_value: Amount,
1619 #[serde(with = "crate::serde_hex")]
1621 pub target: Vec<u8>,
1622 #[serde(rename = "mintime")]
1625 pub min_time: u64,
1626 pub mutable: Vec<GetBlockTemplateResulMutations>,
1629 #[serde(with = "crate::serde_hex", rename = "noncerange")]
1631 pub nonce_range: Vec<u8>,
1632}
1633
1634#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1636pub struct GetBlockTemplateResultTransaction {
1637 pub txid: bitcoin::Txid,
1639 #[serde(rename = "hash")]
1641 pub wtxid: bitcoin::Wtxid,
1642 #[serde(with = "crate::serde_hex", rename = "data")]
1644 pub raw_tx: Vec<u8>,
1645 #[serde(with = "bitcoin::amount::serde::as_sat")]
1647 pub fee: Amount,
1648 pub sigops: u32,
1650 pub weight: usize,
1652 pub depends: Vec<u32>,
1656}
1657
1658impl GetBlockTemplateResultTransaction {
1659 pub fn transaction(&self) -> Result<Transaction, encode::Error> {
1660 encode::deserialize(&self.raw_tx)
1661 }
1662}
1663
1664#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1666#[serde(rename_all = "lowercase")]
1667pub enum GetBlockTemplateResultCapabilities {
1668 Proposal,
1669}
1670
1671#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1674#[serde(rename_all = "lowercase")]
1675pub enum GetBlockTemplateResultRules {
1676 #[serde(alias = "!segwit")]
1679 SegWit,
1680 #[serde(alias = "!signet")]
1683 Signet,
1684 Csv,
1687 Taproot,
1690 Testdummy,
1693}
1694
1695#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1700#[serde(rename_all = "lowercase")]
1701pub enum GetBlockTemplateResulMutations {
1702 Time,
1704 Transactions,
1706 #[serde(rename = "prevblock")]
1710 PreviousBlock,
1711}
1712
1713#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1715pub struct WalletCreateFundedPsbtResult {
1716 pub psbt: String,
1717 #[serde(with = "bitcoin::amount::serde::as_btc")]
1718 pub fee: Amount,
1719 #[serde(rename = "changepos")]
1720 pub change_position: i32,
1721}
1722
1723#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1725pub struct WalletProcessPsbtResult {
1726 pub psbt: String,
1727 pub complete: bool,
1728}
1729
1730#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize, Default)]
1732pub struct WalletCreateFundedPsbtOptions {
1733 #[serde(skip_serializing_if = "Option::is_none")]
1736 pub add_inputs: Option<bool>,
1737 #[serde(rename = "changeAddress", skip_serializing_if = "Option::is_none")]
1738 pub change_address: Option<Address<NetworkUnchecked>>,
1739 #[serde(rename = "changePosition", skip_serializing_if = "Option::is_none")]
1740 pub change_position: Option<u16>,
1741 #[serde(skip_serializing_if = "Option::is_none")]
1742 pub change_type: Option<AddressType>,
1743 #[serde(rename = "includeWatching", skip_serializing_if = "Option::is_none")]
1744 pub include_watching: Option<bool>,
1745 #[serde(rename = "lockUnspents", skip_serializing_if = "Option::is_none")]
1746 pub lock_unspent: Option<bool>,
1747 #[serde(
1748 rename = "feeRate",
1749 skip_serializing_if = "Option::is_none",
1750 with = "bitcoin::amount::serde::as_btc::opt"
1751 )]
1752 pub fee_rate: Option<Amount>,
1753 #[serde(rename = "subtractFeeFromOutputs", skip_serializing_if = "Vec::is_empty")]
1754 pub subtract_fee_from_outputs: Vec<u16>,
1755 #[serde(skip_serializing_if = "Option::is_none")]
1756 pub replaceable: Option<bool>,
1757 #[serde(skip_serializing_if = "Option::is_none")]
1758 pub conf_target: Option<u16>,
1759 #[serde(skip_serializing_if = "Option::is_none")]
1760 pub estimate_mode: Option<EstimateMode>,
1761}
1762
1763#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1765pub struct FinalizePsbtResult {
1766 pub psbt: Option<String>,
1767 #[serde(default, with = "crate::serde_hex::opt")]
1768 pub hex: Option<Vec<u8>>,
1769 pub complete: bool,
1770}
1771
1772#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1774pub struct DecodeRawTransactionResult {
1775 pub txid: bitcoin::Txid,
1776 pub hash: bitcoin::Wtxid,
1777 pub size: u32,
1778 pub vsize: u32,
1779 pub weight: u32,
1780 pub version: u32,
1781 pub locktime: u32,
1782 pub vin: Vec<GetRawTransactionResultVin>,
1783 pub vout: Vec<GetRawTransactionResultVout>,
1784}
1785
1786pub type GetChainTipsResult = Vec<GetChainTipsResultTip>;
1788
1789#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1791pub struct GetChainTipsResultTip {
1792 pub height: u64,
1794 pub hash: bitcoin::BlockHash,
1796 #[serde(rename = "branchlen")]
1798 pub branch_length: usize,
1799 pub status: GetChainTipsResultStatus,
1801}
1802
1803#[derive(Copy, Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
1804#[serde(rename_all = "lowercase")]
1805pub enum GetChainTipsResultStatus {
1806 Invalid,
1808 #[serde(rename = "headers-only")]
1810 HeadersOnly,
1811 #[serde(rename = "valid-headers")]
1813 ValidHeaders,
1814 #[serde(rename = "valid-fork")]
1816 ValidFork,
1817 Active,
1819}
1820
1821impl FinalizePsbtResult {
1822 pub fn transaction(&self) -> Option<Result<Transaction, encode::Error>> {
1823 self.hex.as_ref().map(|h| encode::deserialize(h))
1824 }
1825}
1826
1827#[derive(Serialize, Deserialize, Debug, Clone, Copy, Eq, PartialEq, Hash)]
1830#[serde(rename_all = "UPPERCASE")]
1831pub enum EstimateMode {
1832 Unset,
1833 Economical,
1834 Conservative,
1835}
1836
1837pub struct SigHashType(bitcoin::sighash::EcdsaSighashType);
1840
1841impl From<bitcoin::sighash::EcdsaSighashType> for SigHashType {
1842 fn from(sht: bitcoin::sighash::EcdsaSighashType) -> SigHashType {
1843 SigHashType(sht)
1844 }
1845}
1846
1847impl serde::Serialize for SigHashType {
1848 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1849 where
1850 S: serde::Serializer,
1851 {
1852 serializer.serialize_str(match self.0 {
1853 bitcoin::sighash::EcdsaSighashType::All => "ALL",
1854 bitcoin::sighash::EcdsaSighashType::None => "NONE",
1855 bitcoin::sighash::EcdsaSighashType::Single => "SINGLE",
1856 bitcoin::sighash::EcdsaSighashType::AllPlusAnyoneCanPay => "ALL|ANYONECANPAY",
1857 bitcoin::sighash::EcdsaSighashType::NonePlusAnyoneCanPay => "NONE|ANYONECANPAY",
1858 bitcoin::sighash::EcdsaSighashType::SinglePlusAnyoneCanPay => "SINGLE|ANYONECANPAY",
1859 })
1860 }
1861}
1862
1863#[derive(Serialize, Clone, PartialEq, Eq, Debug, Deserialize)]
1865#[serde(rename_all = "camelCase")]
1866pub struct CreateRawTransactionInput {
1867 pub txid: bitcoin::Txid,
1868 pub vout: u32,
1869 #[serde(skip_serializing_if = "Option::is_none")]
1870 pub sequence: Option<u32>,
1871}
1872
1873#[derive(Serialize, Clone, PartialEq, Eq, Debug, Default)]
1874#[serde(rename_all = "camelCase")]
1875pub struct FundRawTransactionOptions {
1876 #[serde(rename = "add_inputs", skip_serializing_if = "Option::is_none")]
1879 pub add_inputs: Option<bool>,
1880 #[serde(skip_serializing_if = "Option::is_none")]
1881 pub change_address: Option<Address>,
1882 #[serde(skip_serializing_if = "Option::is_none")]
1883 pub change_position: Option<u32>,
1884 #[serde(rename = "change_type", skip_serializing_if = "Option::is_none")]
1885 pub change_type: Option<AddressType>,
1886 #[serde(skip_serializing_if = "Option::is_none")]
1887 pub include_watching: Option<bool>,
1888 #[serde(skip_serializing_if = "Option::is_none")]
1889 pub lock_unspents: Option<bool>,
1890 #[serde(
1894 with = "bitcoin::amount::serde::as_btc::opt",
1895 skip_serializing_if = "Option::is_none"
1896 )]
1897 pub fee_rate: Option<Amount>,
1898 #[serde(skip_serializing_if = "Option::is_none")]
1899 pub subtract_fee_from_outputs: Option<Vec<u32>>,
1900 #[serde(skip_serializing_if = "Option::is_none")]
1901 pub replaceable: Option<bool>,
1902 #[serde(rename = "conf_target", skip_serializing_if = "Option::is_none")]
1903 pub conf_target: Option<u32>,
1904 #[serde(rename = "estimate_mode", skip_serializing_if = "Option::is_none")]
1905 pub estimate_mode: Option<EstimateMode>,
1906}
1907
1908#[derive(Deserialize, Clone, PartialEq, Eq, Debug, Serialize)]
1909#[serde(rename_all = "camelCase")]
1910pub struct FundRawTransactionResult {
1911 #[serde(with = "crate::serde_hex")]
1912 pub hex: Vec<u8>,
1913 #[serde(with = "bitcoin::amount::serde::as_btc")]
1914 pub fee: Amount,
1915 #[serde(rename = "changepos")]
1916 pub change_position: i32,
1917}
1918
1919#[derive(Deserialize, Clone, PartialEq, Eq, Debug, Serialize)]
1920pub struct GetBalancesResultEntry {
1921 #[serde(with = "bitcoin::amount::serde::as_btc")]
1922 pub trusted: Amount,
1923 #[serde(with = "bitcoin::amount::serde::as_btc")]
1924 pub untrusted_pending: Amount,
1925 #[serde(with = "bitcoin::amount::serde::as_btc")]
1926 pub immature: Amount,
1927}
1928
1929#[derive(Deserialize, Clone, PartialEq, Eq, Debug, Serialize)]
1930#[serde(rename_all = "camelCase")]
1931pub struct GetBalancesResult {
1932 pub mine: GetBalancesResultEntry,
1933 pub watchonly: Option<GetBalancesResultEntry>,
1934}
1935
1936impl FundRawTransactionResult {
1937 pub fn transaction(&self) -> Result<Transaction, encode::Error> {
1938 encode::deserialize(&self.hex)
1939 }
1940}
1941
1942#[derive(Serialize, Clone, PartialEq, Debug, Deserialize)]
1944#[serde(rename_all = "camelCase")]
1945pub struct SignRawTransactionInput {
1946 pub txid: bitcoin::Txid,
1947 pub vout: u32,
1948 pub script_pub_key: ScriptBuf,
1949 #[serde(skip_serializing_if = "Option::is_none")]
1950 pub redeem_script: Option<ScriptBuf>,
1951 #[serde(
1952 default,
1953 skip_serializing_if = "Option::is_none",
1954 with = "bitcoin::amount::serde::as_btc::opt"
1955 )]
1956 pub amount: Option<Amount>,
1957}
1958
1959#[derive(Clone, Serialize, PartialEq, Eq, Debug, Deserialize)]
1961#[serde(rename_all = "snake_case")]
1962pub enum TxOutSetHashType {
1963 HashSerialized2,
1964 Muhash,
1965 None,
1966}
1967
1968#[derive(Clone, Serialize, PartialEq, Eq, Debug, Deserialize)]
1970#[serde(untagged)]
1971pub enum HashOrHeight {
1972 BlockHash(bitcoin::BlockHash),
1973 Height(u64),
1974}
1975
1976#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1977pub struct GetTxOutSetInfoResult {
1978 pub height: u64,
1980 #[serde(rename = "bestblock")]
1982 pub best_block: bitcoin::BlockHash,
1983 #[serde(default, skip_serializing_if = "Option::is_none")]
1985 pub transactions: Option<u64>,
1986 #[serde(rename = "txouts")]
1988 pub tx_outs: u64,
1989 pub bogosize: u64,
1991 #[serde(default, skip_serializing_if = "Option::is_none")]
1993 pub hash_serialized_2: Option<sha256::Hash>,
1994 #[serde(default, skip_serializing_if = "Option::is_none")]
1996 pub muhash: Option<sha256::Hash>,
1997 #[serde(default, skip_serializing_if = "Option::is_none")]
1999 pub disk_size: Option<u64>,
2000 #[serde(with = "bitcoin::amount::serde::as_btc")]
2002 pub total_amount: Amount,
2003 #[serde(
2005 default,
2006 skip_serializing_if = "Option::is_none",
2007 with = "bitcoin::amount::serde::as_btc::opt"
2008 )]
2009 pub total_unspendable_amount: Option<Amount>,
2010 #[serde(default, skip_serializing_if = "Option::is_none")]
2012 pub block_info: Option<BlockInfo>,
2013}
2014
2015#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
2017pub struct BlockInfo {
2018 #[serde(with = "bitcoin::amount::serde::as_btc")]
2020 pub prevout_spent: Amount,
2021 #[serde(with = "bitcoin::amount::serde::as_btc")]
2023 pub coinbase: Amount,
2024 #[serde(with = "bitcoin::amount::serde::as_btc")]
2026 pub new_outputs_ex_coinbase: Amount,
2027 #[serde(with = "bitcoin::amount::serde::as_btc")]
2029 pub unspendable: Amount,
2030 pub unspendables: Unspendables,
2032}
2033
2034#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
2036pub struct Unspendables {
2037 #[serde(with = "bitcoin::amount::serde::as_btc")]
2039 pub genesis_block: Amount,
2040 #[serde(with = "bitcoin::amount::serde::as_btc")]
2042 pub bip30: Amount,
2043 #[serde(with = "bitcoin::amount::serde::as_btc")]
2045 pub scripts: Amount,
2046 #[serde(with = "bitcoin::amount::serde::as_btc")]
2048 pub unclaimed_rewards: Amount,
2049}
2050
2051#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
2052pub struct GetNetTotalsResult {
2053 #[serde(rename = "totalbytesrecv")]
2055 pub total_bytes_recv: u64,
2056 #[serde(rename = "totalbytessent")]
2058 pub total_bytes_sent: u64,
2059 #[serde(rename = "timemillis")]
2061 pub time_millis: u64,
2062 #[serde(rename = "uploadtarget")]
2064 pub upload_target: GetNetTotalsResultUploadTarget,
2065}
2066
2067#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
2068pub struct GetNetTotalsResultUploadTarget {
2069 #[serde(rename = "timeframe")]
2071 pub time_frame: u64,
2072 pub target: u64,
2074 pub target_reached: bool,
2076 pub serve_historical_blocks: bool,
2078 pub bytes_left_in_cycle: u64,
2080 pub time_left_in_cycle: u64,
2082}
2083
2084#[derive(Copy, Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
2086#[serde(rename_all = "kebab-case")]
2087pub enum AddressType {
2088 Legacy,
2089 P2shSegwit,
2090 Bech32,
2091 Bech32m,
2092}
2093
2094#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
2096pub enum PubKeyOrAddress<'a> {
2097 Address(&'a Address),
2098 PubKey(&'a PublicKey),
2099}
2100
2101#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
2102#[serde(untagged)]
2103pub enum ScanTxOutRequest {
2105 Single(String),
2107 Extended {
2109 desc: String,
2111 range: (u64, u64),
2113 },
2114}
2115
2116#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
2117pub struct ScanTxOutResult {
2118 pub success: Option<bool>,
2119 #[serde(rename = "txouts")]
2120 pub tx_outs: Option<u64>,
2121 pub height: Option<u64>,
2122 #[serde(rename = "bestblock")]
2123 pub best_block_hash: Option<bitcoin::BlockHash>,
2124 pub unspents: Vec<Utxo>,
2125 #[serde(with = "bitcoin::amount::serde::as_btc")]
2126 pub total_amount: bitcoin::Amount,
2127}
2128
2129#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
2130#[serde(rename_all = "camelCase")]
2131pub struct Utxo {
2132 pub txid: bitcoin::Txid,
2133 pub vout: u32,
2134 pub script_pub_key: bitcoin::ScriptBuf,
2135 #[serde(rename = "desc")]
2136 pub descriptor: String,
2137 #[serde(with = "bitcoin::amount::serde::as_btc")]
2138 pub amount: bitcoin::Amount,
2139 pub height: u64,
2140}
2141
2142#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
2143pub struct IndexStatus {
2144 pub synced: bool,
2145 pub best_block_height: u32,
2146}
2147
2148#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
2149pub struct GetIndexInfoResult {
2150 pub txindex: Option<IndexStatus>,
2151 pub coinstatsindex: Option<IndexStatus>,
2152 #[serde(rename = "basic block filter index")]
2153 pub basic_block_filter_index: Option<IndexStatus>,
2154}
2155
2156#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
2157pub struct GetZmqNotificationsResult {
2158 #[serde(rename = "type")]
2159 pub notification_type: String,
2160 pub address: String,
2161 pub hwm: u64,
2162}
2163
2164impl<'a> serde::Serialize for PubKeyOrAddress<'a> {
2165 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
2166 where
2167 S: serde::Serializer,
2168 {
2169 match *self {
2170 PubKeyOrAddress::Address(a) => serde::Serialize::serialize(a, serializer),
2171 PubKeyOrAddress::PubKey(k) => serde::Serialize::serialize(k, serializer),
2172 }
2173 }
2174}
2175
2176fn deserialize_hex_array_opt<'de, D>(deserializer: D) -> Result<Option<Vec<Vec<u8>>>, D::Error>
2180where
2181 D: serde::Deserializer<'de>,
2182{
2183 let v: Vec<String> = Vec::deserialize(deserializer)?;
2187 let mut res = Vec::new();
2188 for h in v.into_iter() {
2189 res.push(FromHex::from_hex(&h).map_err(D::Error::custom)?);
2190 }
2191 Ok(Some(res))
2192}
2193
2194fn serialize_bip70_network<S>(network: &Network, serializer: S) -> Result<S::Ok, S::Error>
2195where
2196 S: serde::Serializer,
2197{
2198 serializer.serialize_str(network.to_core_arg())
2199}
2200
2201fn deserialize_bip70_network<'de, D>(deserializer: D) -> Result<Network, D::Error>
2204where
2205 D: serde::Deserializer<'de>,
2206{
2207 struct NetworkVisitor;
2208 impl<'de> serde::de::Visitor<'de> for NetworkVisitor {
2209 type Value = Network;
2210
2211 fn visit_str<E: serde::de::Error>(self, s: &str) -> Result<Self::Value, E> {
2212 Network::from_core_arg(s)
2213 .map_err(|_| E::invalid_value(serde::de::Unexpected::Str(s), &"bitcoin network encoded as a string"))
2214 }
2215
2216 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
2217 write!(formatter, "bitcoin network encoded as a string")
2218 }
2219 }
2220
2221 deserializer.deserialize_str(NetworkVisitor)
2222}
2223
2224#[cfg(test)]
2225mod tests {
2226 use super::*;
2227
2228 #[test]
2229 fn test_softfork_type() {
2230 let buried: SoftforkType = serde_json::from_str("\"buried\"").unwrap();
2231 assert_eq!(buried, SoftforkType::Buried);
2232 let bip9: SoftforkType = serde_json::from_str("\"bip9\"").unwrap();
2233 assert_eq!(bip9, SoftforkType::Bip9);
2234 let other: SoftforkType = serde_json::from_str("\"bip8\"").unwrap();
2235 assert_eq!(other, SoftforkType::Other);
2236 }
2237}