1#![crate_name = "bellscoincore_rpc_json"]
17#![crate_type = "rlib"]
18
19pub extern crate bitcoin;
20#[allow(unused)]
21#[macro_use] extern crate serde;
23extern crate serde_json;
24
25use std::collections::HashMap;
26
27use bitcoin::address::NetworkUnchecked;
28use bitcoin::block::Version;
29use bitcoin::consensus::encode;
30use bitcoin::hashes::hex::FromHex;
31use bitcoin::hashes::sha256;
32use bitcoin::{
33 bip158, bip32, Address, Amount, Network, PrivateKey, PublicKey, Script, ScriptBuf,
34 SignedAmount, Transaction,
35};
36use serde::de::Error as SerdeError;
37use serde::{Deserialize, Serialize};
38use std::fmt;
39
40pub mod serde_hex {
46 use bitcoin::hex::{DisplayHex, FromHex};
47 use serde::de::Error;
48 use serde::{Deserializer, Serializer};
49
50 pub fn serialize<S: Serializer>(b: &Vec<u8>, s: S) -> Result<S::Ok, S::Error> {
51 s.serialize_str(&b.to_lower_hex_string())
52 }
53
54 pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result<Vec<u8>, D::Error> {
55 let hex_str: String = ::serde::Deserialize::deserialize(d)?;
56 Ok(FromHex::from_hex(&hex_str).map_err(D::Error::custom)?)
57 }
58
59 pub mod opt {
60 use bitcoin::hex::{DisplayHex, FromHex};
61 use serde::de::Error;
62 use serde::{Deserializer, Serializer};
63
64 pub fn serialize<S: Serializer>(b: &Option<Vec<u8>>, s: S) -> Result<S::Ok, S::Error> {
65 match *b {
66 None => s.serialize_none(),
67 Some(ref b) => s.serialize_str(&b.to_lower_hex_string()),
68 }
69 }
70
71 pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result<Option<Vec<u8>>, D::Error> {
72 let hex_str: String = ::serde::Deserialize::deserialize(d)?;
73 Ok(Some(FromHex::from_hex(&hex_str).map_err(D::Error::custom)?))
74 }
75 }
76}
77
78#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
79pub struct GetNetworkInfoResultNetwork {
80 pub name: String,
81 pub limited: bool,
82 pub reachable: bool,
83 pub proxy: String,
84 pub proxy_randomize_credentials: bool,
85}
86
87#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
88pub struct GetNetworkInfoResultAddress {
89 pub address: String,
90 pub port: usize,
91 pub score: usize,
92}
93
94#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)]
96#[serde(untagged)]
97pub enum StringOrStringArray {
98 String(String),
99 StringArray(Vec<String>),
100}
101
102#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
103pub struct GetNetworkInfoResult {
104 pub version: usize,
105 pub subversion: String,
106 #[serde(rename = "protocolversion")]
107 pub protocol_version: usize,
108 #[serde(rename = "localservices")]
109 pub local_services: String,
110 #[serde(rename = "localrelay")]
111 pub local_relay: bool,
112 #[serde(rename = "timeoffset")]
113 pub time_offset: isize,
114 pub connections: usize,
115 pub connections_in: Option<usize>,
118 pub connections_out: Option<usize>,
121 #[serde(rename = "networkactive")]
122 pub network_active: bool,
123 pub networks: Vec<GetNetworkInfoResultNetwork>,
124 #[serde(rename = "relayfee", with = "bitcoin::amount::serde::as_btc")]
125 pub relay_fee: Amount,
126 #[serde(rename = "incrementalfee", with = "bitcoin::amount::serde::as_btc")]
127 pub incremental_fee: Amount,
128 #[serde(rename = "localaddresses")]
129 pub local_addresses: Vec<GetNetworkInfoResultAddress>,
130 pub warnings: StringOrStringArray,
131}
132
133#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
134#[serde(rename_all = "camelCase")]
135pub struct AddMultiSigAddressResult {
136 pub address: Address<NetworkUnchecked>,
137 pub redeem_script: ScriptBuf,
138}
139
140#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
141pub struct LoadWalletResult {
142 pub name: String,
143 pub warning: Option<String>,
144}
145
146#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
147pub struct UnloadWalletResult {
148 pub warning: Option<String>,
149}
150
151#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
152pub struct ListWalletDirResult {
153 pub wallets: Vec<ListWalletDirItem>,
154}
155
156#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
157pub struct ListWalletDirItem {
158 pub name: String,
159}
160
161#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
162pub struct GetWalletInfoResult {
163 #[serde(rename = "walletname")]
164 pub wallet_name: String,
165 #[serde(rename = "walletversion")]
166 pub wallet_version: u32,
167 #[serde(with = "bitcoin::amount::serde::as_btc")]
168 pub balance: Amount,
169 #[serde(with = "bitcoin::amount::serde::as_btc")]
170 pub unconfirmed_balance: Amount,
171 #[serde(with = "bitcoin::amount::serde::as_btc")]
172 pub immature_balance: Amount,
173 #[serde(rename = "txcount")]
174 pub tx_count: usize,
175 #[serde(rename = "keypoololdest")]
176 pub keypool_oldest: Option<usize>,
177 #[serde(rename = "keypoolsize")]
178 pub keypool_size: usize,
179 #[serde(rename = "keypoolsize_hd_internal")]
180 pub keypool_size_hd_internal: usize,
181 pub unlocked_until: Option<u64>,
182 #[serde(rename = "paytxfee", with = "bitcoin::amount::serde::as_btc")]
183 pub pay_tx_fee: Amount,
184 #[serde(rename = "hdseedid")]
185 pub hd_seed_id: Option<bitcoin::bip32::XKeyIdentifier>,
186 pub private_keys_enabled: bool,
187 pub avoid_reuse: Option<bool>,
188 pub scanning: Option<ScanningDetails>,
189}
190
191#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
192#[serde(untagged)]
193pub enum ScanningDetails {
194 Scanning {
195 duration: usize,
196 progress: f32,
197 },
198 NotScanning(bool),
200}
201
202impl Eq for ScanningDetails {}
203
204#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
205#[serde(rename_all = "camelCase")]
206pub struct GetBlockResult {
207 pub hash: bitcoin::BlockHash,
208 pub confirmations: i32,
209 pub size: usize,
210 pub strippedsize: Option<usize>,
211 pub weight: usize,
212 pub height: usize,
213 pub version: i32,
214 #[serde(default, with = "crate::serde_hex::opt")]
215 pub version_hex: Option<Vec<u8>>,
216 pub merkleroot: bitcoin::hash_types::TxMerkleNode,
217 pub tx: Vec<bitcoin::Txid>,
218 pub time: usize,
219 pub mediantime: Option<usize>,
220 pub nonce: u32,
221 pub bits: String,
222 pub difficulty: f64,
223 #[serde(with = "crate::serde_hex")]
224 pub chainwork: Vec<u8>,
225 pub n_tx: usize,
226 pub previousblockhash: Option<bitcoin::BlockHash>,
227 pub nextblockhash: Option<bitcoin::BlockHash>,
228}
229
230#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
231#[serde(rename_all = "camelCase")]
232pub struct GetBlockHeaderResult {
233 pub hash: bitcoin::BlockHash,
234 pub confirmations: i32,
235 pub height: usize,
236 pub version: Version,
237 #[serde(default, with = "crate::serde_hex::opt")]
238 pub version_hex: Option<Vec<u8>>,
239 #[serde(rename = "merkleroot")]
240 pub merkle_root: bitcoin::hash_types::TxMerkleNode,
241 pub time: usize,
242 #[serde(rename = "mediantime")]
243 pub median_time: Option<usize>,
244 pub nonce: u32,
245 pub bits: String,
246 pub difficulty: f64,
247 #[serde(with = "crate::serde_hex")]
248 pub chainwork: Vec<u8>,
249 pub n_tx: usize,
250 #[serde(rename = "previousblockhash")]
251 pub previous_block_hash: Option<bitcoin::BlockHash>,
252 #[serde(rename = "nextblockhash")]
253 pub next_block_hash: Option<bitcoin::BlockHash>,
254}
255
256#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
257pub struct GetBlockStatsResult {
258 #[serde(rename = "avgfee", with = "bitcoin::amount::serde::as_sat")]
259 pub avg_fee: Amount,
260 #[serde(rename = "avgfeerate", with = "bitcoin::amount::serde::as_sat")]
261 pub avg_fee_rate: Amount,
262 #[serde(rename = "avgtxsize")]
263 pub avg_tx_size: u32,
264 #[serde(rename = "blockhash")]
265 pub block_hash: bitcoin::BlockHash,
266 #[serde(rename = "feerate_percentiles")]
267 pub fee_rate_percentiles: FeeRatePercentiles,
268 pub height: u64,
269 pub ins: usize,
270 #[serde(rename = "maxfee", with = "bitcoin::amount::serde::as_sat")]
271 pub max_fee: Amount,
272 #[serde(rename = "maxfeerate", with = "bitcoin::amount::serde::as_sat")]
273 pub max_fee_rate: Amount,
274 #[serde(rename = "maxtxsize")]
275 pub max_tx_size: u32,
276 #[serde(rename = "medianfee", with = "bitcoin::amount::serde::as_sat")]
277 pub median_fee: Amount,
278 #[serde(rename = "mediantime")]
279 pub median_time: u64,
280 #[serde(rename = "mediantxsize")]
281 pub median_tx_size: u32,
282 #[serde(rename = "minfee", with = "bitcoin::amount::serde::as_sat")]
283 pub min_fee: Amount,
284 #[serde(rename = "minfeerate", with = "bitcoin::amount::serde::as_sat")]
285 pub min_fee_rate: Amount,
286 #[serde(rename = "mintxsize")]
287 pub min_tx_size: u32,
288 pub outs: usize,
289 #[serde(with = "bitcoin::amount::serde::as_sat")]
290 pub subsidy: Amount,
291 #[serde(rename = "swtotal_size")]
292 pub sw_total_size: usize,
293 #[serde(rename = "swtotal_weight")]
294 pub sw_total_weight: usize,
295 #[serde(rename = "swtxs")]
296 pub sw_txs: usize,
297 pub time: u64,
298 #[serde(with = "bitcoin::amount::serde::as_sat")]
299 pub total_out: Amount,
300 pub total_size: usize,
301 pub total_weight: usize,
302 #[serde(rename = "totalfee", with = "bitcoin::amount::serde::as_sat")]
303 pub total_fee: Amount,
304 pub txs: usize,
305 pub utxo_increase: i32,
306 pub utxo_size_inc: i32,
307}
308
309#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
310pub struct GetBlockStatsResultPartial {
311 #[serde(
312 default,
313 rename = "avgfee",
314 with = "bitcoin::amount::serde::as_sat::opt",
315 skip_serializing_if = "Option::is_none"
316 )]
317 pub avg_fee: Option<Amount>,
318 #[serde(
319 default,
320 rename = "avgfeerate",
321 with = "bitcoin::amount::serde::as_sat::opt",
322 skip_serializing_if = "Option::is_none"
323 )]
324 pub avg_fee_rate: Option<Amount>,
325 #[serde(default, rename = "avgtxsize", skip_serializing_if = "Option::is_none")]
326 pub avg_tx_size: Option<u32>,
327 #[serde(default, rename = "blockhash", skip_serializing_if = "Option::is_none")]
328 pub block_hash: Option<bitcoin::BlockHash>,
329 #[serde(default, rename = "feerate_percentiles", skip_serializing_if = "Option::is_none")]
330 pub fee_rate_percentiles: Option<FeeRatePercentiles>,
331 #[serde(default, skip_serializing_if = "Option::is_none")]
332 pub height: Option<u64>,
333 #[serde(default, skip_serializing_if = "Option::is_none")]
334 pub ins: Option<usize>,
335 #[serde(
336 default,
337 rename = "maxfee",
338 with = "bitcoin::amount::serde::as_sat::opt",
339 skip_serializing_if = "Option::is_none"
340 )]
341 pub max_fee: Option<Amount>,
342 #[serde(
343 default,
344 rename = "maxfeerate",
345 with = "bitcoin::amount::serde::as_sat::opt",
346 skip_serializing_if = "Option::is_none"
347 )]
348 pub max_fee_rate: Option<Amount>,
349 #[serde(default, rename = "maxtxsize", skip_serializing_if = "Option::is_none")]
350 pub max_tx_size: Option<u32>,
351 #[serde(
352 default,
353 rename = "medianfee",
354 with = "bitcoin::amount::serde::as_sat::opt",
355 skip_serializing_if = "Option::is_none"
356 )]
357 pub median_fee: Option<Amount>,
358 #[serde(default, rename = "mediantime", skip_serializing_if = "Option::is_none")]
359 pub median_time: Option<u64>,
360 #[serde(default, rename = "mediantxsize", skip_serializing_if = "Option::is_none")]
361 pub median_tx_size: Option<u32>,
362 #[serde(
363 default,
364 rename = "minfee",
365 with = "bitcoin::amount::serde::as_sat::opt",
366 skip_serializing_if = "Option::is_none"
367 )]
368 pub min_fee: Option<Amount>,
369 #[serde(
370 default,
371 rename = "minfeerate",
372 with = "bitcoin::amount::serde::as_sat::opt",
373 skip_serializing_if = "Option::is_none"
374 )]
375 pub min_fee_rate: Option<Amount>,
376 #[serde(default, rename = "mintxsize", skip_serializing_if = "Option::is_none")]
377 pub min_tx_size: Option<u32>,
378 #[serde(default, skip_serializing_if = "Option::is_none")]
379 pub outs: Option<usize>,
380 #[serde(
381 default,
382 with = "bitcoin::amount::serde::as_sat::opt",
383 skip_serializing_if = "Option::is_none"
384 )]
385 pub subsidy: Option<Amount>,
386 #[serde(default, rename = "swtotal_size", skip_serializing_if = "Option::is_none")]
387 pub sw_total_size: Option<usize>,
388 #[serde(default, rename = "swtotal_weight", skip_serializing_if = "Option::is_none")]
389 pub sw_total_weight: Option<usize>,
390 #[serde(default, rename = "swtxs", skip_serializing_if = "Option::is_none")]
391 pub sw_txs: Option<usize>,
392 #[serde(default, skip_serializing_if = "Option::is_none")]
393 pub time: Option<u64>,
394 #[serde(
395 default,
396 with = "bitcoin::amount::serde::as_sat::opt",
397 skip_serializing_if = "Option::is_none"
398 )]
399 pub total_out: Option<Amount>,
400 #[serde(default, skip_serializing_if = "Option::is_none")]
401 pub total_size: Option<usize>,
402 #[serde(default, skip_serializing_if = "Option::is_none")]
403 pub total_weight: Option<usize>,
404 #[serde(
405 default,
406 rename = "totalfee",
407 with = "bitcoin::amount::serde::as_sat::opt",
408 skip_serializing_if = "Option::is_none"
409 )]
410 pub total_fee: Option<Amount>,
411 #[serde(default, skip_serializing_if = "Option::is_none")]
412 pub txs: Option<usize>,
413 #[serde(default, skip_serializing_if = "Option::is_none")]
414 pub utxo_increase: Option<i32>,
415 #[serde(default, skip_serializing_if = "Option::is_none")]
416 pub utxo_size_inc: Option<i32>,
417}
418
419#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
420pub struct FeeRatePercentiles {
421 #[serde(with = "bitcoin::amount::serde::as_sat")]
422 pub fr_10th: Amount,
423 #[serde(with = "bitcoin::amount::serde::as_sat")]
424 pub fr_25th: Amount,
425 #[serde(with = "bitcoin::amount::serde::as_sat")]
426 pub fr_50th: Amount,
427 #[serde(with = "bitcoin::amount::serde::as_sat")]
428 pub fr_75th: Amount,
429 #[serde(with = "bitcoin::amount::serde::as_sat")]
430 pub fr_90th: Amount,
431}
432
433#[derive(Clone)]
434pub enum BlockStatsFields {
435 AverageFee,
436 AverageFeeRate,
437 AverageTxSize,
438 BlockHash,
439 FeeRatePercentiles,
440 Height,
441 Ins,
442 MaxFee,
443 MaxFeeRate,
444 MaxTxSize,
445 MedianFee,
446 MedianTime,
447 MedianTxSize,
448 MinFee,
449 MinFeeRate,
450 MinTxSize,
451 Outs,
452 Subsidy,
453 SegWitTotalSize,
454 SegWitTotalWeight,
455 SegWitTxs,
456 Time,
457 TotalOut,
458 TotalSize,
459 TotalWeight,
460 TotalFee,
461 Txs,
462 UtxoIncrease,
463 UtxoSizeIncrease,
464}
465
466impl BlockStatsFields {
467 fn get_rpc_keyword(&self) -> &str {
468 match *self {
469 BlockStatsFields::AverageFee => "avgfee",
470 BlockStatsFields::AverageFeeRate => "avgfeerate",
471 BlockStatsFields::AverageTxSize => "avgtxsize",
472 BlockStatsFields::BlockHash => "blockhash",
473 BlockStatsFields::FeeRatePercentiles => "feerate_percentiles",
474 BlockStatsFields::Height => "height",
475 BlockStatsFields::Ins => "ins",
476 BlockStatsFields::MaxFee => "maxfee",
477 BlockStatsFields::MaxFeeRate => "maxfeerate",
478 BlockStatsFields::MaxTxSize => "maxtxsize",
479 BlockStatsFields::MedianFee => "medianfee",
480 BlockStatsFields::MedianTime => "mediantime",
481 BlockStatsFields::MedianTxSize => "mediantxsize",
482 BlockStatsFields::MinFee => "minfee",
483 BlockStatsFields::MinFeeRate => "minfeerate",
484 BlockStatsFields::MinTxSize => "minfeerate",
485 BlockStatsFields::Outs => "outs",
486 BlockStatsFields::Subsidy => "subsidy",
487 BlockStatsFields::SegWitTotalSize => "swtotal_size",
488 BlockStatsFields::SegWitTotalWeight => "swtotal_weight",
489 BlockStatsFields::SegWitTxs => "swtxs",
490 BlockStatsFields::Time => "time",
491 BlockStatsFields::TotalOut => "total_out",
492 BlockStatsFields::TotalSize => "total_size",
493 BlockStatsFields::TotalWeight => "total_weight",
494 BlockStatsFields::TotalFee => "totalfee",
495 BlockStatsFields::Txs => "txs",
496 BlockStatsFields::UtxoIncrease => "utxo_increase",
497 BlockStatsFields::UtxoSizeIncrease => "utxo_size_inc",
498 }
499 }
500}
501
502impl fmt::Display for BlockStatsFields {
503 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
504 write!(f, "{}", self.get_rpc_keyword())
505 }
506}
507
508impl From<BlockStatsFields> for serde_json::Value {
509 fn from(bsf: BlockStatsFields) -> Self {
510 Self::from(bsf.to_string())
511 }
512}
513
514#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
515#[serde(rename_all = "camelCase")]
516pub struct GetMiningInfoResult {
517 pub blocks: u32,
518 #[serde(rename = "currentblockweight")]
519 pub current_block_weight: Option<u64>,
520 #[serde(rename = "currentblocktx")]
521 pub current_block_tx: Option<usize>,
522 pub difficulty: f64,
523 #[serde(rename = "networkhashps")]
524 pub network_hash_ps: f64,
525 #[serde(rename = "pooledtx")]
526 pub pooled_tx: usize,
527 #[serde(deserialize_with = "deserialize_bip70_network")]
528 pub chain: Network,
529 pub warnings: StringOrStringArray,
530}
531
532#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
533#[serde(rename_all = "camelCase")]
534pub struct GetRawTransactionResultVinScriptSig {
535 pub asm: String,
536 #[serde(with = "crate::serde_hex")]
537 pub hex: Vec<u8>,
538}
539
540impl GetRawTransactionResultVinScriptSig {
541 pub fn script(&self) -> Result<ScriptBuf, encode::Error> {
542 Ok(ScriptBuf::from(self.hex.clone()))
543 }
544}
545
546#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
547#[serde(rename_all = "camelCase")]
548pub struct GetRawTransactionResultVin {
549 pub sequence: u32,
550 #[serde(default, with = "crate::serde_hex::opt")]
552 pub coinbase: Option<Vec<u8>>,
553 pub txid: Option<bitcoin::Txid>,
555 pub vout: Option<u32>,
557 pub script_sig: Option<GetRawTransactionResultVinScriptSig>,
559 #[serde(default, deserialize_with = "deserialize_hex_array_opt")]
561 pub txinwitness: Option<Vec<Vec<u8>>>,
562}
563
564impl GetRawTransactionResultVin {
565 pub fn is_coinbase(&self) -> bool {
569 self.coinbase.is_some()
570 }
571}
572
573#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
574#[serde(rename_all = "camelCase")]
575pub struct GetRawTransactionResultVoutScriptPubKey {
576 pub asm: String,
577 #[serde(with = "crate::serde_hex")]
578 pub hex: Vec<u8>,
579 pub req_sigs: Option<usize>,
580 #[serde(rename = "type")]
581 pub type_: Option<ScriptPubkeyType>,
582 #[serde(default)]
584 pub addresses: Vec<Address<NetworkUnchecked>>,
585 #[serde(default)]
587 pub address: Option<Address<NetworkUnchecked>>,
588}
589
590impl GetRawTransactionResultVoutScriptPubKey {
591 pub fn script(&self) -> Result<ScriptBuf, encode::Error> {
592 Ok(ScriptBuf::from(self.hex.clone()))
593 }
594}
595
596#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
597#[serde(rename_all = "camelCase")]
598pub struct GetRawTransactionResultVout {
599 #[serde(with = "bitcoin::amount::serde::as_btc")]
600 pub value: Amount,
601 pub n: u32,
602 pub script_pub_key: GetRawTransactionResultVoutScriptPubKey,
603}
604
605#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
606#[serde(rename_all = "camelCase")]
607pub struct GetRawTransactionResult {
608 #[serde(rename = "in_active_chain")]
609 pub in_active_chain: Option<bool>,
610 #[serde(with = "crate::serde_hex")]
611 pub hex: Vec<u8>,
612 pub txid: bitcoin::Txid,
613 pub hash: bitcoin::Wtxid,
614 pub size: usize,
615 pub vsize: usize,
616 pub version: u32,
617 pub locktime: u32,
618 pub vin: Vec<GetRawTransactionResultVin>,
619 pub vout: Vec<GetRawTransactionResultVout>,
620 pub blockhash: Option<bitcoin::BlockHash>,
621 pub confirmations: Option<u32>,
622 pub time: Option<usize>,
623 pub blocktime: Option<usize>,
624}
625
626#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
627pub struct GetBlockFilterResult {
628 pub header: bitcoin::hash_types::FilterHash,
629 #[serde(with = "crate::serde_hex")]
630 pub filter: Vec<u8>,
631}
632
633impl GetBlockFilterResult {
634 pub fn to_filter(&self) -> bip158::BlockFilter {
638 bip158::BlockFilter::new(&self.filter)
639 }
640
641 pub fn into_filter(self) -> bip158::BlockFilter {
643 bip158::BlockFilter {
644 content: self.filter,
645 }
646 }
647}
648
649impl GetRawTransactionResult {
650 pub fn is_coinbase(&self) -> bool {
652 self.vin.len() == 1 && self.vin[0].is_coinbase()
653 }
654
655 pub fn transaction(&self) -> Result<Transaction, encode::Error> {
656 Ok(encode::deserialize(&self.hex)?)
657 }
658}
659
660#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
662#[serde(rename_all = "lowercase")]
663pub enum Bip125Replaceable {
664 Yes,
665 No,
666 Unknown,
667}
668
669#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
671#[serde(rename_all = "lowercase")]
672pub enum GetTransactionResultDetailCategory {
673 Send,
674 Receive,
675 Generate,
676 Immature,
677 Orphan,
678}
679
680#[derive(Clone, PartialEq, Eq, Debug, Deserialize)]
681pub struct GetTransactionResultDetail {
682 pub address: Option<Address<NetworkUnchecked>>,
683 pub category: GetTransactionResultDetailCategory,
684 #[serde(with = "bitcoin::amount::serde::as_btc")]
685 pub amount: SignedAmount,
686 pub label: Option<String>,
687 pub vout: u32,
688 #[serde(default, with = "bitcoin::amount::serde::as_btc::opt")]
689 pub fee: Option<SignedAmount>,
690 pub abandoned: Option<bool>,
691}
692
693#[derive(Clone, PartialEq, Eq, Debug, Deserialize)]
694pub struct WalletTxInfo {
695 pub confirmations: i32,
696 pub blockhash: Option<bitcoin::BlockHash>,
697 pub blockindex: Option<usize>,
698 pub blocktime: Option<u64>,
699 pub blockheight: Option<u32>,
700 pub txid: bitcoin::Txid,
701 pub time: u64,
702 pub timereceived: u64,
703 #[serde(rename = "bip125-replaceable")]
704 pub bip125_replaceable: Bip125Replaceable,
705 #[serde(rename = "walletconflicts")]
707 pub wallet_conflicts: Vec<bitcoin::Txid>,
708}
709
710#[derive(Clone, PartialEq, Eq, Debug, Deserialize)]
711pub struct GetTransactionResult {
712 #[serde(flatten)]
713 pub info: WalletTxInfo,
714 #[serde(with = "bitcoin::amount::serde::as_btc")]
715 pub amount: SignedAmount,
716 #[serde(default, with = "bitcoin::amount::serde::as_btc::opt")]
717 pub fee: Option<SignedAmount>,
718 pub details: Vec<GetTransactionResultDetail>,
719 #[serde(with = "crate::serde_hex")]
720 pub hex: Vec<u8>,
721}
722
723impl GetTransactionResult {
724 pub fn transaction(&self) -> Result<Transaction, encode::Error> {
725 Ok(encode::deserialize(&self.hex)?)
726 }
727}
728
729#[derive(Clone, PartialEq, Eq, Debug, Deserialize)]
730pub struct ListTransactionResult {
731 #[serde(flatten)]
732 pub info: WalletTxInfo,
733 #[serde(flatten)]
734 pub detail: GetTransactionResultDetail,
735
736 pub trusted: Option<bool>,
737 pub comment: Option<String>,
738}
739
740#[derive(Clone, PartialEq, Eq, Debug, Deserialize)]
741pub struct ListSinceBlockResult {
742 pub transactions: Vec<ListTransactionResult>,
743 #[serde(default)]
744 pub removed: Vec<ListTransactionResult>,
745 pub lastblock: bitcoin::BlockHash,
746}
747
748#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
749#[serde(rename_all = "camelCase")]
750pub struct GetTxOutResult {
751 pub bestblock: bitcoin::BlockHash,
752 pub confirmations: u32,
753 #[serde(with = "bitcoin::amount::serde::as_btc")]
754 pub value: Amount,
755 pub script_pub_key: GetRawTransactionResultVoutScriptPubKey,
756 pub coinbase: bool,
757}
758
759#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize, Default)]
760#[serde(rename_all = "camelCase")]
761pub struct ListUnspentQueryOptions {
762 #[serde(
763 rename = "minimumAmount",
764 with = "bitcoin::amount::serde::as_btc::opt",
765 skip_serializing_if = "Option::is_none"
766 )]
767 pub minimum_amount: Option<Amount>,
768 #[serde(
769 rename = "maximumAmount",
770 with = "bitcoin::amount::serde::as_btc::opt",
771 skip_serializing_if = "Option::is_none"
772 )]
773 pub maximum_amount: Option<Amount>,
774 #[serde(rename = "maximumCount", skip_serializing_if = "Option::is_none")]
775 pub maximum_count: Option<usize>,
776 #[serde(
777 rename = "minimumSumAmount",
778 with = "bitcoin::amount::serde::as_btc::opt",
779 skip_serializing_if = "Option::is_none"
780 )]
781 pub minimum_sum_amount: Option<Amount>,
782}
783
784#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
785#[serde(rename_all = "camelCase")]
786pub struct ListUnspentResultEntry {
787 pub txid: bitcoin::Txid,
788 pub vout: u32,
789 pub address: Option<Address<NetworkUnchecked>>,
790 pub label: Option<String>,
791 pub redeem_script: Option<ScriptBuf>,
792 pub witness_script: Option<ScriptBuf>,
793 pub script_pub_key: ScriptBuf,
794 #[serde(with = "bitcoin::amount::serde::as_btc")]
795 pub amount: Amount,
796 pub confirmations: u32,
797 pub spendable: bool,
798 pub solvable: bool,
799 #[serde(rename = "desc")]
800 pub descriptor: Option<String>,
801 pub safe: bool,
802}
803
804#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
805#[serde(rename_all = "camelCase")]
806pub struct ListReceivedByAddressResult {
807 #[serde(default, rename = "involvesWatchonly")]
808 pub involved_watch_only: bool,
809 pub address: Address<NetworkUnchecked>,
810 #[serde(with = "bitcoin::amount::serde::as_btc")]
811 pub amount: Amount,
812 pub confirmations: u32,
813 pub label: String,
814 pub txids: Vec<bitcoin::Txid>,
815}
816
817#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
818#[serde(rename_all = "camelCase")]
819pub struct SignRawTransactionResultError {
820 pub txid: bitcoin::Txid,
821 pub vout: u32,
822 pub script_sig: ScriptBuf,
823 pub sequence: u32,
824 pub error: String,
825}
826
827#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
828#[serde(rename_all = "camelCase")]
829pub struct SignRawTransactionResult {
830 #[serde(with = "crate::serde_hex")]
831 pub hex: Vec<u8>,
832 pub complete: bool,
833 pub errors: Option<Vec<SignRawTransactionResultError>>,
834}
835
836impl SignRawTransactionResult {
837 pub fn transaction(&self) -> Result<Transaction, encode::Error> {
838 Ok(encode::deserialize(&self.hex)?)
839 }
840}
841
842#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
843pub struct TestMempoolAcceptResult {
844 pub txid: bitcoin::Txid,
845 pub allowed: bool,
846 #[serde(rename = "reject-reason")]
847 pub reject_reason: Option<String>,
848 pub vsize: Option<u64>,
851 pub fees: Option<TestMempoolAcceptResultFees>,
854}
855
856#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
857pub struct TestMempoolAcceptResultFees {
858 #[serde(with = "bitcoin::amount::serde::as_btc")]
860 pub base: Amount,
861 }
863
864#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
865#[serde(rename_all = "snake_case")]
866pub enum Bip9SoftforkStatus {
867 Defined,
868 Started,
869 LockedIn,
870 Active,
871 Failed,
872}
873
874#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
875pub struct Bip9SoftforkStatistics {
876 pub period: u32,
877 pub threshold: Option<u32>,
878 pub elapsed: u32,
879 pub count: u32,
880 pub possible: Option<bool>,
881}
882
883#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
884pub struct Bip9SoftforkInfo {
885 pub status: Bip9SoftforkStatus,
886 pub bit: Option<u8>,
887 pub start_time: i64,
889 pub timeout: u64,
890 pub since: u32,
891 pub statistics: Option<Bip9SoftforkStatistics>,
892}
893
894#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
895#[serde(rename_all = "lowercase")]
896pub enum SoftforkType {
897 Buried,
898 Bip9,
899 #[serde(other)]
900 Other,
901}
902
903#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
905pub struct Softfork {
906 #[serde(rename = "type")]
907 pub type_: SoftforkType,
908 pub bip9: Option<Bip9SoftforkInfo>,
909 pub height: Option<u32>,
910 pub active: bool,
911}
912
913#[allow(non_camel_case_types)]
914#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
915#[serde(rename_all = "lowercase")]
916pub enum ScriptPubkeyType {
917 Nonstandard,
918 Pubkey,
919 PubkeyHash,
920 ScriptHash,
921 MultiSig,
922 NullData,
923 Witness_v0_KeyHash,
924 Witness_v0_ScriptHash,
925 Witness_v1_Taproot,
926 Witness_Unknown,
927}
928
929#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
930pub struct GetAddressInfoResultEmbedded {
931 pub address: Address<NetworkUnchecked>,
932 #[serde(rename = "scriptPubKey")]
933 pub script_pub_key: ScriptBuf,
934 #[serde(rename = "is_script")]
935 pub is_script: Option<bool>,
936 #[serde(rename = "is_witness")]
937 pub is_witness: Option<bool>,
938 pub witness_version: Option<u32>,
939 #[serde(with = "crate::serde_hex")]
940 pub witness_program: Vec<u8>,
941 pub script: Option<ScriptPubkeyType>,
942 #[serde(default, with = "crate::serde_hex::opt")]
944 pub hex: Option<Vec<u8>>,
945 pub pubkeys: Option<Vec<PublicKey>>,
946 #[serde(rename = "sigsrequired")]
947 pub n_signatures_required: Option<usize>,
948 pub pubkey: Option<PublicKey>,
949 #[serde(rename = "is_compressed")]
950 pub is_compressed: Option<bool>,
951 pub label: Option<String>,
952 #[serde(rename = "hdkeypath")]
953 pub hd_key_path: Option<bip32::DerivationPath>,
954 #[serde(rename = "hdseedid")]
955 pub hd_seed_id: Option<bitcoin::bip32::XKeyIdentifier>,
956 #[serde(default)]
957 pub labels: Vec<GetAddressInfoResultLabel>,
958}
959
960#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
961#[serde(rename_all = "lowercase")]
962pub enum GetAddressInfoResultLabelPurpose {
963 Send,
964 Receive,
965}
966
967#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
968#[serde(untagged)]
969pub enum GetAddressInfoResultLabel {
970 Simple(String),
971 WithPurpose {
972 name: String,
973 purpose: GetAddressInfoResultLabelPurpose,
974 },
975}
976
977#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
978pub struct GetAddressInfoResult {
979 pub address: Address<NetworkUnchecked>,
980 #[serde(rename = "scriptPubKey")]
981 pub script_pub_key: ScriptBuf,
982 #[serde(rename = "ismine")]
983 pub is_mine: Option<bool>,
984 #[serde(rename = "iswatchonly")]
985 pub is_watchonly: Option<bool>,
986 #[serde(rename = "isscript")]
987 pub is_script: Option<bool>,
988 #[serde(rename = "iswitness")]
989 pub is_witness: Option<bool>,
990 pub witness_version: Option<u32>,
991 #[serde(default, with = "crate::serde_hex::opt")]
992 pub witness_program: Option<Vec<u8>>,
993 pub script: Option<ScriptPubkeyType>,
994 #[serde(default, with = "crate::serde_hex::opt")]
996 pub hex: Option<Vec<u8>>,
997 pub pubkeys: Option<Vec<PublicKey>>,
998 #[serde(rename = "sigsrequired")]
999 pub n_signatures_required: Option<usize>,
1000 pub pubkey: Option<PublicKey>,
1001 pub embedded: Option<GetAddressInfoResultEmbedded>,
1003 #[serde(rename = "is_compressed")]
1004 pub is_compressed: Option<bool>,
1005 pub timestamp: Option<u64>,
1006 #[serde(rename = "hdkeypath")]
1007 pub hd_key_path: Option<bip32::DerivationPath>,
1008 #[serde(rename = "hdseedid")]
1009 pub hd_seed_id: Option<bitcoin::bip32::XKeyIdentifier>,
1010 pub labels: Vec<GetAddressInfoResultLabel>,
1011 #[deprecated(note = "since Core v0.20.0")]
1013 pub label: Option<String>,
1014}
1015
1016#[derive(Clone, Debug, Deserialize, Serialize)]
1018pub struct GetBlockchainInfoResult {
1019 #[serde(deserialize_with = "deserialize_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)]
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(with = "bitcoin::amount::serde::as_btc::opt", skip_serializing_if = "Option::is_none")]
1891 pub fee_rate: Option<Amount>,
1892 #[serde(skip_serializing_if = "Option::is_none")]
1893 pub subtract_fee_from_outputs: Option<Vec<u32>>,
1894 #[serde(skip_serializing_if = "Option::is_none")]
1895 pub replaceable: Option<bool>,
1896 #[serde(rename = "conf_target", skip_serializing_if = "Option::is_none")]
1897 pub conf_target: Option<u32>,
1898 #[serde(rename = "estimate_mode", skip_serializing_if = "Option::is_none")]
1899 pub estimate_mode: Option<EstimateMode>,
1900}
1901
1902#[derive(Deserialize, Clone, PartialEq, Eq, Debug)]
1903#[serde(rename_all = "camelCase")]
1904pub struct FundRawTransactionResult {
1905 #[serde(with = "crate::serde_hex")]
1906 pub hex: Vec<u8>,
1907 #[serde(with = "bitcoin::amount::serde::as_btc")]
1908 pub fee: Amount,
1909 #[serde(rename = "changepos")]
1910 pub change_position: i32,
1911}
1912
1913#[derive(Deserialize, Clone, PartialEq, Eq, Debug)]
1914pub struct GetBalancesResultEntry {
1915 #[serde(with = "bitcoin::amount::serde::as_btc")]
1916 pub trusted: Amount,
1917 #[serde(with = "bitcoin::amount::serde::as_btc")]
1918 pub untrusted_pending: Amount,
1919 #[serde(with = "bitcoin::amount::serde::as_btc")]
1920 pub immature: Amount,
1921}
1922
1923#[derive(Deserialize, Clone, PartialEq, Eq, Debug)]
1924#[serde(rename_all = "camelCase")]
1925pub struct GetBalancesResult {
1926 pub mine: GetBalancesResultEntry,
1927 pub watchonly: Option<GetBalancesResultEntry>,
1928}
1929
1930impl FundRawTransactionResult {
1931 pub fn transaction(&self) -> Result<Transaction, encode::Error> {
1932 encode::deserialize(&self.hex)
1933 }
1934}
1935
1936#[derive(Serialize, Clone, PartialEq, Debug)]
1938#[serde(rename_all = "camelCase")]
1939pub struct SignRawTransactionInput {
1940 pub txid: bitcoin::Txid,
1941 pub vout: u32,
1942 pub script_pub_key: ScriptBuf,
1943 #[serde(skip_serializing_if = "Option::is_none")]
1944 pub redeem_script: Option<ScriptBuf>,
1945 #[serde(
1946 default,
1947 skip_serializing_if = "Option::is_none",
1948 with = "bitcoin::amount::serde::as_btc::opt"
1949 )]
1950 pub amount: Option<Amount>,
1951}
1952
1953#[derive(Clone, Serialize, PartialEq, Eq, Debug)]
1955#[serde(rename_all = "snake_case")]
1956pub enum TxOutSetHashType {
1957 HashSerialized2,
1958 Muhash,
1959 None,
1960}
1961
1962#[derive(Clone, Serialize, PartialEq, Eq, Debug)]
1964#[serde(untagged)]
1965pub enum HashOrHeight {
1966 BlockHash(bitcoin::BlockHash),
1967 Height(u64),
1968}
1969
1970#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1971pub struct GetTxOutSetInfoResult {
1972 pub height: u64,
1974 #[serde(rename = "bestblock")]
1976 pub best_block: bitcoin::BlockHash,
1977 #[serde(default, skip_serializing_if = "Option::is_none")]
1979 pub transactions: Option<u64>,
1980 #[serde(rename = "txouts")]
1982 pub tx_outs: u64,
1983 pub bogosize: u64,
1985 #[serde(default, skip_serializing_if = "Option::is_none")]
1987 pub hash_serialized_2: Option<sha256::Hash>,
1988 #[serde(default, skip_serializing_if = "Option::is_none")]
1990 pub muhash: Option<sha256::Hash>,
1991 #[serde(default, skip_serializing_if = "Option::is_none")]
1993 pub disk_size: Option<u64>,
1994 #[serde(with = "bitcoin::amount::serde::as_btc")]
1996 pub total_amount: Amount,
1997 #[serde(
1999 default,
2000 skip_serializing_if = "Option::is_none",
2001 with = "bitcoin::amount::serde::as_btc::opt"
2002 )]
2003 pub total_unspendable_amount: Option<Amount>,
2004 #[serde(default, skip_serializing_if = "Option::is_none")]
2006 pub block_info: Option<BlockInfo>,
2007}
2008
2009#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
2011pub struct BlockInfo {
2012 #[serde(with = "bitcoin::amount::serde::as_btc")]
2014 pub prevout_spent: Amount,
2015 #[serde(with = "bitcoin::amount::serde::as_btc")]
2017 pub coinbase: Amount,
2018 #[serde(with = "bitcoin::amount::serde::as_btc")]
2020 pub new_outputs_ex_coinbase: Amount,
2021 #[serde(with = "bitcoin::amount::serde::as_btc")]
2023 pub unspendable: Amount,
2024 pub unspendables: Unspendables,
2026}
2027
2028#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
2030pub struct Unspendables {
2031 #[serde(with = "bitcoin::amount::serde::as_btc")]
2033 pub genesis_block: Amount,
2034 #[serde(with = "bitcoin::amount::serde::as_btc")]
2036 pub bip30: Amount,
2037 #[serde(with = "bitcoin::amount::serde::as_btc")]
2039 pub scripts: Amount,
2040 #[serde(with = "bitcoin::amount::serde::as_btc")]
2042 pub unclaimed_rewards: Amount,
2043}
2044
2045#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
2046pub struct GetNetTotalsResult {
2047 #[serde(rename = "totalbytesrecv")]
2049 pub total_bytes_recv: u64,
2050 #[serde(rename = "totalbytessent")]
2052 pub total_bytes_sent: u64,
2053 #[serde(rename = "timemillis")]
2055 pub time_millis: u64,
2056 #[serde(rename = "uploadtarget")]
2058 pub upload_target: GetNetTotalsResultUploadTarget,
2059}
2060
2061#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
2062pub struct GetNetTotalsResultUploadTarget {
2063 #[serde(rename = "timeframe")]
2065 pub time_frame: u64,
2066 pub target: u64,
2068 pub target_reached: bool,
2070 pub serve_historical_blocks: bool,
2072 pub bytes_left_in_cycle: u64,
2074 pub time_left_in_cycle: u64,
2076}
2077
2078#[derive(Copy, Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
2080#[serde(rename_all = "kebab-case")]
2081pub enum AddressType {
2082 Legacy,
2083 P2shSegwit,
2084 Bech32,
2085 Bech32m,
2086}
2087
2088#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
2090pub enum PubKeyOrAddress<'a> {
2091 Address(&'a Address),
2092 PubKey(&'a PublicKey),
2093}
2094
2095#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
2096#[serde(untagged)]
2097pub enum ScanTxOutRequest {
2099 Single(String),
2101 Extended {
2103 desc: String,
2105 range: (u64, u64),
2107 },
2108}
2109
2110#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
2111pub struct ScanTxOutResult {
2112 pub success: Option<bool>,
2113 #[serde(rename = "txouts")]
2114 pub tx_outs: Option<u64>,
2115 pub height: Option<u64>,
2116 #[serde(rename = "bestblock")]
2117 pub best_block_hash: Option<bitcoin::BlockHash>,
2118 pub unspents: Vec<Utxo>,
2119 #[serde(with = "bitcoin::amount::serde::as_btc")]
2120 pub total_amount: bitcoin::Amount,
2121}
2122
2123#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
2124#[serde(rename_all = "camelCase")]
2125pub struct Utxo {
2126 pub txid: bitcoin::Txid,
2127 pub vout: u32,
2128 pub script_pub_key: bitcoin::ScriptBuf,
2129 #[serde(rename = "desc")]
2130 pub descriptor: String,
2131 #[serde(with = "bitcoin::amount::serde::as_btc")]
2132 pub amount: bitcoin::Amount,
2133 pub height: u64,
2134}
2135
2136#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
2137pub struct IndexStatus {
2138 pub synced: bool,
2139 pub best_block_height: u32,
2140}
2141
2142#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
2143pub struct GetIndexInfoResult {
2144 pub txindex: Option<IndexStatus>,
2145 pub coinstatsindex: Option<IndexStatus>,
2146 #[serde(rename = "basic block filter index")]
2147 pub basic_block_filter_index: Option<IndexStatus>,
2148}
2149
2150impl<'a> serde::Serialize for PubKeyOrAddress<'a> {
2151 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
2152 where
2153 S: serde::Serializer,
2154 {
2155 match *self {
2156 PubKeyOrAddress::Address(a) => serde::Serialize::serialize(a, serializer),
2157 PubKeyOrAddress::PubKey(k) => serde::Serialize::serialize(k, serializer),
2158 }
2159 }
2160}
2161
2162fn deserialize_hex_array_opt<'de, D>(deserializer: D) -> Result<Option<Vec<Vec<u8>>>, D::Error>
2166where
2167 D: serde::Deserializer<'de>,
2168{
2169 let v: Vec<String> = Vec::deserialize(deserializer)?;
2173 let mut res = Vec::new();
2174 for h in v.into_iter() {
2175 res.push(FromHex::from_hex(&h).map_err(D::Error::custom)?);
2176 }
2177 Ok(Some(res))
2178}
2179
2180fn deserialize_bip70_network<'de, D>(deserializer: D) -> Result<Network, D::Error>
2183where
2184 D: serde::Deserializer<'de>,
2185{
2186 struct NetworkVisitor;
2187 impl<'de> serde::de::Visitor<'de> for NetworkVisitor {
2188 type Value = Network;
2189
2190 fn visit_str<E: serde::de::Error>(self, s: &str) -> Result<Self::Value, E> {
2191 Network::from_core_arg(s).map_err(|_| {
2192 E::invalid_value(
2193 serde::de::Unexpected::Str(s),
2194 &"bitcoin network encoded as a string",
2195 )
2196 })
2197 }
2198
2199 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
2200 write!(formatter, "bitcoin network encoded as a string")
2201 }
2202 }
2203
2204 deserializer.deserialize_str(NetworkVisitor)
2205}
2206
2207#[cfg(test)]
2208mod tests {
2209 use super::*;
2210
2211 #[test]
2212 fn test_softfork_type() {
2213 let buried: SoftforkType = serde_json::from_str("\"buried\"").unwrap();
2214 assert_eq!(buried, SoftforkType::Buried);
2215 let bip9: SoftforkType = serde_json::from_str("\"bip9\"").unwrap();
2216 assert_eq!(bip9, SoftforkType::Bip9);
2217 let other: SoftforkType = serde_json::from_str("\"bip8\"").unwrap();
2218 assert_eq!(other, SoftforkType::Other);
2219 }
2220}