1#![crate_name = "core_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::{Address, Amount, PrivateKey, PublicKey, SignedAmount, Transaction, ScriptBuf, Script, bip158, bip32};
33use serde::de::Error as SerdeError;
34use serde::{Deserialize, Serialize};
35use std::fmt;
36
37pub mod serde_hex {
43 use bitcoin::hashes::hex::FromHex;
44 use bitcoin_private::hex::exts::DisplayHex;
45 use serde::de::Error;
46 use serde::{Deserializer, Serializer};
47
48 pub fn serialize<S: Serializer>(b: &Vec<u8>, s: S) -> Result<S::Ok, S::Error> {
49 s.serialize_str(&b.to_lower_hex_string())
50 }
51
52 pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result<Vec<u8>, D::Error> {
53 let hex_str: String = ::serde::Deserialize::deserialize(d)?;
54 Ok(FromHex::from_hex(&hex_str).map_err(D::Error::custom)?)
55 }
56
57 pub mod opt {
58 use bitcoin::hashes::hex::FromHex;
59 use bitcoin_private::hex::exts::DisplayHex;
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: String,
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 ListWalletDirResult {
139 pub wallets: Vec<ListWalletDirItem>,
140}
141
142#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
143pub struct ListWalletDirItem {
144 pub name: String,
145}
146
147#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
148pub struct GetWalletInfoResult {
149 #[serde(rename = "walletname")]
150 pub wallet_name: String,
151 #[serde(rename = "walletversion")]
152 pub wallet_version: u32,
153 #[serde(with = "bitcoin::amount::serde::as_btc")]
154 pub balance: Amount,
155 #[serde(with = "bitcoin::amount::serde::as_btc")]
156 pub unconfirmed_balance: Amount,
157 #[serde(with = "bitcoin::amount::serde::as_btc")]
158 pub immature_balance: Amount,
159 #[serde(rename = "txcount")]
160 pub tx_count: usize,
161 #[serde(rename = "keypoololdest")]
162 pub keypool_oldest: Option<usize>,
163 #[serde(rename = "keypoolsize")]
164 pub keypool_size: usize,
165 #[serde(rename = "keypoolsize_hd_internal")]
166 pub keypool_size_hd_internal: usize,
167 pub unlocked_until: Option<u64>,
168 #[serde(rename = "paytxfee", with = "bitcoin::amount::serde::as_btc")]
169 pub pay_tx_fee: Amount,
170 #[serde(rename = "hdseedid")]
171 pub hd_seed_id: Option<bitcoin::hash_types::XpubIdentifier>,
172 pub private_keys_enabled: bool,
173 pub avoid_reuse: Option<bool>,
174 pub scanning: Option<ScanningDetails>,
175}
176
177#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
178#[serde(untagged)]
179pub enum ScanningDetails {
180 Scanning {
181 duration: usize,
182 progress: f32,
183 },
184 NotScanning(bool),
186}
187
188impl Eq for ScanningDetails {}
189
190#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
191#[serde(rename_all = "camelCase")]
192pub struct GetBlockResult {
193 pub hash: bitcoin::BlockHash,
194 pub confirmations: i32,
195 pub size: usize,
196 pub strippedsize: Option<usize>,
197 pub weight: usize,
198 pub height: usize,
199 pub version: i32,
200 #[serde(default, with = "crate::serde_hex::opt")]
201 pub version_hex: Option<Vec<u8>>,
202 pub merkleroot: bitcoin::hash_types::TxMerkleNode,
203 pub tx: Vec<bitcoin::Txid>,
204 pub time: usize,
205 pub mediantime: Option<usize>,
206 pub nonce: u32,
207 pub bits: String,
208 pub difficulty: f64,
209 #[serde(with = "crate::serde_hex")]
210 pub chainwork: Vec<u8>,
211 pub n_tx: usize,
212 pub previousblockhash: Option<bitcoin::BlockHash>,
213 pub nextblockhash: Option<bitcoin::BlockHash>,
214}
215
216#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
217#[serde(rename_all = "camelCase")]
218pub struct GetBlockHeaderResult {
219 pub hash: bitcoin::BlockHash,
220 pub confirmations: i32,
221 pub height: usize,
222 pub version: Version,
223 #[serde(default, with = "crate::serde_hex::opt")]
224 pub version_hex: Option<Vec<u8>>,
225 #[serde(rename = "merkleroot")]
226 pub merkle_root: bitcoin::hash_types::TxMerkleNode,
227 pub time: usize,
228 #[serde(rename = "mediantime")]
229 pub median_time: Option<usize>,
230 pub nonce: u32,
231 pub bits: String,
232 pub difficulty: f64,
233 #[serde(with = "crate::serde_hex")]
234 pub chainwork: Vec<u8>,
235 pub n_tx: usize,
236 #[serde(rename = "previousblockhash")]
237 pub previous_block_hash: Option<bitcoin::BlockHash>,
238 #[serde(rename = "nextblockhash")]
239 pub next_block_hash: Option<bitcoin::BlockHash>,
240}
241
242#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
243pub struct GetBlockStatsResult {
244 #[serde(rename = "avgfee", with = "bitcoin::amount::serde::as_sat")]
245 pub avg_fee: Amount,
246 #[serde(rename = "avgfeerate", with = "bitcoin::amount::serde::as_sat")]
247 pub avg_fee_rate: Amount,
248 #[serde(rename = "avgtxsize")]
249 pub avg_tx_size: u32,
250 #[serde(rename = "blockhash")]
251 pub block_hash: bitcoin::BlockHash,
252 #[serde(rename = "feerate_percentiles")]
253 pub fee_rate_percentiles: FeeRatePercentiles,
254 pub height: u64,
255 pub ins: usize,
256 #[serde(rename = "maxfee", with = "bitcoin::amount::serde::as_sat")]
257 pub max_fee: Amount,
258 #[serde(rename = "maxfeerate", with = "bitcoin::amount::serde::as_sat")]
259 pub max_fee_rate: Amount,
260 #[serde(rename = "maxtxsize")]
261 pub max_tx_size: u32,
262 #[serde(rename = "medianfee", with = "bitcoin::amount::serde::as_sat")]
263 pub median_fee: Amount,
264 #[serde(rename = "mediantime")]
265 pub median_time: u64,
266 #[serde(rename = "mediantxsize")]
267 pub median_tx_size: u32,
268 #[serde(rename = "minfee", with = "bitcoin::amount::serde::as_sat")]
269 pub min_fee: Amount,
270 #[serde(rename = "minfeerate", with = "bitcoin::amount::serde::as_sat")]
271 pub min_fee_rate: Amount,
272 #[serde(rename = "mintxsize")]
273 pub min_tx_size: u32,
274 pub outs: usize,
275 #[serde(with = "bitcoin::amount::serde::as_sat")]
276 pub subsidy: Amount,
277 #[serde(rename = "swtotal_size")]
278 pub sw_total_size: usize,
279 #[serde(rename = "swtotal_weight")]
280 pub sw_total_weight: usize,
281 #[serde(rename = "swtxs")]
282 pub sw_txs: usize,
283 pub time: u64,
284 #[serde(with = "bitcoin::amount::serde::as_sat")]
285 pub total_out: Amount,
286 pub total_size: usize,
287 pub total_weight: usize,
288 #[serde(rename = "totalfee", with = "bitcoin::amount::serde::as_sat")]
289 pub total_fee: Amount,
290 pub txs: usize,
291 pub utxo_increase: i32,
292 pub utxo_size_inc: i32,
293}
294
295#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
296pub struct GetBlockStatsResultPartial {
297 #[serde(
298 default,
299 rename = "avgfee",
300 with = "bitcoin::amount::serde::as_sat::opt",
301 skip_serializing_if = "Option::is_none"
302 )]
303 pub avg_fee: Option<Amount>,
304 #[serde(
305 default,
306 rename = "avgfeerate",
307 with = "bitcoin::amount::serde::as_sat::opt",
308 skip_serializing_if = "Option::is_none"
309 )]
310 pub avg_fee_rate: Option<Amount>,
311 #[serde(default, rename = "avgtxsize", skip_serializing_if = "Option::is_none")]
312 pub avg_tx_size: Option<u32>,
313 #[serde(default, rename = "blockhash", skip_serializing_if = "Option::is_none")]
314 pub block_hash: Option<bitcoin::BlockHash>,
315 #[serde(default, rename = "feerate_percentiles", skip_serializing_if = "Option::is_none")]
316 pub fee_rate_percentiles: Option<FeeRatePercentiles>,
317 #[serde(default, skip_serializing_if = "Option::is_none")]
318 pub height: Option<u64>,
319 #[serde(default, skip_serializing_if = "Option::is_none")]
320 pub ins: Option<usize>,
321 #[serde(
322 default,
323 rename = "maxfee",
324 with = "bitcoin::amount::serde::as_sat::opt",
325 skip_serializing_if = "Option::is_none"
326 )]
327 pub max_fee: Option<Amount>,
328 #[serde(
329 default,
330 rename = "maxfeerate",
331 with = "bitcoin::amount::serde::as_sat::opt",
332 skip_serializing_if = "Option::is_none"
333 )]
334 pub max_fee_rate: Option<Amount>,
335 #[serde(default, rename = "maxtxsize", skip_serializing_if = "Option::is_none")]
336 pub max_tx_size: Option<u32>,
337 #[serde(
338 default,
339 rename = "medianfee",
340 with = "bitcoin::amount::serde::as_sat::opt",
341 skip_serializing_if = "Option::is_none"
342 )]
343 pub median_fee: Option<Amount>,
344 #[serde(default, rename = "mediantime", skip_serializing_if = "Option::is_none")]
345 pub median_time: Option<u64>,
346 #[serde(default, rename = "mediantxsize", skip_serializing_if = "Option::is_none")]
347 pub median_tx_size: Option<u32>,
348 #[serde(
349 default,
350 rename = "minfee",
351 with = "bitcoin::amount::serde::as_sat::opt",
352 skip_serializing_if = "Option::is_none"
353 )]
354 pub min_fee: Option<Amount>,
355 #[serde(
356 default,
357 rename = "minfeerate",
358 with = "bitcoin::amount::serde::as_sat::opt",
359 skip_serializing_if = "Option::is_none"
360 )]
361 pub min_fee_rate: Option<Amount>,
362 #[serde(default, rename = "mintxsize", skip_serializing_if = "Option::is_none")]
363 pub min_tx_size: Option<u32>,
364 #[serde(default, skip_serializing_if = "Option::is_none")]
365 pub outs: Option<usize>,
366 #[serde(
367 default,
368 with = "bitcoin::amount::serde::as_sat::opt",
369 skip_serializing_if = "Option::is_none"
370 )]
371 pub subsidy: Option<Amount>,
372 #[serde(default, rename = "swtotal_size", skip_serializing_if = "Option::is_none")]
373 pub sw_total_size: Option<usize>,
374 #[serde(default, rename = "swtotal_weight", skip_serializing_if = "Option::is_none")]
375 pub sw_total_weight: Option<usize>,
376 #[serde(default, rename = "swtxs", skip_serializing_if = "Option::is_none")]
377 pub sw_txs: Option<usize>,
378 #[serde(default, skip_serializing_if = "Option::is_none")]
379 pub time: Option<u64>,
380 #[serde(
381 default,
382 with = "bitcoin::amount::serde::as_sat::opt",
383 skip_serializing_if = "Option::is_none"
384 )]
385 pub total_out: Option<Amount>,
386 #[serde(default, skip_serializing_if = "Option::is_none")]
387 pub total_size: Option<usize>,
388 #[serde(default, skip_serializing_if = "Option::is_none")]
389 pub total_weight: Option<usize>,
390 #[serde(
391 default,
392 rename = "totalfee",
393 with = "bitcoin::amount::serde::as_sat::opt",
394 skip_serializing_if = "Option::is_none"
395 )]
396 pub total_fee: Option<Amount>,
397 #[serde(default, skip_serializing_if = "Option::is_none")]
398 pub txs: Option<usize>,
399 #[serde(default, skip_serializing_if = "Option::is_none")]
400 pub utxo_increase: Option<i32>,
401 #[serde(default, skip_serializing_if = "Option::is_none")]
402 pub utxo_size_inc: Option<i32>,
403}
404
405#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
406pub struct FeeRatePercentiles {
407 #[serde(with = "bitcoin::amount::serde::as_sat")]
408 pub fr_10th: Amount,
409 #[serde(with = "bitcoin::amount::serde::as_sat")]
410 pub fr_25th: Amount,
411 #[serde(with = "bitcoin::amount::serde::as_sat")]
412 pub fr_50th: Amount,
413 #[serde(with = "bitcoin::amount::serde::as_sat")]
414 pub fr_75th: Amount,
415 #[serde(with = "bitcoin::amount::serde::as_sat")]
416 pub fr_90th: Amount,
417}
418
419#[derive(Clone)]
420pub enum BlockStatsFields {
421 AverageFee,
422 AverageFeeRate,
423 AverageTxSize,
424 BlockHash,
425 FeeRatePercentiles,
426 Height,
427 Ins,
428 MaxFee,
429 MaxFeeRate,
430 MaxTxSize,
431 MedianFee,
432 MedianTime,
433 MedianTxSize,
434 MinFee,
435 MinFeeRate,
436 MinTxSize,
437 Outs,
438 Subsidy,
439 SegWitTotalSize,
440 SegWitTotalWeight,
441 SegWitTxs,
442 Time,
443 TotalOut,
444 TotalSize,
445 TotalWeight,
446 TotalFee,
447 Txs,
448 UtxoIncrease,
449 UtxoSizeIncrease,
450}
451
452impl BlockStatsFields {
453 fn get_rpc_keyword(&self) -> &str {
454 match *self {
455 BlockStatsFields::AverageFee => "avgfee",
456 BlockStatsFields::AverageFeeRate => "avgfeerate",
457 BlockStatsFields::AverageTxSize => "avgtxsize",
458 BlockStatsFields::BlockHash => "blockhash",
459 BlockStatsFields::FeeRatePercentiles => "feerate_percentiles",
460 BlockStatsFields::Height => "height",
461 BlockStatsFields::Ins => "ins",
462 BlockStatsFields::MaxFee => "maxfee",
463 BlockStatsFields::MaxFeeRate => "maxfeerate",
464 BlockStatsFields::MaxTxSize => "maxtxsize",
465 BlockStatsFields::MedianFee => "medianfee",
466 BlockStatsFields::MedianTime => "mediantime",
467 BlockStatsFields::MedianTxSize => "mediantxsize",
468 BlockStatsFields::MinFee => "minfee",
469 BlockStatsFields::MinFeeRate => "minfeerate",
470 BlockStatsFields::MinTxSize => "minfeerate",
471 BlockStatsFields::Outs => "outs",
472 BlockStatsFields::Subsidy => "subsidy",
473 BlockStatsFields::SegWitTotalSize => "swtotal_size",
474 BlockStatsFields::SegWitTotalWeight => "swtotal_weight",
475 BlockStatsFields::SegWitTxs => "swtxs",
476 BlockStatsFields::Time => "time",
477 BlockStatsFields::TotalOut => "total_out",
478 BlockStatsFields::TotalSize => "total_size",
479 BlockStatsFields::TotalWeight => "total_weight",
480 BlockStatsFields::TotalFee => "totalfee",
481 BlockStatsFields::Txs => "txs",
482 BlockStatsFields::UtxoIncrease => "utxo_increase",
483 BlockStatsFields::UtxoSizeIncrease => "utxo_size_inc",
484 }
485 }
486}
487
488impl fmt::Display for BlockStatsFields {
489 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
490 write!(f, "{}", self.get_rpc_keyword())
491 }
492}
493
494impl From<BlockStatsFields> for serde_json::Value {
495 fn from(bsf: BlockStatsFields) -> Self {
496 Self::from(bsf.to_string())
497 }
498}
499
500#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
501#[serde(rename_all = "camelCase")]
502pub struct GetMiningInfoResult {
503 pub blocks: u32,
504 #[serde(rename = "currentblockweight")]
505 pub current_block_weight: Option<u64>,
506 #[serde(rename = "currentblocktx")]
507 pub current_block_tx: Option<usize>,
508 pub difficulty: f64,
509 #[serde(rename = "networkhashps")]
510 pub network_hash_ps: f64,
511 #[serde(rename = "pooledtx")]
512 pub pooled_tx: usize,
513 pub chain: String,
514 pub warnings: String,
515}
516
517#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
518#[serde(rename_all = "camelCase")]
519pub struct GetRawTransactionResultVinScriptSig {
520 pub asm: String,
521 #[serde(with = "crate::serde_hex")]
522 pub hex: Vec<u8>,
523}
524
525impl GetRawTransactionResultVinScriptSig {
526 pub fn script(&self) -> Result<ScriptBuf, encode::Error> {
527 Ok(ScriptBuf::from(self.hex.clone()))
528 }
529}
530
531#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
532#[serde(rename_all = "camelCase")]
533pub struct GetRawTransactionResultVin {
534 pub sequence: u32,
535 #[serde(default, with = "crate::serde_hex::opt")]
537 pub coinbase: Option<Vec<u8>>,
538 pub txid: Option<bitcoin::Txid>,
540 pub vout: Option<u32>,
542 pub script_sig: Option<GetRawTransactionResultVinScriptSig>,
544 #[serde(default, deserialize_with = "deserialize_hex_array_opt")]
546 pub txinwitness: Option<Vec<Vec<u8>>>,
547}
548
549impl GetRawTransactionResultVin {
550 pub fn is_coinbase(&self) -> bool {
554 self.coinbase.is_some()
555 }
556}
557
558#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
559#[serde(rename_all = "camelCase")]
560pub struct GetRawTransactionResultVoutScriptPubKey {
561 pub asm: String,
562 #[serde(with = "crate::serde_hex")]
563 pub hex: Vec<u8>,
564 pub req_sigs: Option<usize>,
565 #[serde(rename = "type")]
566 pub type_: Option<ScriptPubkeyType>,
567 #[serde(default)]
569 pub addresses: Vec<Address<NetworkUnchecked>>,
570 #[serde(default)]
572 pub address: Option<Address<NetworkUnchecked>>,
573}
574
575impl GetRawTransactionResultVoutScriptPubKey {
576 pub fn script(&self) -> Result<ScriptBuf, encode::Error> {
577 Ok(ScriptBuf::from(self.hex.clone()))
578 }
579}
580
581#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
582#[serde(rename_all = "camelCase")]
583pub struct GetRawTransactionResultVout {
584 #[serde(with = "bitcoin::amount::serde::as_btc")]
585 pub value: Amount,
586 pub n: u32,
587 pub script_pub_key: GetRawTransactionResultVoutScriptPubKey,
588}
589
590#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
591#[serde(rename_all = "camelCase")]
592pub struct GetRawTransactionResult {
593 #[serde(rename = "in_active_chain")]
594 pub in_active_chain: Option<bool>,
595 #[serde(with = "crate::serde_hex")]
596 pub hex: Vec<u8>,
597 pub txid: bitcoin::Txid,
598 pub hash: bitcoin::Wtxid,
599 pub size: usize,
600 pub vsize: usize,
601 pub version: u32,
602 pub locktime: u32,
603 pub vin: Vec<GetRawTransactionResultVin>,
604 pub vout: Vec<GetRawTransactionResultVout>,
605 pub blockhash: Option<bitcoin::BlockHash>,
606 pub confirmations: Option<u32>,
607 pub time: Option<usize>,
608 pub blocktime: Option<usize>,
609}
610
611#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
612pub struct GetBlockFilterResult {
613 pub header: bitcoin::hash_types::FilterHash,
614 #[serde(with = "crate::serde_hex")]
615 pub filter: Vec<u8>,
616}
617
618impl GetBlockFilterResult {
619 pub fn to_filter(&self) -> bip158::BlockFilter {
623 bip158::BlockFilter::new(&self.filter)
624 }
625
626 pub fn into_filter(self) -> bip158::BlockFilter {
628 bip158::BlockFilter {
629 content: self.filter,
630 }
631 }
632}
633
634impl GetRawTransactionResult {
635 pub fn is_coinbase(&self) -> bool {
637 self.vin.len() == 1 && self.vin[0].is_coinbase()
638 }
639
640 pub fn transaction(&self) -> Result<Transaction, encode::Error> {
641 Ok(encode::deserialize(&self.hex)?)
642 }
643}
644
645#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
647#[serde(rename_all = "lowercase")]
648pub enum Bip125Replaceable {
649 Yes,
650 No,
651 Unknown,
652}
653
654#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
656#[serde(rename_all = "lowercase")]
657pub enum GetTransactionResultDetailCategory {
658 Send,
659 Receive,
660 Generate,
661 Immature,
662 Orphan,
663}
664
665#[derive(Clone, PartialEq, Eq, Debug, Deserialize)]
666pub struct GetTransactionResultDetail {
667 pub address: Option<Address<NetworkUnchecked>>,
668 pub category: GetTransactionResultDetailCategory,
669 #[serde(with = "bitcoin::amount::serde::as_btc")]
670 pub amount: SignedAmount,
671 pub label: Option<String>,
672 pub vout: u32,
673 #[serde(default, with = "bitcoin::amount::serde::as_btc::opt")]
674 pub fee: Option<SignedAmount>,
675 pub abandoned: Option<bool>,
676}
677
678#[derive(Clone, PartialEq, Eq, Debug, Deserialize)]
679pub struct WalletTxInfo {
680 pub confirmations: i32,
681 pub blockhash: Option<bitcoin::BlockHash>,
682 pub blockindex: Option<usize>,
683 pub blocktime: Option<u64>,
684 pub blockheight: Option<u32>,
685 pub txid: bitcoin::Txid,
686 pub time: u64,
687 pub timereceived: u64,
688 #[serde(rename = "bip125-replaceable")]
689 pub bip125_replaceable: Bip125Replaceable,
690 #[serde(rename = "walletconflicts")]
692 pub wallet_conflicts: Vec<bitcoin::Txid>,
693}
694
695#[derive(Clone, PartialEq, Eq, Debug, Deserialize)]
696pub struct GetTransactionResult {
697 #[serde(flatten)]
698 pub info: WalletTxInfo,
699 #[serde(with = "bitcoin::amount::serde::as_btc")]
700 pub amount: SignedAmount,
701 #[serde(default, with = "bitcoin::amount::serde::as_btc::opt")]
702 pub fee: Option<SignedAmount>,
703 pub details: Vec<GetTransactionResultDetail>,
704 #[serde(with = "crate::serde_hex")]
705 pub hex: Vec<u8>,
706}
707
708impl GetTransactionResult {
709 pub fn transaction(&self) -> Result<Transaction, encode::Error> {
710 Ok(encode::deserialize(&self.hex)?)
711 }
712}
713
714#[derive(Clone, PartialEq, Eq, Debug, Deserialize)]
715pub struct ListTransactionResult {
716 #[serde(flatten)]
717 pub info: WalletTxInfo,
718 #[serde(flatten)]
719 pub detail: GetTransactionResultDetail,
720
721 pub trusted: Option<bool>,
722 pub comment: Option<String>,
723}
724
725#[derive(Clone, PartialEq, Eq, Debug, Deserialize)]
726pub struct ListSinceBlockResult {
727 pub transactions: Vec<ListTransactionResult>,
728 #[serde(default)]
729 pub removed: Vec<ListTransactionResult>,
730 pub lastblock: bitcoin::BlockHash,
731}
732
733#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
734#[serde(rename_all = "camelCase")]
735pub struct GetTxOutResult {
736 pub bestblock: bitcoin::BlockHash,
737 pub confirmations: u32,
738 #[serde(with = "bitcoin::amount::serde::as_btc")]
739 pub value: Amount,
740 pub script_pub_key: GetRawTransactionResultVoutScriptPubKey,
741 pub coinbase: bool,
742}
743
744#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize, Default)]
745#[serde(rename_all = "camelCase")]
746pub struct ListUnspentQueryOptions {
747 #[serde(
748 rename = "minimumAmount",
749 with = "bitcoin::amount::serde::as_btc::opt",
750 skip_serializing_if = "Option::is_none"
751 )]
752 pub minimum_amount: Option<Amount>,
753 #[serde(
754 rename = "maximumAmount",
755 with = "bitcoin::amount::serde::as_btc::opt",
756 skip_serializing_if = "Option::is_none"
757 )]
758 pub maximum_amount: Option<Amount>,
759 #[serde(rename = "maximumCount", skip_serializing_if = "Option::is_none")]
760 pub maximum_count: Option<usize>,
761 #[serde(
762 rename = "minimumSumAmount",
763 with = "bitcoin::amount::serde::as_btc::opt",
764 skip_serializing_if = "Option::is_none"
765 )]
766 pub minimum_sum_amount: Option<Amount>,
767}
768
769#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
770#[serde(rename_all = "camelCase")]
771pub struct ListUnspentResultEntry {
772 pub txid: bitcoin::Txid,
773 pub vout: u32,
774 pub address: Option<Address<NetworkUnchecked>>,
775 pub label: Option<String>,
776 pub redeem_script: Option<ScriptBuf>,
777 pub witness_script: Option<ScriptBuf>,
778 pub script_pub_key: ScriptBuf,
779 #[serde(with = "bitcoin::amount::serde::as_btc")]
780 pub amount: Amount,
781 pub confirmations: u32,
782 pub spendable: bool,
783 pub solvable: bool,
784 #[serde(rename = "desc")]
785 pub descriptor: Option<String>,
786 pub safe: bool,
787}
788
789#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
790#[serde(rename_all = "camelCase")]
791pub struct ListReceivedByAddressResult {
792 #[serde(default, rename = "involvesWatchonly")]
793 pub involved_watch_only: bool,
794 pub address: Address<NetworkUnchecked>,
795 #[serde(with = "bitcoin::amount::serde::as_btc")]
796 pub amount: Amount,
797 pub confirmations: u32,
798 pub label: String,
799 pub txids: Vec<bitcoin::Txid>,
800}
801
802#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
803#[serde(rename_all = "camelCase")]
804pub struct SignRawTransactionResultError {
805 pub txid: bitcoin::Txid,
806 pub vout: u32,
807 pub script_sig: ScriptBuf,
808 pub sequence: u32,
809 pub error: String,
810}
811
812#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
813#[serde(rename_all = "camelCase")]
814pub struct SignRawTransactionResult {
815 #[serde(with = "crate::serde_hex")]
816 pub hex: Vec<u8>,
817 pub complete: bool,
818 pub errors: Option<Vec<SignRawTransactionResultError>>,
819}
820
821impl SignRawTransactionResult {
822 pub fn transaction(&self) -> Result<Transaction, encode::Error> {
823 Ok(encode::deserialize(&self.hex)?)
824 }
825}
826
827#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
828pub struct TestMempoolAcceptResult {
829 pub txid: bitcoin::Txid,
830 pub allowed: bool,
831 #[serde(rename = "reject-reason")]
832 pub reject_reason: Option<String>,
833 pub vsize: Option<u64>,
836 pub fees: Option<TestMempoolAcceptResultFees>,
839}
840
841#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
842pub struct TestMempoolAcceptResultFees {
843 #[serde(with = "bitcoin::amount::serde::as_btc")]
845 pub base: Amount,
846 }
848
849#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
850#[serde(rename_all = "snake_case")]
851pub enum Bip9SoftforkStatus {
852 Defined,
853 Started,
854 LockedIn,
855 Active,
856 Failed,
857}
858
859#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
860pub struct Bip9SoftforkStatistics {
861 pub period: u32,
862 pub threshold: Option<u32>,
863 pub elapsed: u32,
864 pub count: u32,
865 pub possible: Option<bool>,
866}
867
868#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
869pub struct Bip9SoftforkInfo {
870 pub status: Bip9SoftforkStatus,
871 pub bit: Option<u8>,
872 pub start_time: i64,
874 pub timeout: u64,
875 pub since: u32,
876 pub statistics: Option<Bip9SoftforkStatistics>,
877}
878
879#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
880#[serde(rename_all = "lowercase")]
881pub enum SoftforkType {
882 Buried,
883 Bip9,
884 #[serde(other)]
885 Other,
886}
887
888#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
890pub struct Softfork {
891 #[serde(rename = "type")]
892 pub type_: SoftforkType,
893 pub bip9: Option<Bip9SoftforkInfo>,
894 pub height: Option<u32>,
895 pub active: bool,
896}
897
898#[allow(non_camel_case_types)]
899#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
900#[serde(rename_all = "lowercase")]
901pub enum ScriptPubkeyType {
902 Nonstandard,
903 Pubkey,
904 PubkeyHash,
905 ScriptHash,
906 MultiSig,
907 NullData,
908 Witness_v0_KeyHash,
909 Witness_v0_ScriptHash,
910 Witness_v1_Taproot,
911 Witness_Unknown,
912}
913
914#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
915pub struct GetAddressInfoResultEmbedded {
916 pub address: Address<NetworkUnchecked>,
917 #[serde(rename = "scriptPubKey")]
918 pub script_pub_key: ScriptBuf,
919 #[serde(rename = "is_script")]
920 pub is_script: Option<bool>,
921 #[serde(rename = "is_witness")]
922 pub is_witness: Option<bool>,
923 pub witness_version: Option<u32>,
924 #[serde(with = "crate::serde_hex")]
925 pub witness_program: Vec<u8>,
926 pub script: Option<ScriptPubkeyType>,
927 #[serde(default, with = "crate::serde_hex::opt")]
929 pub hex: Option<Vec<u8>>,
930 pub pubkeys: Option<Vec<PublicKey>>,
931 #[serde(rename = "sigsrequired")]
932 pub n_signatures_required: Option<usize>,
933 pub pubkey: Option<PublicKey>,
934 #[serde(rename = "is_compressed")]
935 pub is_compressed: Option<bool>,
936 pub label: Option<String>,
937 #[serde(rename = "hdkeypath")]
938 pub hd_key_path: Option<bip32::DerivationPath>,
939 #[serde(rename = "hdseedid")]
940 pub hd_seed_id: Option<bitcoin::hash_types::XpubIdentifier>,
941 #[serde(default)]
942 pub labels: Vec<GetAddressInfoResultLabel>,
943}
944
945#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
946#[serde(rename_all = "lowercase")]
947pub enum GetAddressInfoResultLabelPurpose {
948 Send,
949 Receive,
950}
951
952#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
953#[serde(untagged)]
954pub enum GetAddressInfoResultLabel {
955 Simple(String),
956 WithPurpose {
957 name: String,
958 purpose: GetAddressInfoResultLabelPurpose,
959 },
960}
961
962#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
963pub struct GetAddressInfoResult {
964 pub address: Address<NetworkUnchecked>,
965 #[serde(rename = "scriptPubKey")]
966 pub script_pub_key: ScriptBuf,
967 #[serde(rename = "ismine")]
968 pub is_mine: Option<bool>,
969 #[serde(rename = "iswatchonly")]
970 pub is_watchonly: Option<bool>,
971 #[serde(rename = "isscript")]
972 pub is_script: Option<bool>,
973 #[serde(rename = "iswitness")]
974 pub is_witness: Option<bool>,
975 pub witness_version: Option<u32>,
976 #[serde(default, with = "crate::serde_hex::opt")]
977 pub witness_program: Option<Vec<u8>>,
978 pub script: Option<ScriptPubkeyType>,
979 #[serde(default, with = "crate::serde_hex::opt")]
981 pub hex: Option<Vec<u8>>,
982 pub pubkeys: Option<Vec<PublicKey>>,
983 #[serde(rename = "sigsrequired")]
984 pub n_signatures_required: Option<usize>,
985 pub pubkey: Option<PublicKey>,
986 pub embedded: Option<GetAddressInfoResultEmbedded>,
988 #[serde(rename = "is_compressed")]
989 pub is_compressed: Option<bool>,
990 pub timestamp: Option<u64>,
991 #[serde(rename = "hdkeypath")]
992 pub hd_key_path: Option<bip32::DerivationPath>,
993 #[serde(rename = "hdseedid")]
994 pub hd_seed_id: Option<bitcoin::hash_types::XpubIdentifier>,
995 pub labels: Vec<GetAddressInfoResultLabel>,
996 #[deprecated(note = "since Core v0.20.0")]
998 pub label: Option<String>,
999}
1000
1001#[derive(Clone, Debug, Deserialize, Serialize)]
1003pub struct GetBlockchainInfoResult {
1004 pub chain: String,
1006 pub blocks: u64,
1008 pub headers: u64,
1010 #[serde(rename = "bestblockhash")]
1012 pub best_block_hash: bitcoin::BlockHash,
1013 pub difficulty: f64,
1015 #[serde(rename = "mediantime")]
1017 pub median_time: u64,
1018 #[serde(rename = "verificationprogress")]
1020 pub verification_progress: f64,
1021 #[serde(rename = "initialblockdownload")]
1023 pub initial_block_download: bool,
1024 #[serde(rename = "chainwork", with = "crate::serde_hex")]
1026 pub chain_work: Vec<u8>,
1027 pub size_on_disk: u64,
1029 pub pruned: bool,
1031 #[serde(rename = "pruneheight")]
1033 pub prune_height: Option<u64>,
1034 pub automatic_pruning: Option<bool>,
1036 pub prune_target_size: Option<u64>,
1038 #[serde(default)]
1040 pub softforks: HashMap<String, Softfork>,
1041 pub warnings: String,
1043}
1044
1045#[derive(Clone, PartialEq, Eq, Debug)]
1046pub enum ImportMultiRequestScriptPubkey<'a> {
1047 Address(&'a Address),
1048 Script(&'a Script),
1049}
1050
1051#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1052pub struct GetMempoolInfoResult {
1053 pub loaded: bool,
1055 pub size: usize,
1057 pub bytes: usize,
1059 pub usage: usize,
1061 #[serde(with = "bitcoin::amount::serde::as_btc")]
1063 pub total_fee: Amount,
1064 #[serde(rename = "maxmempool")]
1066 pub max_mempool: usize,
1067 #[serde(rename = "mempoolminfee", with = "bitcoin::amount::serde::as_btc")]
1069 pub mempool_min_fee: Amount,
1070 #[serde(rename = "minrelaytxfee", with = "bitcoin::amount::serde::as_btc")]
1072 pub min_relay_tx_fee: Amount,
1073 #[serde(rename = "incrementalrelayfee", with = "bitcoin::amount::serde::as_btc")]
1075 pub incremental_relay_fee: Amount,
1076 #[serde(rename = "unbroadcastcount")]
1078 pub unbroadcast_count: usize,
1079 #[serde(rename = "fullrbf")]
1081 pub full_rbf: bool,
1082}
1083
1084#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1085pub struct GetMempoolEntryResult {
1086 #[serde(alias = "size")]
1089 pub vsize: u64,
1090 pub weight: Option<u64>,
1092 pub time: u64,
1094 pub height: u64,
1096 #[serde(rename = "descendantcount")]
1098 pub descendant_count: u64,
1099 #[serde(rename = "descendantsize")]
1101 pub descendant_size: u64,
1102 #[serde(rename = "ancestorcount")]
1104 pub ancestor_count: u64,
1105 #[serde(rename = "ancestorsize")]
1107 pub ancestor_size: u64,
1108 pub wtxid: bitcoin::Txid,
1110 pub fees: GetMempoolEntryResultFees,
1112 pub depends: Vec<bitcoin::Txid>,
1114 #[serde(rename = "spentby")]
1116 pub spent_by: Vec<bitcoin::Txid>,
1117 #[serde(rename = "bip125-replaceable")]
1119 pub bip125_replaceable: bool,
1120 pub unbroadcast: Option<bool>,
1123}
1124
1125#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1126pub struct GetMempoolEntryResultFees {
1127 #[serde(with = "bitcoin::amount::serde::as_btc")]
1129 pub base: Amount,
1130 #[serde(with = "bitcoin::amount::serde::as_btc")]
1132 pub modified: Amount,
1133 #[serde(with = "bitcoin::amount::serde::as_btc")]
1135 pub ancestor: Amount,
1136 #[serde(with = "bitcoin::amount::serde::as_btc")]
1138 pub descendant: Amount,
1139}
1140
1141impl<'a> serde::Serialize for ImportMultiRequestScriptPubkey<'a> {
1142 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1143 where
1144 S: serde::Serializer,
1145 {
1146 match *self {
1147 ImportMultiRequestScriptPubkey::Address(ref addr) => {
1148 #[derive(Serialize)]
1149 struct Tmp<'a> {
1150 pub address: &'a Address,
1151 }
1152 serde::Serialize::serialize(
1153 &Tmp {
1154 address: addr,
1155 },
1156 serializer,
1157 )
1158 }
1159 ImportMultiRequestScriptPubkey::Script(script) => {
1160 serializer.serialize_str(&script.to_hex_string())
1161 }
1162 }
1163 }
1164}
1165
1166#[derive(Clone, PartialEq, Eq, Debug, Default, Serialize)]
1170pub struct ImportMultiRequest<'a> {
1171 pub timestamp: Timestamp,
1172 #[serde(rename = "desc", skip_serializing_if = "Option::is_none")]
1174 pub descriptor: Option<&'a str>,
1175 #[serde(rename = "scriptPubKey", skip_serializing_if = "Option::is_none")]
1176 pub script_pubkey: Option<ImportMultiRequestScriptPubkey<'a>>,
1177 #[serde(rename = "redeemscript", skip_serializing_if = "Option::is_none")]
1178 pub redeem_script: Option<&'a Script>,
1179 #[serde(rename = "witnessscript", skip_serializing_if = "Option::is_none")]
1180 pub witness_script: Option<&'a Script>,
1181 #[serde(skip_serializing_if = "<[_]>::is_empty")]
1182 pub pubkeys: &'a [PublicKey],
1183 #[serde(skip_serializing_if = "<[_]>::is_empty")]
1184 pub keys: &'a [PrivateKey],
1185 #[serde(skip_serializing_if = "Option::is_none")]
1186 pub range: Option<(usize, usize)>,
1187 #[serde(skip_serializing_if = "Option::is_none")]
1188 pub internal: Option<bool>,
1189 #[serde(skip_serializing_if = "Option::is_none")]
1190 pub watchonly: Option<bool>,
1191 #[serde(skip_serializing_if = "Option::is_none")]
1192 pub label: Option<&'a str>,
1193 #[serde(skip_serializing_if = "Option::is_none")]
1194 pub keypool: Option<bool>,
1195}
1196
1197#[derive(Clone, PartialEq, Eq, Debug, Default, Deserialize, Serialize)]
1198pub struct ImportMultiOptions {
1199 #[serde(skip_serializing_if = "Option::is_none")]
1200 pub rescan: Option<bool>,
1201}
1202
1203#[derive(Clone, PartialEq, Eq, Copy, Debug)]
1204pub enum Timestamp {
1205 Now,
1206 Time(u64),
1207}
1208
1209impl serde::Serialize for Timestamp {
1210 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1211 where
1212 S: serde::Serializer,
1213 {
1214 match *self {
1215 Timestamp::Now => serializer.serialize_str("now"),
1216 Timestamp::Time(timestamp) => serializer.serialize_u64(timestamp),
1217 }
1218 }
1219}
1220
1221impl<'de> serde::Deserialize<'de> for Timestamp {
1222 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1223 where
1224 D: serde::Deserializer<'de>,
1225 {
1226 use serde::de;
1227 struct Visitor;
1228 impl<'de> de::Visitor<'de> for Visitor {
1229 type Value = Timestamp;
1230
1231 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
1232 write!(formatter, "unix timestamp or 'now'")
1233 }
1234
1235 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
1236 where
1237 E: de::Error,
1238 {
1239 Ok(Timestamp::Time(value))
1240 }
1241
1242 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
1243 where
1244 E: de::Error,
1245 {
1246 if value == "now" {
1247 Ok(Timestamp::Now)
1248 } else {
1249 Err(de::Error::custom(format!(
1250 "invalid str '{}', expecting 'now' or unix timestamp",
1251 value
1252 )))
1253 }
1254 }
1255 }
1256 deserializer.deserialize_any(Visitor)
1257 }
1258}
1259
1260impl Default for Timestamp {
1261 fn default() -> Self {
1262 Timestamp::Time(0)
1263 }
1264}
1265
1266impl From<u64> for Timestamp {
1267 fn from(t: u64) -> Self {
1268 Timestamp::Time(t)
1269 }
1270}
1271
1272impl From<Option<u64>> for Timestamp {
1273 fn from(timestamp: Option<u64>) -> Self {
1274 timestamp.map_or(Timestamp::Now, Timestamp::Time)
1275 }
1276}
1277
1278#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1279pub struct ImportMultiResultError {
1280 pub code: i64,
1281 pub message: String,
1282}
1283
1284#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1285pub struct ImportMultiResult {
1286 pub success: bool,
1287 #[serde(default)]
1288 pub warnings: Vec<String>,
1289 pub error: Option<ImportMultiResultError>,
1290}
1291
1292#[derive(Clone, PartialEq, Eq, Debug, Default, Deserialize, Serialize)]
1294pub struct ImportDescriptors {
1295 #[serde(rename = "desc")]
1296 pub descriptor: String,
1297 pub timestamp: Timestamp,
1298 #[serde(skip_serializing_if = "Option::is_none")]
1299 pub active: Option<bool>,
1300 #[serde(skip_serializing_if = "Option::is_none")]
1301 pub range: Option<(usize, usize)>,
1302 #[serde(skip_serializing_if = "Option::is_none")]
1303 pub next_index: Option<usize>,
1304 #[serde(skip_serializing_if = "Option::is_none")]
1305 pub internal: Option<bool>,
1306 #[serde(skip_serializing_if = "Option::is_none")]
1307 pub label: Option<String>,
1308}
1309
1310#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1312pub struct RejectStatus {
1313 pub status: bool,
1315}
1316
1317#[derive(Clone, Debug, Deserialize, Serialize)]
1319pub struct GetPeerInfoResult {
1320 pub id: u64,
1322 pub addr: String,
1325 pub addrbind: String,
1328 pub addrlocal: Option<String>,
1331 pub network: Option<GetPeerInfoResultNetwork>,
1334 pub services: String,
1337 pub relaytxes: bool,
1339 pub lastsend: u64,
1341 pub lastrecv: u64,
1343 pub last_transaction: Option<u64>,
1346 pub last_block: Option<u64>,
1349 pub bytessent: u64,
1351 pub bytesrecv: u64,
1353 pub conntime: u64,
1355 pub timeoffset: i64,
1357 pub pingtime: Option<f64>,
1359 pub minping: Option<f64>,
1361 pub pingwait: Option<f64>,
1363 pub version: u64,
1365 pub subver: String,
1367 pub inbound: bool,
1369 pub addnode: Option<bool>,
1373 pub startingheight: i64,
1375 pub banscore: Option<i64>,
1378 pub synced_headers: i64,
1380 pub synced_blocks: i64,
1382 pub inflight: Vec<u64>,
1384 pub whitelisted: Option<bool>,
1387 #[serde(rename = "minfeefilter", default, with = "bitcoin::amount::serde::as_btc::opt")]
1388 pub min_fee_filter: Option<Amount>,
1389 pub bytessent_per_msg: HashMap<String, u64>,
1391 pub bytesrecv_per_msg: HashMap<String, u64>,
1393 pub connection_type: Option<GetPeerInfoResultConnectionType>,
1396}
1397
1398#[derive(Copy, Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
1399#[serde(rename_all = "snake_case")]
1400pub enum GetPeerInfoResultNetwork {
1401 Ipv4,
1402 Ipv6,
1403 Onion,
1404 #[deprecated]
1405 Unroutable,
1406 NotPubliclyRoutable,
1407 I2p,
1408 Cjdns,
1409 Internal,
1410}
1411
1412#[derive(Copy, Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
1413#[serde(rename_all = "kebab-case")]
1414pub enum GetPeerInfoResultConnectionType {
1415 OutboundFullRelay,
1416 BlockRelayOnly,
1417 Inbound,
1418 Manual,
1419 AddrFetch,
1420 Feeler,
1421}
1422
1423#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1424pub struct GetAddedNodeInfoResult {
1425 #[serde(rename = "addednode")]
1427 pub added_node: String,
1428 pub connected: bool,
1430 pub addresses: Vec<GetAddedNodeInfoResultAddress>,
1432}
1433
1434#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1435pub struct GetAddedNodeInfoResultAddress {
1436 pub address: String,
1438 pub connected: GetAddedNodeInfoResultAddressType,
1440}
1441
1442#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1443#[serde(rename_all = "lowercase")]
1444pub enum GetAddedNodeInfoResultAddressType {
1445 Inbound,
1446 Outbound,
1447}
1448
1449#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1450pub struct GetNodeAddressesResult {
1451 pub time: u64,
1453 pub services: usize,
1455 pub address: String,
1457 pub port: u16,
1459}
1460
1461#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1462pub struct ListBannedResult {
1463 pub address: String,
1464 pub banned_until: u64,
1465 pub ban_created: u64,
1466}
1467
1468#[derive(Clone, Debug, Deserialize, Serialize)]
1470pub struct EstimateSmartFeeResult {
1471 #[serde(
1473 default,
1474 rename = "feerate",
1475 skip_serializing_if = "Option::is_none",
1476 with = "bitcoin::amount::serde::as_btc::opt"
1477 )]
1478 pub fee_rate: Option<Amount>,
1479 pub errors: Option<Vec<String>>,
1481 pub blocks: i64,
1483}
1484
1485#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1487pub struct BlockRef {
1488 pub hash: bitcoin::BlockHash,
1489 pub height: u64,
1490}
1491
1492#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1494pub struct GetDescriptorInfoResult {
1495 pub descriptor: String,
1496 pub checksum: String,
1497 #[serde(rename = "isrange")]
1498 pub is_range: bool,
1499 #[serde(rename = "issolvable")]
1500 pub is_solvable: bool,
1501 #[serde(rename = "hasprivatekeys")]
1502 pub has_private_keys: bool,
1503}
1504
1505#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1507pub struct GetBlockTemplateOptions {
1508 pub mode: GetBlockTemplateModes,
1509 pub rules: Vec<GetBlockTemplateRules>,
1511 pub capabilities: Vec<GetBlockTemplateCapabilities>,
1513}
1514
1515#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1517#[serde(rename_all = "lowercase")]
1518pub enum GetBlockTemplateCapabilities {
1519 }
1521
1522#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1525#[serde(rename_all = "lowercase")]
1526pub enum GetBlockTemplateRules {
1527 SegWit,
1528 Signet,
1529 Csv,
1530 Taproot,
1531}
1532
1533#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1535#[serde(rename_all = "lowercase")]
1536pub enum GetBlockTemplateModes {
1537 Template,
1540 }
1543
1544#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1546pub struct GetBlockTemplateResult {
1547 #[serde(with = "crate::serde_hex")]
1549 pub bits: Vec<u8>,
1550 #[serde(rename = "previousblockhash")]
1552 pub previous_block_hash: bitcoin::BlockHash,
1553 #[serde(rename = "curtime")]
1557 pub current_time: u64,
1558 pub height: u64,
1560 #[serde(rename = "sigoplimit")]
1562 pub sigop_limit: u32,
1563 #[serde(rename = "sizelimit")]
1565 pub size_limit: u32,
1566 #[serde(rename = "weightlimit")]
1568 pub weight_limit: u32,
1569 pub version: u32,
1571 pub rules: Vec<GetBlockTemplateResultRules>,
1573 pub capabilities: Vec<GetBlockTemplateResultCapabilities>,
1575 #[serde(rename = "vbavailable")]
1577 pub version_bits_available: HashMap<String, u32>,
1578 #[serde(rename = "vbrequired")]
1580 pub version_bits_required: u32,
1581 pub longpollid: String,
1583 pub transactions: Vec<GetBlockTemplateResultTransaction>,
1585 #[serde(default, with = "bitcoin::script::ScriptBuf")]
1587 pub signet_challenge: bitcoin::script::ScriptBuf,
1588 #[serde(with = "bitcoin::script::ScriptBuf", default)]
1592 pub default_witness_commitment: bitcoin::script::ScriptBuf,
1593 pub coinbaseaux: HashMap<String, String>,
1600 #[serde(rename = "coinbasevalue", with = "bitcoin::amount::serde::as_sat", default)]
1602 pub coinbase_value: Amount,
1603 #[serde(with = "crate::serde_hex")]
1605 pub target: Vec<u8>,
1606 #[serde(rename = "mintime")]
1609 pub min_time: u64,
1610 pub mutable: Vec<GetBlockTemplateResulMutations>,
1613 #[serde(with = "crate::serde_hex", rename = "noncerange")]
1615 pub nonce_range: Vec<u8>,
1616}
1617
1618#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1620pub struct GetBlockTemplateResultTransaction {
1621 pub txid: bitcoin::Txid,
1623 #[serde(rename = "hash")]
1625 pub wtxid: bitcoin::Wtxid,
1626 #[serde(with = "crate::serde_hex", rename = "data")]
1628 pub raw_tx: Vec<u8>,
1629 #[serde(with = "bitcoin::amount::serde::as_sat")]
1631 pub fee: Amount,
1632 pub sigops: u32,
1634 pub weight: usize,
1636 pub depends: Vec<u32>,
1640}
1641
1642impl GetBlockTemplateResultTransaction {
1643 pub fn transaction(&self) -> Result<Transaction, encode::Error> {
1644 encode::deserialize(&self.raw_tx)
1645 }
1646}
1647
1648#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1650#[serde(rename_all = "lowercase")]
1651pub enum GetBlockTemplateResultCapabilities {
1652 Proposal,
1653}
1654
1655#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1658#[serde(rename_all = "lowercase")]
1659pub enum GetBlockTemplateResultRules {
1660 #[serde(alias = "!segwit")]
1663 SegWit,
1664 #[serde(alias = "!signet")]
1667 Signet,
1668 Csv,
1671 Taproot,
1674 Testdummy,
1677}
1678
1679#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1684#[serde(rename_all = "lowercase")]
1685pub enum GetBlockTemplateResulMutations {
1686 Time,
1688 Transactions,
1690 #[serde(rename = "prevblock")]
1694 PreviousBlock,
1695}
1696
1697#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1699pub struct WalletCreateFundedPsbtResult {
1700 pub psbt: String,
1701 #[serde(with = "bitcoin::amount::serde::as_btc")]
1702 pub fee: Amount,
1703 #[serde(rename = "changepos")]
1704 pub change_position: i32,
1705}
1706
1707#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1709pub struct WalletProcessPsbtResult {
1710 pub psbt: String,
1711 pub complete: bool,
1712}
1713
1714#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize, Default)]
1716pub struct WalletCreateFundedPsbtOptions {
1717 #[serde(skip_serializing_if = "Option::is_none")]
1720 pub add_inputs: Option<bool>,
1721 #[serde(rename = "changeAddress", skip_serializing_if = "Option::is_none")]
1722 pub change_address: Option<Address<NetworkUnchecked>>,
1723 #[serde(rename = "changePosition", skip_serializing_if = "Option::is_none")]
1724 pub change_position: Option<u16>,
1725 #[serde(skip_serializing_if = "Option::is_none")]
1726 pub change_type: Option<AddressType>,
1727 #[serde(rename = "includeWatching", skip_serializing_if = "Option::is_none")]
1728 pub include_watching: Option<bool>,
1729 #[serde(rename = "lockUnspents", skip_serializing_if = "Option::is_none")]
1730 pub lock_unspent: Option<bool>,
1731 #[serde(
1732 rename = "feeRate",
1733 skip_serializing_if = "Option::is_none",
1734 with = "bitcoin::amount::serde::as_btc::opt"
1735 )]
1736 pub fee_rate: Option<Amount>,
1737 #[serde(rename = "subtractFeeFromOutputs", skip_serializing_if = "Vec::is_empty")]
1738 pub subtract_fee_from_outputs: Vec<u16>,
1739 #[serde(skip_serializing_if = "Option::is_none")]
1740 pub replaceable: Option<bool>,
1741 #[serde(skip_serializing_if = "Option::is_none")]
1742 pub conf_target: Option<u16>,
1743 #[serde(skip_serializing_if = "Option::is_none")]
1744 pub estimate_mode: Option<EstimateMode>,
1745}
1746
1747#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1749pub struct FinalizePsbtResult {
1750 pub psbt: Option<String>,
1751 #[serde(default, with = "crate::serde_hex::opt")]
1752 pub hex: Option<Vec<u8>>,
1753 pub complete: bool,
1754}
1755
1756#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1758pub struct DecodeRawTransactionResult {
1759 pub txid: bitcoin::Txid,
1760 pub hash: bitcoin::Wtxid,
1761 pub size: u32,
1762 pub vsize: u32,
1763 pub weight: u32,
1764 pub version: u32,
1765 pub locktime: u32,
1766 pub vin: Vec<GetRawTransactionResultVin>,
1767 pub vout: Vec<GetRawTransactionResultVout>,
1768}
1769
1770pub type GetChainTipsResult = Vec<GetChainTipsResultTip>;
1772
1773#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1775pub struct GetChainTipsResultTip {
1776 pub height: u64,
1778 pub hash: bitcoin::BlockHash,
1780 #[serde(rename = "branchlen")]
1782 pub branch_length: usize,
1783 pub status: GetChainTipsResultStatus,
1785}
1786
1787#[derive(Copy, Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
1788#[serde(rename_all = "lowercase")]
1789pub enum GetChainTipsResultStatus {
1790 Invalid,
1792 #[serde(rename = "headers-only")]
1794 HeadersOnly,
1795 #[serde(rename = "valid-headers")]
1797 ValidHeaders,
1798 #[serde(rename = "valid-fork")]
1800 ValidFork,
1801 Active,
1803}
1804
1805impl FinalizePsbtResult {
1806 pub fn transaction(&self) -> Option<Result<Transaction, encode::Error>> {
1807 self.hex.as_ref().map(|h| encode::deserialize(h))
1808 }
1809}
1810
1811#[derive(Serialize, Deserialize, Debug, Clone, Copy, Eq, PartialEq, Hash)]
1814#[serde(rename_all = "UPPERCASE")]
1815pub enum EstimateMode {
1816 Unset,
1817 Economical,
1818 Conservative,
1819}
1820
1821pub struct SigHashType(bitcoin::sighash::EcdsaSighashType);
1824
1825impl From<bitcoin::sighash::EcdsaSighashType> for SigHashType {
1826 fn from(sht: bitcoin::sighash::EcdsaSighashType) -> SigHashType {
1827 SigHashType(sht)
1828 }
1829}
1830
1831impl serde::Serialize for SigHashType {
1832 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1833 where
1834 S: serde::Serializer,
1835 {
1836 serializer.serialize_str(match self.0 {
1837 bitcoin::sighash::EcdsaSighashType::All => "ALL",
1838 bitcoin::sighash::EcdsaSighashType::None => "NONE",
1839 bitcoin::sighash::EcdsaSighashType::Single => "SINGLE",
1840 bitcoin::sighash::EcdsaSighashType::AllPlusAnyoneCanPay => "ALL|ANYONECANPAY",
1841 bitcoin::sighash::EcdsaSighashType::NonePlusAnyoneCanPay => "NONE|ANYONECANPAY",
1842 bitcoin::sighash::EcdsaSighashType::SinglePlusAnyoneCanPay => "SINGLE|ANYONECANPAY",
1843 })
1844 }
1845}
1846
1847#[derive(Serialize, Clone, PartialEq, Eq, Debug)]
1849#[serde(rename_all = "camelCase")]
1850pub struct CreateRawTransactionInput {
1851 pub txid: bitcoin::Txid,
1852 pub vout: u32,
1853 #[serde(skip_serializing_if = "Option::is_none")]
1854 pub sequence: Option<u32>,
1855}
1856
1857#[derive(Serialize, Clone, PartialEq, Eq, Debug, Default)]
1858#[serde(rename_all = "camelCase")]
1859pub struct FundRawTransactionOptions {
1860 #[serde(rename = "add_inputs", skip_serializing_if = "Option::is_none")]
1863 pub add_inputs: Option<bool>,
1864 #[serde(skip_serializing_if = "Option::is_none")]
1865 pub change_address: Option<Address>,
1866 #[serde(skip_serializing_if = "Option::is_none")]
1867 pub change_position: Option<u32>,
1868 #[serde(rename = "change_type", skip_serializing_if = "Option::is_none")]
1869 pub change_type: Option<AddressType>,
1870 #[serde(skip_serializing_if = "Option::is_none")]
1871 pub include_watching: Option<bool>,
1872 #[serde(skip_serializing_if = "Option::is_none")]
1873 pub lock_unspents: Option<bool>,
1874 #[serde(
1875 with = "bitcoin::amount::serde::as_btc::opt",
1876 skip_serializing_if = "Option::is_none"
1877 )]
1878 pub fee_rate: Option<Amount>,
1879 #[serde(skip_serializing_if = "Option::is_none")]
1880 pub subtract_fee_from_outputs: Option<Vec<u32>>,
1881 #[serde(skip_serializing_if = "Option::is_none")]
1882 pub replaceable: Option<bool>,
1883 #[serde(rename = "conf_target", skip_serializing_if = "Option::is_none")]
1884 pub conf_target: Option<u32>,
1885 #[serde(rename = "estimate_mode", skip_serializing_if = "Option::is_none")]
1886 pub estimate_mode: Option<EstimateMode>,
1887}
1888
1889#[derive(Deserialize, Clone, PartialEq, Eq, Debug)]
1890#[serde(rename_all = "camelCase")]
1891pub struct FundRawTransactionResult {
1892 #[serde(with = "crate::serde_hex")]
1893 pub hex: Vec<u8>,
1894 #[serde(with = "bitcoin::amount::serde::as_btc")]
1895 pub fee: Amount,
1896 #[serde(rename = "changepos")]
1897 pub change_position: i32,
1898}
1899
1900#[derive(Deserialize, Clone, PartialEq, Eq, Debug)]
1901pub struct GetBalancesResultEntry {
1902 #[serde(with = "bitcoin::amount::serde::as_btc")]
1903 pub trusted: Amount,
1904 #[serde(with = "bitcoin::amount::serde::as_btc")]
1905 pub untrusted_pending: Amount,
1906 #[serde(with = "bitcoin::amount::serde::as_btc")]
1907 pub immature: Amount,
1908}
1909
1910#[derive(Deserialize, Clone, PartialEq, Eq, Debug)]
1911#[serde(rename_all = "camelCase")]
1912pub struct GetBalancesResult {
1913 pub mine: GetBalancesResultEntry,
1914 pub watchonly: Option<GetBalancesResultEntry>,
1915}
1916
1917impl FundRawTransactionResult {
1918 pub fn transaction(&self) -> Result<Transaction, encode::Error> {
1919 encode::deserialize(&self.hex)
1920 }
1921}
1922
1923#[derive(Serialize, Clone, PartialEq, Debug)]
1925#[serde(rename_all = "camelCase")]
1926pub struct SignRawTransactionInput {
1927 pub txid: bitcoin::Txid,
1928 pub vout: u32,
1929 pub script_pub_key: ScriptBuf,
1930 #[serde(skip_serializing_if = "Option::is_none")]
1931 pub redeem_script: Option<ScriptBuf>,
1932 #[serde(
1933 default,
1934 skip_serializing_if = "Option::is_none",
1935 with = "bitcoin::amount::serde::as_btc::opt"
1936 )]
1937 pub amount: Option<Amount>,
1938}
1939
1940#[derive(Clone, Serialize, PartialEq, Eq, Debug)]
1942#[serde(rename_all = "snake_case")]
1943pub enum TxOutSetHashType {
1944 HashSerialized2,
1945 Muhash,
1946 None,
1947}
1948
1949#[derive(Clone, Serialize, PartialEq, Eq, Debug)]
1951#[serde(untagged)]
1952pub enum HashOrHeight {
1953 BlockHash(bitcoin::BlockHash),
1954 Height(u64),
1955}
1956
1957#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1958pub struct GetTxOutSetInfoResult {
1959 pub height: u64,
1961 #[serde(rename = "bestblock")]
1963 pub best_block: bitcoin::BlockHash,
1964 #[serde(default, skip_serializing_if = "Option::is_none")]
1966 pub transactions: Option<u64>,
1967 #[serde(rename = "txouts")]
1969 pub tx_outs: u64,
1970 pub bogosize: u64,
1972 #[serde(default, skip_serializing_if = "Option::is_none")]
1974 pub hash_serialized_2: Option<sha256::Hash>,
1975 #[serde(default, skip_serializing_if = "Option::is_none")]
1977 pub muhash: Option<sha256::Hash>,
1978 #[serde(default, skip_serializing_if = "Option::is_none")]
1980 pub disk_size: Option<u64>,
1981 #[serde(with = "bitcoin::amount::serde::as_btc")]
1983 pub total_amount: Amount,
1984 #[serde(
1986 default,
1987 skip_serializing_if = "Option::is_none",
1988 with = "bitcoin::amount::serde::as_btc::opt"
1989 )]
1990 pub total_unspendable_amount: Option<Amount>,
1991 #[serde(default, skip_serializing_if = "Option::is_none")]
1993 pub block_info: Option<BlockInfo>,
1994}
1995
1996#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1998pub struct BlockInfo {
1999 #[serde(with = "bitcoin::amount::serde::as_btc")]
2001 pub prevout_spent: Amount,
2002 #[serde(with = "bitcoin::amount::serde::as_btc")]
2004 pub coinbase: Amount,
2005 #[serde(with = "bitcoin::amount::serde::as_btc")]
2007 pub new_outputs_ex_coinbase: Amount,
2008 #[serde(with = "bitcoin::amount::serde::as_btc")]
2010 pub unspendable: Amount,
2011 pub unspendables: Unspendables,
2013}
2014
2015#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
2017pub struct Unspendables {
2018 #[serde(with = "bitcoin::amount::serde::as_btc")]
2020 pub genesis_block: Amount,
2021 #[serde(with = "bitcoin::amount::serde::as_btc")]
2023 pub bip30: Amount,
2024 #[serde(with = "bitcoin::amount::serde::as_btc")]
2026 pub scripts: Amount,
2027 #[serde(with = "bitcoin::amount::serde::as_btc")]
2029 pub unclaimed_rewards: Amount,
2030}
2031
2032#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
2033pub struct GetNetTotalsResult {
2034 #[serde(rename = "totalbytesrecv")]
2036 pub total_bytes_recv: u64,
2037 #[serde(rename = "totalbytessent")]
2039 pub total_bytes_sent: u64,
2040 #[serde(rename = "timemillis")]
2042 pub time_millis: u64,
2043 #[serde(rename = "uploadtarget")]
2045 pub upload_target: GetNetTotalsResultUploadTarget,
2046}
2047
2048#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
2049pub struct GetNetTotalsResultUploadTarget {
2050 #[serde(rename = "timeframe")]
2052 pub time_frame: u64,
2053 pub target: u64,
2055 pub target_reached: bool,
2057 pub serve_historical_blocks: bool,
2059 pub bytes_left_in_cycle: u64,
2061 pub time_left_in_cycle: u64,
2063}
2064
2065#[derive(Copy, Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
2067#[serde(rename_all = "kebab-case")]
2068pub enum AddressType {
2069 Legacy,
2070 P2shSegwit,
2071 Bech32,
2072 Bech32m,
2073}
2074
2075#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
2077pub enum PubKeyOrAddress<'a> {
2078 Address(&'a Address),
2079 PubKey(&'a PublicKey),
2080}
2081
2082#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
2083#[serde(untagged)]
2084pub enum ScanTxOutRequest {
2086 Single(String),
2088 Extended {
2090 desc: String,
2092 range: (u64, u64),
2094 },
2095}
2096
2097#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
2098pub struct ScanTxOutResult {
2099 pub success: Option<bool>,
2100 #[serde(rename = "txouts")]
2101 pub tx_outs: Option<u64>,
2102 pub height: Option<u64>,
2103 #[serde(rename = "bestblock")]
2104 pub best_block_hash: Option<bitcoin::BlockHash>,
2105 pub unspents: Vec<Utxo>,
2106 #[serde(with = "bitcoin::amount::serde::as_btc")]
2107 pub total_amount: bitcoin::Amount,
2108}
2109
2110#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
2111#[serde(rename_all = "camelCase")]
2112pub struct Utxo {
2113 pub txid: bitcoin::Txid,
2114 pub vout: u32,
2115 pub script_pub_key: bitcoin::ScriptBuf,
2116 #[serde(rename = "desc")]
2117 pub descriptor: String,
2118 #[serde(with = "bitcoin::amount::serde::as_btc")]
2119 pub amount: bitcoin::Amount,
2120 pub height: u64,
2121}
2122
2123#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
2124pub struct IndexStatus {
2125 pub synced: bool,
2126 pub best_block_height: u32,
2127}
2128
2129#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
2130pub struct GetIndexInfoResult {
2131 pub txindex: Option<IndexStatus>,
2132 pub coinstatsindex: Option<IndexStatus>,
2133 #[serde(rename = "basic block filter index")]
2134 pub basic_block_filter_index: Option<IndexStatus>,
2135}
2136
2137impl<'a> serde::Serialize for PubKeyOrAddress<'a> {
2138 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
2139 where
2140 S: serde::Serializer,
2141 {
2142 match *self {
2143 PubKeyOrAddress::Address(a) => serde::Serialize::serialize(a, serializer),
2144 PubKeyOrAddress::PubKey(k) => serde::Serialize::serialize(k, serializer),
2145 }
2146 }
2147}
2148
2149fn deserialize_hex_array_opt<'de, D>(deserializer: D) -> Result<Option<Vec<Vec<u8>>>, D::Error>
2153where
2154 D: serde::Deserializer<'de>,
2155{
2156 let v: Vec<String> = Vec::deserialize(deserializer)?;
2160 let mut res = Vec::new();
2161 for h in v.into_iter() {
2162 res.push(FromHex::from_hex(&h).map_err(D::Error::custom)?);
2163 }
2164 Ok(Some(res))
2165}
2166
2167#[cfg(test)]
2168mod tests {
2169 use super::*;
2170
2171 #[test]
2172 fn test_softfork_type() {
2173 let buried: SoftforkType = serde_json::from_str("\"buried\"").unwrap();
2174 assert_eq!(buried, SoftforkType::Buried);
2175 let bip9: SoftforkType = serde_json::from_str("\"bip9\"").unwrap();
2176 assert_eq!(bip9, SoftforkType::Bip9);
2177 let other: SoftforkType = serde_json::from_str("\"bip8\"").unwrap();
2178 assert_eq!(other, SoftforkType::Other);
2179 }
2180}