1#![crate_name = "twistercore_rpc_json"]
17#![crate_type = "rlib"]
18#![allow(deprecated)] pub extern crate bitcoin;
21#[allow(unused)]
22#[macro_use] extern crate serde;
24extern crate serde_json;
25
26use std::collections::HashMap;
27
28use bitcoin::address::NetworkUnchecked;
29use bitcoin::block::Version;
30use bitcoin::consensus::encode;
31use bitcoin::hashes::hex::FromHex;
32use bitcoin::hashes::sha256;
33use bitcoin::{
34 bip158, bip32, Address, Amount, Network, PrivateKey, PublicKey, Script, ScriptBuf,
35 SignedAmount, Transaction,
36};
37use serde::de::Error as SerdeError;
38use serde::{Deserialize, Serialize};
39use std::fmt;
40
41pub mod serde_hex {
47 use bitcoin::hex::{DisplayHex, FromHex};
48 use serde::de::Error;
49 use serde::{Deserializer, Serializer};
50
51 pub fn serialize<S: Serializer>(b: &Vec<u8>, s: S) -> Result<S::Ok, S::Error> {
52 s.serialize_str(&b.to_lower_hex_string())
53 }
54
55 pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result<Vec<u8>, D::Error> {
56 let hex_str: String = ::serde::Deserialize::deserialize(d)?;
57 Ok(FromHex::from_hex(&hex_str).map_err(D::Error::custom)?)
58 }
59
60 pub mod opt {
61 use bitcoin::hex::{DisplayHex, FromHex};
62 use serde::de::Error;
63 use serde::{Deserializer, Serializer};
64
65 pub fn serialize<S: Serializer>(b: &Option<Vec<u8>>, s: S) -> Result<S::Ok, S::Error> {
66 match *b {
67 None => s.serialize_none(),
68 Some(ref b) => s.serialize_str(&b.to_lower_hex_string()),
69 }
70 }
71
72 pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result<Option<Vec<u8>>, D::Error> {
73 let hex_str: String = ::serde::Deserialize::deserialize(d)?;
74 Ok(Some(FromHex::from_hex(&hex_str).map_err(D::Error::custom)?))
75 }
76 }
77}
78
79#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
80pub struct GetNetworkInfoResultNetwork {
81 pub name: String,
82 pub limited: bool,
83 pub reachable: bool,
84 pub proxy: String,
85 pub proxy_randomize_credentials: bool,
86}
87
88#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
89pub struct GetNetworkInfoResultAddress {
90 pub address: String,
91 pub port: usize,
92 pub score: usize,
93}
94
95#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
96pub struct GetNetworkInfoResult {
97 pub version: usize,
98 pub subversion: String,
99 #[serde(rename = "protocolversion")]
100 pub protocol_version: usize,
101 #[serde(rename = "localservices")]
102 pub local_services: String,
103 #[serde(rename = "localrelay")]
104 pub local_relay: bool,
105 #[serde(rename = "timeoffset")]
106 pub time_offset: isize,
107 pub connections: usize,
108 pub connections_in: Option<usize>,
111 pub connections_out: Option<usize>,
114 #[serde(rename = "networkactive")]
115 pub network_active: bool,
116 pub networks: Vec<GetNetworkInfoResultNetwork>,
117 #[serde(rename = "relayfee", with = "bitcoin::amount::serde::as_btc")]
118 pub relay_fee: Amount,
119 #[serde(rename = "incrementalfee", with = "bitcoin::amount::serde::as_btc")]
120 pub incremental_fee: Amount,
121 #[serde(rename = "localaddresses")]
122 pub local_addresses: Vec<GetNetworkInfoResultAddress>,
123 pub warnings: StringOrStringArray,
124}
125
126#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
127#[serde(rename_all = "camelCase")]
128pub struct AddMultiSigAddressResult {
129 pub address: Address<NetworkUnchecked>,
130 pub redeem_script: ScriptBuf,
131}
132
133#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
134pub struct LoadWalletResult {
135 pub name: String,
136 pub warning: Option<String>,
137}
138
139#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
140pub struct UnloadWalletResult {
141 pub warning: Option<String>,
142}
143
144#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
145pub struct ListWalletDirResult {
146 pub wallets: Vec<ListWalletDirItem>,
147}
148
149#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
150pub struct ListWalletDirItem {
151 pub name: String,
152}
153
154#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
155pub struct GetWalletInfoResult {
156 #[serde(rename = "walletname")]
157 pub wallet_name: String,
158 #[serde(rename = "walletversion")]
159 pub wallet_version: u32,
160 #[serde(with = "bitcoin::amount::serde::as_btc")]
161 pub balance: Amount,
162 #[serde(with = "bitcoin::amount::serde::as_btc")]
163 pub unconfirmed_balance: Amount,
164 #[serde(with = "bitcoin::amount::serde::as_btc")]
165 pub immature_balance: Amount,
166 #[serde(rename = "txcount")]
167 pub tx_count: usize,
168 #[serde(rename = "keypoololdest")]
169 pub keypool_oldest: Option<usize>,
170 #[serde(rename = "keypoolsize")]
171 pub keypool_size: usize,
172 #[serde(rename = "keypoolsize_hd_internal")]
173 pub keypool_size_hd_internal: usize,
174 pub unlocked_until: Option<u64>,
175 #[serde(rename = "paytxfee", with = "bitcoin::amount::serde::as_btc")]
176 pub pay_tx_fee: Amount,
177 #[serde(rename = "hdseedid")]
178 pub hd_seed_id: Option<bitcoin::bip32::XKeyIdentifier>,
179 pub private_keys_enabled: bool,
180 pub avoid_reuse: Option<bool>,
181 pub scanning: Option<ScanningDetails>,
182}
183
184#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
185#[serde(untagged)]
186pub enum ScanningDetails {
187 Scanning {
188 duration: usize,
189 progress: f32,
190 },
191 NotScanning(bool),
193}
194
195impl Eq for ScanningDetails {}
196
197#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
198#[serde(rename_all = "camelCase")]
199pub struct GetBlockResult {
200 pub hash: bitcoin::BlockHash,
201 pub confirmations: i32,
202 pub size: usize,
203 pub strippedsize: Option<usize>,
204 pub height: usize,
205 pub version: i32,
206 #[serde(default, with = "crate::serde_hex::opt")]
207 pub version_hex: Option<Vec<u8>>,
208 pub merkleroot: bitcoin::hash_types::TxMerkleNode,
209 pub tx: Vec<bitcoin::Txid>,
210 pub time: usize,
211 pub mediantime: Option<usize>,
212 pub nonce: u32,
213 pub bits: String,
214 pub difficulty: f64,
215 pub previousblockhash: Option<bitcoin::BlockHash>,
216 pub nextblockhash: Option<bitcoin::BlockHash>,
217}
218
219#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
220#[serde(rename_all = "camelCase")]
221pub struct GetBlockHeaderResult {
222 pub hash: bitcoin::BlockHash,
223 pub confirmations: i32,
224 pub height: usize,
225 pub version: Version,
226 #[serde(default, with = "crate::serde_hex::opt")]
227 pub version_hex: Option<Vec<u8>>,
228 #[serde(rename = "merkleroot")]
229 pub merkle_root: bitcoin::hash_types::TxMerkleNode,
230 pub time: usize,
231 #[serde(rename = "mediantime")]
232 pub median_time: Option<usize>,
233 pub nonce: u32,
234 pub bits: String,
235 pub difficulty: f64,
236 #[serde(with = "crate::serde_hex")]
237 pub chainwork: Vec<u8>,
238 pub n_tx: usize,
239 #[serde(rename = "previousblockhash")]
240 pub previous_block_hash: Option<bitcoin::BlockHash>,
241 #[serde(rename = "nextblockhash")]
242 pub next_block_hash: Option<bitcoin::BlockHash>,
243}
244
245#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
246pub struct GetBlockStatsResult {
247 #[serde(rename = "avgfee", with = "bitcoin::amount::serde::as_sat")]
248 pub avg_fee: Amount,
249 #[serde(rename = "avgfeerate", with = "bitcoin::amount::serde::as_sat")]
250 pub avg_fee_rate: Amount,
251 #[serde(rename = "avgtxsize")]
252 pub avg_tx_size: u32,
253 #[serde(rename = "blockhash")]
254 pub block_hash: bitcoin::BlockHash,
255 #[serde(rename = "feerate_percentiles")]
256 pub fee_rate_percentiles: FeeRatePercentiles,
257 pub height: u64,
258 pub ins: usize,
259 #[serde(rename = "maxfee", with = "bitcoin::amount::serde::as_sat")]
260 pub max_fee: Amount,
261 #[serde(rename = "maxfeerate", with = "bitcoin::amount::serde::as_sat")]
262 pub max_fee_rate: Amount,
263 #[serde(rename = "maxtxsize")]
264 pub max_tx_size: u32,
265 #[serde(rename = "medianfee", with = "bitcoin::amount::serde::as_sat")]
266 pub median_fee: Amount,
267 #[serde(rename = "mediantime")]
268 pub median_time: u64,
269 #[serde(rename = "mediantxsize")]
270 pub median_tx_size: u32,
271 #[serde(rename = "minfee", with = "bitcoin::amount::serde::as_sat")]
272 pub min_fee: Amount,
273 #[serde(rename = "minfeerate", with = "bitcoin::amount::serde::as_sat")]
274 pub min_fee_rate: Amount,
275 #[serde(rename = "mintxsize")]
276 pub min_tx_size: u32,
277 pub outs: usize,
278 #[serde(with = "bitcoin::amount::serde::as_sat")]
279 pub subsidy: Amount,
280 #[serde(rename = "swtotal_size")]
281 pub sw_total_size: usize,
282 #[serde(rename = "swtotal_weight")]
283 pub sw_total_weight: usize,
284 #[serde(rename = "swtxs")]
285 pub sw_txs: usize,
286 pub time: u64,
287 #[serde(with = "bitcoin::amount::serde::as_sat")]
288 pub total_out: Amount,
289 pub total_size: usize,
290 pub total_weight: usize,
291 #[serde(rename = "totalfee", with = "bitcoin::amount::serde::as_sat")]
292 pub total_fee: Amount,
293 pub txs: usize,
294 pub utxo_increase: i32,
295 pub utxo_size_inc: i32,
296}
297
298#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
299pub struct GetBlockStatsResultPartial {
300 #[serde(
301 default,
302 rename = "avgfee",
303 with = "bitcoin::amount::serde::as_sat::opt",
304 skip_serializing_if = "Option::is_none"
305 )]
306 pub avg_fee: Option<Amount>,
307 #[serde(
308 default,
309 rename = "avgfeerate",
310 with = "bitcoin::amount::serde::as_sat::opt",
311 skip_serializing_if = "Option::is_none"
312 )]
313 pub avg_fee_rate: Option<Amount>,
314 #[serde(default, rename = "avgtxsize", skip_serializing_if = "Option::is_none")]
315 pub avg_tx_size: Option<u32>,
316 #[serde(default, rename = "blockhash", skip_serializing_if = "Option::is_none")]
317 pub block_hash: Option<bitcoin::BlockHash>,
318 #[serde(default, rename = "feerate_percentiles", skip_serializing_if = "Option::is_none")]
319 pub fee_rate_percentiles: Option<FeeRatePercentiles>,
320 #[serde(default, skip_serializing_if = "Option::is_none")]
321 pub height: Option<u64>,
322 #[serde(default, skip_serializing_if = "Option::is_none")]
323 pub ins: Option<usize>,
324 #[serde(
325 default,
326 rename = "maxfee",
327 with = "bitcoin::amount::serde::as_sat::opt",
328 skip_serializing_if = "Option::is_none"
329 )]
330 pub max_fee: Option<Amount>,
331 #[serde(
332 default,
333 rename = "maxfeerate",
334 with = "bitcoin::amount::serde::as_sat::opt",
335 skip_serializing_if = "Option::is_none"
336 )]
337 pub max_fee_rate: Option<Amount>,
338 #[serde(default, rename = "maxtxsize", skip_serializing_if = "Option::is_none")]
339 pub max_tx_size: Option<u32>,
340 #[serde(
341 default,
342 rename = "medianfee",
343 with = "bitcoin::amount::serde::as_sat::opt",
344 skip_serializing_if = "Option::is_none"
345 )]
346 pub median_fee: Option<Amount>,
347 #[serde(default, rename = "mediantime", skip_serializing_if = "Option::is_none")]
348 pub median_time: Option<u64>,
349 #[serde(default, rename = "mediantxsize", skip_serializing_if = "Option::is_none")]
350 pub median_tx_size: Option<u32>,
351 #[serde(
352 default,
353 rename = "minfee",
354 with = "bitcoin::amount::serde::as_sat::opt",
355 skip_serializing_if = "Option::is_none"
356 )]
357 pub min_fee: Option<Amount>,
358 #[serde(
359 default,
360 rename = "minfeerate",
361 with = "bitcoin::amount::serde::as_sat::opt",
362 skip_serializing_if = "Option::is_none"
363 )]
364 pub min_fee_rate: Option<Amount>,
365 #[serde(default, rename = "mintxsize", skip_serializing_if = "Option::is_none")]
366 pub min_tx_size: Option<u32>,
367 #[serde(default, skip_serializing_if = "Option::is_none")]
368 pub outs: Option<usize>,
369 #[serde(
370 default,
371 with = "bitcoin::amount::serde::as_sat::opt",
372 skip_serializing_if = "Option::is_none"
373 )]
374 pub subsidy: Option<Amount>,
375 #[serde(default, rename = "swtotal_size", skip_serializing_if = "Option::is_none")]
376 pub sw_total_size: Option<usize>,
377 #[serde(default, rename = "swtotal_weight", skip_serializing_if = "Option::is_none")]
378 pub sw_total_weight: Option<usize>,
379 #[serde(default, rename = "swtxs", skip_serializing_if = "Option::is_none")]
380 pub sw_txs: Option<usize>,
381 #[serde(default, skip_serializing_if = "Option::is_none")]
382 pub time: Option<u64>,
383 #[serde(
384 default,
385 with = "bitcoin::amount::serde::as_sat::opt",
386 skip_serializing_if = "Option::is_none"
387 )]
388 pub total_out: Option<Amount>,
389 #[serde(default, skip_serializing_if = "Option::is_none")]
390 pub total_size: Option<usize>,
391 #[serde(default, skip_serializing_if = "Option::is_none")]
392 pub total_weight: Option<usize>,
393 #[serde(
394 default,
395 rename = "totalfee",
396 with = "bitcoin::amount::serde::as_sat::opt",
397 skip_serializing_if = "Option::is_none"
398 )]
399 pub total_fee: Option<Amount>,
400 #[serde(default, skip_serializing_if = "Option::is_none")]
401 pub txs: Option<usize>,
402 #[serde(default, skip_serializing_if = "Option::is_none")]
403 pub utxo_increase: Option<i32>,
404 #[serde(default, skip_serializing_if = "Option::is_none")]
405 pub utxo_size_inc: Option<i32>,
406}
407
408#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
409pub struct FeeRatePercentiles {
410 #[serde(with = "bitcoin::amount::serde::as_sat")]
411 pub fr_10th: Amount,
412 #[serde(with = "bitcoin::amount::serde::as_sat")]
413 pub fr_25th: Amount,
414 #[serde(with = "bitcoin::amount::serde::as_sat")]
415 pub fr_50th: Amount,
416 #[serde(with = "bitcoin::amount::serde::as_sat")]
417 pub fr_75th: Amount,
418 #[serde(with = "bitcoin::amount::serde::as_sat")]
419 pub fr_90th: Amount,
420}
421
422#[derive(Clone)]
423pub enum BlockStatsFields {
424 AverageFee,
425 AverageFeeRate,
426 AverageTxSize,
427 BlockHash,
428 FeeRatePercentiles,
429 Height,
430 Ins,
431 MaxFee,
432 MaxFeeRate,
433 MaxTxSize,
434 MedianFee,
435 MedianTime,
436 MedianTxSize,
437 MinFee,
438 MinFeeRate,
439 MinTxSize,
440 Outs,
441 Subsidy,
442 SegWitTotalSize,
443 SegWitTotalWeight,
444 SegWitTxs,
445 Time,
446 TotalOut,
447 TotalSize,
448 TotalWeight,
449 TotalFee,
450 Txs,
451 UtxoIncrease,
452 UtxoSizeIncrease,
453}
454
455impl BlockStatsFields {
456 fn get_rpc_keyword(&self) -> &str {
457 match *self {
458 BlockStatsFields::AverageFee => "avgfee",
459 BlockStatsFields::AverageFeeRate => "avgfeerate",
460 BlockStatsFields::AverageTxSize => "avgtxsize",
461 BlockStatsFields::BlockHash => "blockhash",
462 BlockStatsFields::FeeRatePercentiles => "feerate_percentiles",
463 BlockStatsFields::Height => "height",
464 BlockStatsFields::Ins => "ins",
465 BlockStatsFields::MaxFee => "maxfee",
466 BlockStatsFields::MaxFeeRate => "maxfeerate",
467 BlockStatsFields::MaxTxSize => "maxtxsize",
468 BlockStatsFields::MedianFee => "medianfee",
469 BlockStatsFields::MedianTime => "mediantime",
470 BlockStatsFields::MedianTxSize => "mediantxsize",
471 BlockStatsFields::MinFee => "minfee",
472 BlockStatsFields::MinFeeRate => "minfeerate",
473 BlockStatsFields::MinTxSize => "minfeerate",
474 BlockStatsFields::Outs => "outs",
475 BlockStatsFields::Subsidy => "subsidy",
476 BlockStatsFields::SegWitTotalSize => "swtotal_size",
477 BlockStatsFields::SegWitTotalWeight => "swtotal_weight",
478 BlockStatsFields::SegWitTxs => "swtxs",
479 BlockStatsFields::Time => "time",
480 BlockStatsFields::TotalOut => "total_out",
481 BlockStatsFields::TotalSize => "total_size",
482 BlockStatsFields::TotalWeight => "total_weight",
483 BlockStatsFields::TotalFee => "totalfee",
484 BlockStatsFields::Txs => "txs",
485 BlockStatsFields::UtxoIncrease => "utxo_increase",
486 BlockStatsFields::UtxoSizeIncrease => "utxo_size_inc",
487 }
488 }
489}
490
491impl fmt::Display for BlockStatsFields {
492 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
493 write!(f, "{}", self.get_rpc_keyword())
494 }
495}
496
497impl From<BlockStatsFields> for serde_json::Value {
498 fn from(bsf: BlockStatsFields) -> Self {
499 Self::from(bsf.to_string())
500 }
501}
502
503#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
504#[serde(rename_all = "camelCase")]
505pub struct GetMiningInfoResult {
506 pub blocks: u32,
507 #[serde(rename = "currentblockweight")]
508 pub current_block_weight: Option<u64>,
509 #[serde(rename = "currentblocktx")]
510 pub current_block_tx: Option<usize>,
511 pub difficulty: f64,
512 #[serde(rename = "networkhashps")]
513 pub network_hash_ps: f64,
514 #[serde(rename = "pooledtx")]
515 pub pooled_tx: usize,
516 #[serde(deserialize_with = "deserialize_bip70_network")]
517 pub chain: Network,
518 pub warnings: StringOrStringArray,
519}
520
521#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
522#[serde(rename_all = "camelCase")]
523pub struct GetRawTransactionResultVinScriptSig {
524 pub asm: String,
525 #[serde(with = "crate::serde_hex")]
526 pub hex: Vec<u8>,
527}
528
529impl GetRawTransactionResultVinScriptSig {
530 pub fn script(&self) -> Result<ScriptBuf, encode::Error> {
531 Ok(ScriptBuf::from(self.hex.clone()))
532 }
533}
534
535#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
536#[serde(rename_all = "camelCase")]
537pub struct GetRawTransactionResultVin {
538 pub sequence: u32,
539 #[serde(default, with = "crate::serde_hex::opt")]
541 pub coinbase: Option<Vec<u8>>,
542 pub txid: Option<bitcoin::Txid>,
544 pub vout: Option<u32>,
546 pub script_sig: Option<GetRawTransactionResultVinScriptSig>,
548 #[serde(default, deserialize_with = "deserialize_hex_array_opt")]
550 pub txinwitness: Option<Vec<Vec<u8>>>,
551}
552
553impl GetRawTransactionResultVin {
554 pub fn is_coinbase(&self) -> bool {
558 self.coinbase.is_some()
559 }
560}
561
562#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
563#[serde(rename_all = "camelCase")]
564pub struct GetRawTransactionResultVoutScriptPubKey {
565 pub asm: String,
566 #[serde(with = "crate::serde_hex")]
567 pub hex: Vec<u8>,
568 pub req_sigs: Option<usize>,
569 #[serde(rename = "type")]
570 pub type_: Option<ScriptPubkeyType>,
571 #[serde(default)]
573 pub addresses: Vec<Address<NetworkUnchecked>>,
574 #[serde(default)]
576 pub address: Option<Address<NetworkUnchecked>>,
577}
578
579impl GetRawTransactionResultVoutScriptPubKey {
580 pub fn script(&self) -> Result<ScriptBuf, encode::Error> {
581 Ok(ScriptBuf::from(self.hex.clone()))
582 }
583}
584
585#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
586#[serde(rename_all = "camelCase")]
587pub struct GetRawTransactionResultVout {
588 #[serde(with = "bitcoin::amount::serde::as_btc")]
589 pub value: Amount,
590 pub n: u32,
591 pub script_pub_key: GetRawTransactionResultVoutScriptPubKey,
592}
593
594#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
595#[serde(rename_all = "camelCase")]
596pub struct GetRawTransactionResult {
597 #[serde(rename = "in_active_chain")]
598 pub in_active_chain: Option<bool>,
599 #[serde(with = "crate::serde_hex")]
600 pub hex: Vec<u8>,
601 pub txid: bitcoin::Txid,
602 pub hash: bitcoin::Wtxid,
603 pub size: usize,
604 pub vsize: usize,
605 pub version: u32,
606 pub locktime: u32,
607 pub vin: Vec<GetRawTransactionResultVin>,
608 pub vout: Vec<GetRawTransactionResultVout>,
609 pub blockhash: Option<bitcoin::BlockHash>,
610 pub confirmations: Option<u32>,
611 pub time: Option<usize>,
612 pub blocktime: Option<usize>,
613}
614
615#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
616pub struct GetBlockFilterResult {
617 pub header: bitcoin::hash_types::FilterHash,
618 #[serde(with = "crate::serde_hex")]
619 pub filter: Vec<u8>,
620}
621
622impl GetBlockFilterResult {
623 pub fn to_filter(&self) -> bip158::BlockFilter {
627 bip158::BlockFilter::new(&self.filter)
628 }
629
630 pub fn into_filter(self) -> bip158::BlockFilter {
632 bip158::BlockFilter {
633 content: self.filter,
634 }
635 }
636}
637
638impl GetRawTransactionResult {
639 pub fn is_coinbase(&self) -> bool {
641 self.vin.len() == 1 && self.vin[0].is_coinbase()
642 }
643
644 pub fn transaction(&self) -> Result<Transaction, encode::Error> {
645 Ok(encode::deserialize(&self.hex)?)
646 }
647}
648
649#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
651#[serde(rename_all = "lowercase")]
652pub enum Bip125Replaceable {
653 Yes,
654 No,
655 Unknown,
656}
657
658#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
660#[serde(rename_all = "lowercase")]
661pub enum GetTransactionResultDetailCategory {
662 Send,
663 Receive,
664 Generate,
665 Immature,
666 Orphan,
667}
668
669#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
670pub struct GetTransactionResultDetail {
671 pub address: Option<Address<NetworkUnchecked>>,
672 pub category: GetTransactionResultDetailCategory,
673 #[serde(with = "bitcoin::amount::serde::as_btc")]
674 pub amount: SignedAmount,
675 pub label: Option<String>,
676 pub vout: u32,
677 #[serde(default, with = "bitcoin::amount::serde::as_btc::opt")]
678 pub fee: Option<SignedAmount>,
679 pub abandoned: Option<bool>,
680}
681
682#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
683pub struct WalletTxInfo {
684 pub confirmations: i32,
685 pub blockhash: Option<bitcoin::BlockHash>,
686 pub blockindex: Option<usize>,
687 pub blocktime: Option<u64>,
688 pub blockheight: Option<u32>,
689 pub txid: bitcoin::Txid,
690 pub time: u64,
691 pub timereceived: u64,
692 #[serde(rename = "bip125-replaceable")]
693 pub bip125_replaceable: Bip125Replaceable,
694 #[serde(rename = "walletconflicts")]
696 pub wallet_conflicts: Vec<bitcoin::Txid>,
697}
698
699#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
700pub struct GetTransactionResult {
701 #[serde(flatten)]
702 pub info: WalletTxInfo,
703 #[serde(with = "bitcoin::amount::serde::as_btc")]
704 pub amount: SignedAmount,
705 #[serde(default, with = "bitcoin::amount::serde::as_btc::opt")]
706 pub fee: Option<SignedAmount>,
707 pub details: Vec<GetTransactionResultDetail>,
708 #[serde(with = "crate::serde_hex")]
709 pub hex: Vec<u8>,
710}
711
712impl GetTransactionResult {
713 pub fn transaction(&self) -> Result<Transaction, encode::Error> {
714 Ok(encode::deserialize(&self.hex)?)
715 }
716}
717
718#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
719pub struct ListTransactionResult {
720 #[serde(flatten)]
721 pub info: WalletTxInfo,
722 #[serde(flatten)]
723 pub detail: GetTransactionResultDetail,
724
725 pub trusted: Option<bool>,
726 pub comment: Option<String>,
727}
728
729#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
730pub struct ListSinceBlockResult {
731 pub transactions: Vec<ListTransactionResult>,
732 #[serde(default)]
733 pub removed: Vec<ListTransactionResult>,
734 pub lastblock: bitcoin::BlockHash,
735}
736
737#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
738#[serde(rename_all = "camelCase")]
739pub struct GetTxOutResult {
740 pub bestblock: bitcoin::BlockHash,
741 pub confirmations: u32,
742 #[serde(with = "bitcoin::amount::serde::as_btc")]
743 pub value: Amount,
744 pub script_pub_key: GetRawTransactionResultVoutScriptPubKey,
745 pub coinbase: bool,
746}
747
748#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize, Default)]
749#[serde(rename_all = "camelCase")]
750pub struct ListUnspentQueryOptions {
751 #[serde(
752 rename = "minimumAmount",
753 with = "bitcoin::amount::serde::as_btc::opt",
754 skip_serializing_if = "Option::is_none"
755 )]
756 pub minimum_amount: Option<Amount>,
757 #[serde(
758 rename = "maximumAmount",
759 with = "bitcoin::amount::serde::as_btc::opt",
760 skip_serializing_if = "Option::is_none"
761 )]
762 pub maximum_amount: Option<Amount>,
763 #[serde(rename = "maximumCount", skip_serializing_if = "Option::is_none")]
764 pub maximum_count: Option<usize>,
765 #[serde(
766 rename = "minimumSumAmount",
767 with = "bitcoin::amount::serde::as_btc::opt",
768 skip_serializing_if = "Option::is_none"
769 )]
770 pub minimum_sum_amount: Option<Amount>,
771}
772
773#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
774#[serde(rename_all = "camelCase")]
775pub struct ListUnspentResultEntry {
776 pub txid: bitcoin::Txid,
777 pub vout: u32,
778 pub address: Option<Address<NetworkUnchecked>>,
779 pub label: Option<String>,
780 pub redeem_script: Option<ScriptBuf>,
781 pub witness_script: Option<ScriptBuf>,
782 pub script_pub_key: ScriptBuf,
783 #[serde(with = "bitcoin::amount::serde::as_btc")]
784 pub amount: Amount,
785 pub confirmations: u32,
786 pub spendable: bool,
787 pub solvable: bool,
788 #[serde(rename = "desc")]
789 pub descriptor: Option<String>,
790 pub safe: bool,
791}
792
793#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
794#[serde(rename_all = "camelCase")]
795pub struct ListReceivedByAddressResult {
796 #[serde(default, rename = "involvesWatchonly")]
797 pub involved_watch_only: bool,
798 pub address: Address<NetworkUnchecked>,
799 #[serde(with = "bitcoin::amount::serde::as_btc")]
800 pub amount: Amount,
801 pub confirmations: u32,
802 pub label: String,
803 pub txids: Vec<bitcoin::Txid>,
804}
805
806#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
807#[serde(rename_all = "camelCase")]
808pub struct SignRawTransactionResultError {
809 pub txid: bitcoin::Txid,
810 pub vout: u32,
811 pub script_sig: ScriptBuf,
812 pub sequence: u32,
813 pub error: String,
814}
815
816#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
817#[serde(rename_all = "camelCase")]
818pub struct SignRawTransactionResult {
819 #[serde(with = "crate::serde_hex")]
820 pub hex: Vec<u8>,
821 pub complete: bool,
822 pub errors: Option<Vec<SignRawTransactionResultError>>,
823}
824
825impl SignRawTransactionResult {
826 pub fn transaction(&self) -> Result<Transaction, encode::Error> {
827 Ok(encode::deserialize(&self.hex)?)
828 }
829}
830
831#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
832pub struct TestMempoolAcceptResult {
833 pub txid: bitcoin::Txid,
834 pub allowed: bool,
835 #[serde(rename = "reject-reason")]
836 pub reject_reason: Option<String>,
837 pub vsize: Option<u64>,
840 pub fees: Option<TestMempoolAcceptResultFees>,
843}
844
845#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
846pub struct TestMempoolAcceptResultFees {
847 #[serde(with = "bitcoin::amount::serde::as_btc")]
849 pub base: Amount,
850 }
852
853#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
854#[serde(rename_all = "snake_case")]
855pub enum Bip9SoftforkStatus {
856 Defined,
857 Started,
858 LockedIn,
859 Active,
860 Failed,
861}
862
863#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
864pub struct Bip9SoftforkStatistics {
865 pub period: u32,
866 pub threshold: Option<u32>,
867 pub elapsed: u32,
868 pub count: u32,
869 pub possible: Option<bool>,
870}
871
872#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
873pub struct Bip9SoftforkInfo {
874 pub status: Bip9SoftforkStatus,
875 pub bit: Option<u8>,
876 pub start_time: i64,
878 pub timeout: u64,
879 pub since: u32,
880 pub statistics: Option<Bip9SoftforkStatistics>,
881}
882
883#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
884#[serde(rename_all = "lowercase")]
885pub enum SoftforkType {
886 Buried,
887 Bip9,
888 #[serde(other)]
889 Other,
890}
891
892#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
894pub struct Softfork {
895 #[serde(rename = "type")]
896 pub type_: SoftforkType,
897 pub bip9: Option<Bip9SoftforkInfo>,
898 pub height: Option<u32>,
899 pub active: bool,
900}
901
902#[allow(non_camel_case_types)]
903#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
904#[serde(rename_all = "lowercase")]
905pub enum ScriptPubkeyType {
906 Nonstandard,
907 Pubkey,
908 PubkeyHash,
909 ScriptHash,
910 MultiSig,
911 NullData,
912 Witness_v0_KeyHash,
913 Witness_v0_ScriptHash,
914 Witness_v1_Taproot,
915 Witness_Unknown,
916}
917
918#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
919pub struct GetAddressInfoResultEmbedded {
920 pub address: Address<NetworkUnchecked>,
921 #[serde(rename = "scriptPubKey")]
922 pub script_pub_key: ScriptBuf,
923 #[serde(rename = "is_script")]
924 pub is_script: Option<bool>,
925 #[serde(rename = "is_witness")]
926 pub is_witness: Option<bool>,
927 pub witness_version: Option<u32>,
928 #[serde(with = "crate::serde_hex")]
929 pub witness_program: Vec<u8>,
930 pub script: Option<ScriptPubkeyType>,
931 #[serde(default, with = "crate::serde_hex::opt")]
933 pub hex: Option<Vec<u8>>,
934 pub pubkeys: Option<Vec<PublicKey>>,
935 #[serde(rename = "sigsrequired")]
936 pub n_signatures_required: Option<usize>,
937 pub pubkey: Option<PublicKey>,
938 #[serde(rename = "is_compressed")]
939 pub is_compressed: Option<bool>,
940 pub label: Option<String>,
941 #[serde(rename = "hdkeypath")]
942 pub hd_key_path: Option<bip32::DerivationPath>,
943 #[serde(rename = "hdseedid")]
944 pub hd_seed_id: Option<bitcoin::bip32::XKeyIdentifier>,
945 #[serde(default)]
946 pub labels: Vec<GetAddressInfoResultLabel>,
947}
948
949#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
950#[serde(rename_all = "lowercase")]
951pub enum GetAddressInfoResultLabelPurpose {
952 Send,
953 Receive,
954}
955
956#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
957#[serde(untagged)]
958pub enum GetAddressInfoResultLabel {
959 Simple(String),
960 WithPurpose {
961 name: String,
962 purpose: GetAddressInfoResultLabelPurpose,
963 },
964}
965
966#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
967pub struct GetAddressInfoResult {
968 pub address: Address<NetworkUnchecked>,
969 #[serde(rename = "scriptPubKey")]
970 pub script_pub_key: ScriptBuf,
971 #[serde(rename = "ismine")]
972 pub is_mine: Option<bool>,
973 #[serde(rename = "iswatchonly")]
974 pub is_watchonly: Option<bool>,
975 #[serde(rename = "isscript")]
976 pub is_script: Option<bool>,
977 #[serde(rename = "iswitness")]
978 pub is_witness: Option<bool>,
979 pub witness_version: Option<u32>,
980 #[serde(default, with = "crate::serde_hex::opt")]
981 pub witness_program: Option<Vec<u8>>,
982 pub script: Option<ScriptPubkeyType>,
983 #[serde(default, with = "crate::serde_hex::opt")]
985 pub hex: Option<Vec<u8>>,
986 pub pubkeys: Option<Vec<PublicKey>>,
987 #[serde(rename = "sigsrequired")]
988 pub n_signatures_required: Option<usize>,
989 pub pubkey: Option<PublicKey>,
990 pub embedded: Option<GetAddressInfoResultEmbedded>,
992 #[serde(rename = "is_compressed")]
993 pub is_compressed: Option<bool>,
994 pub timestamp: Option<u64>,
995 #[serde(rename = "hdkeypath")]
996 pub hd_key_path: Option<bip32::DerivationPath>,
997 #[serde(rename = "hdseedid")]
998 pub hd_seed_id: Option<bitcoin::bip32::XKeyIdentifier>,
999 pub labels: Vec<GetAddressInfoResultLabel>,
1000 #[deprecated(note = "since Core v0.20.0")]
1002 pub label: Option<String>,
1003}
1004
1005#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)]
1007#[serde(untagged)]
1008pub enum StringOrStringArray {
1009 String(String),
1010 StringArray(Vec<String>),
1011}
1012
1013#[derive(Clone, Debug, Deserialize, Serialize)]
1015pub struct GetBlockchainInfoResult {
1016 #[serde(deserialize_with = "deserialize_bip70_network")]
1018 pub chain: Network,
1019 pub blocks: u64,
1021 pub headers: u64,
1023 #[serde(rename = "bestblockhash")]
1025 pub best_block_hash: bitcoin::BlockHash,
1026 pub difficulty: f64,
1028 #[serde(rename = "mediantime")]
1030 pub median_time: u64,
1031 #[serde(rename = "verificationprogress")]
1033 pub verification_progress: f64,
1034 #[serde(rename = "initialblockdownload")]
1036 pub initial_block_download: bool,
1037 #[serde(rename = "chainwork", with = "crate::serde_hex")]
1039 pub chain_work: Vec<u8>,
1040 pub size_on_disk: u64,
1042 pub pruned: bool,
1044 #[serde(rename = "pruneheight")]
1046 pub prune_height: Option<u64>,
1047 pub automatic_pruning: Option<bool>,
1049 pub prune_target_size: Option<u64>,
1051 #[serde(default)]
1053 pub softforks: HashMap<String, Softfork>,
1054 pub warnings: StringOrStringArray,
1056}
1057
1058#[derive(Clone, PartialEq, Eq, Debug)]
1059pub enum ImportMultiRequestScriptPubkey<'a> {
1060 Address(&'a Address),
1061 Script(&'a Script),
1062}
1063
1064#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1065pub struct GetMempoolInfoResult {
1066 pub loaded: Option<bool>,
1068 pub size: usize,
1070 pub bytes: usize,
1072 pub usage: usize,
1074 #[serde(default, with = "bitcoin::amount::serde::as_btc::opt")]
1076 pub total_fee: Option<Amount>,
1077 #[serde(rename = "maxmempool")]
1079 pub max_mempool: usize,
1080 #[serde(rename = "mempoolminfee", with = "bitcoin::amount::serde::as_btc")]
1082 pub mempool_min_fee: Amount,
1083 #[serde(rename = "minrelaytxfee", with = "bitcoin::amount::serde::as_btc")]
1085 pub min_relay_tx_fee: Amount,
1086 #[serde(rename = "incrementalrelayfee", default, with = "bitcoin::amount::serde::as_btc::opt")]
1088 pub incremental_relay_fee: Option<Amount>,
1089 #[serde(rename = "unbroadcastcount")]
1091 pub unbroadcast_count: Option<usize>,
1092 #[serde(rename = "fullrbf")]
1094 pub full_rbf: Option<bool>,
1095}
1096
1097#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1098pub struct GetMempoolEntryResult {
1099 #[serde(alias = "size")]
1102 pub vsize: u64,
1103 pub weight: Option<u64>,
1105 pub time: u64,
1107 pub height: u64,
1109 #[serde(rename = "descendantcount")]
1111 pub descendant_count: u64,
1112 #[serde(rename = "descendantsize")]
1114 pub descendant_size: u64,
1115 #[serde(rename = "ancestorcount")]
1117 pub ancestor_count: u64,
1118 #[serde(rename = "ancestorsize")]
1120 pub ancestor_size: u64,
1121 pub wtxid: bitcoin::Txid,
1123 pub fees: GetMempoolEntryResultFees,
1125 pub depends: Vec<bitcoin::Txid>,
1127 #[serde(rename = "spentby")]
1129 pub spent_by: Vec<bitcoin::Txid>,
1130 #[serde(rename = "bip125-replaceable")]
1132 pub bip125_replaceable: bool,
1133 pub unbroadcast: Option<bool>,
1136}
1137
1138#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1139pub struct GetMempoolEntryResultFees {
1140 #[serde(with = "bitcoin::amount::serde::as_btc")]
1142 pub base: Amount,
1143 #[serde(with = "bitcoin::amount::serde::as_btc")]
1145 pub modified: Amount,
1146 #[serde(with = "bitcoin::amount::serde::as_btc")]
1148 pub ancestor: Amount,
1149 #[serde(with = "bitcoin::amount::serde::as_btc")]
1151 pub descendant: Amount,
1152}
1153
1154impl<'a> serde::Serialize for ImportMultiRequestScriptPubkey<'a> {
1155 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1156 where
1157 S: serde::Serializer,
1158 {
1159 match *self {
1160 ImportMultiRequestScriptPubkey::Address(ref addr) => {
1161 #[derive(Serialize)]
1162 struct Tmp<'a> {
1163 pub address: &'a Address,
1164 }
1165 serde::Serialize::serialize(
1166 &Tmp {
1167 address: addr,
1168 },
1169 serializer,
1170 )
1171 }
1172 ImportMultiRequestScriptPubkey::Script(script) => {
1173 serializer.serialize_str(&script.to_hex_string())
1174 }
1175 }
1176 }
1177}
1178
1179#[derive(Clone, PartialEq, Eq, Debug, Default, Serialize)]
1183pub struct ImportMultiRequest<'a> {
1184 pub timestamp: Timestamp,
1185 #[serde(rename = "desc", skip_serializing_if = "Option::is_none")]
1187 pub descriptor: Option<&'a str>,
1188 #[serde(rename = "scriptPubKey", skip_serializing_if = "Option::is_none")]
1189 pub script_pubkey: Option<ImportMultiRequestScriptPubkey<'a>>,
1190 #[serde(rename = "redeemscript", skip_serializing_if = "Option::is_none")]
1191 pub redeem_script: Option<&'a Script>,
1192 #[serde(rename = "witnessscript", skip_serializing_if = "Option::is_none")]
1193 pub witness_script: Option<&'a Script>,
1194 #[serde(skip_serializing_if = "<[_]>::is_empty")]
1195 pub pubkeys: &'a [PublicKey],
1196 #[serde(skip_serializing_if = "<[_]>::is_empty")]
1197 pub keys: &'a [PrivateKey],
1198 #[serde(skip_serializing_if = "Option::is_none")]
1199 pub range: Option<(usize, usize)>,
1200 #[serde(skip_serializing_if = "Option::is_none")]
1201 pub internal: Option<bool>,
1202 #[serde(skip_serializing_if = "Option::is_none")]
1203 pub watchonly: Option<bool>,
1204 #[serde(skip_serializing_if = "Option::is_none")]
1205 pub label: Option<&'a str>,
1206 #[serde(skip_serializing_if = "Option::is_none")]
1207 pub keypool: Option<bool>,
1208}
1209
1210#[derive(Clone, PartialEq, Eq, Debug, Default, Deserialize, Serialize)]
1211pub struct ImportMultiOptions {
1212 #[serde(skip_serializing_if = "Option::is_none")]
1213 pub rescan: Option<bool>,
1214}
1215
1216#[derive(Clone, PartialEq, Eq, Copy, Debug)]
1217pub enum Timestamp {
1218 Now,
1219 Time(u64),
1220}
1221
1222impl serde::Serialize for Timestamp {
1223 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1224 where
1225 S: serde::Serializer,
1226 {
1227 match *self {
1228 Timestamp::Now => serializer.serialize_str("now"),
1229 Timestamp::Time(timestamp) => serializer.serialize_u64(timestamp),
1230 }
1231 }
1232}
1233
1234impl<'de> serde::Deserialize<'de> for Timestamp {
1235 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1236 where
1237 D: serde::Deserializer<'de>,
1238 {
1239 use serde::de;
1240 struct Visitor;
1241 impl<'de> de::Visitor<'de> for Visitor {
1242 type Value = Timestamp;
1243
1244 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
1245 write!(formatter, "unix timestamp or 'now'")
1246 }
1247
1248 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
1249 where
1250 E: de::Error,
1251 {
1252 Ok(Timestamp::Time(value))
1253 }
1254
1255 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
1256 where
1257 E: de::Error,
1258 {
1259 if value == "now" {
1260 Ok(Timestamp::Now)
1261 } else {
1262 Err(de::Error::custom(format!(
1263 "invalid str '{}', expecting 'now' or unix timestamp",
1264 value
1265 )))
1266 }
1267 }
1268 }
1269 deserializer.deserialize_any(Visitor)
1270 }
1271}
1272
1273impl Default for Timestamp {
1274 fn default() -> Self {
1275 Timestamp::Time(0)
1276 }
1277}
1278
1279impl From<u64> for Timestamp {
1280 fn from(t: u64) -> Self {
1281 Timestamp::Time(t)
1282 }
1283}
1284
1285impl From<Option<u64>> for Timestamp {
1286 fn from(timestamp: Option<u64>) -> Self {
1287 timestamp.map_or(Timestamp::Now, Timestamp::Time)
1288 }
1289}
1290
1291#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1292pub struct ImportMultiResultError {
1293 pub code: i64,
1294 pub message: String,
1295}
1296
1297#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1298pub struct ImportMultiResult {
1299 pub success: bool,
1300 #[serde(default)]
1301 pub warnings: Vec<String>,
1302 pub error: Option<ImportMultiResultError>,
1303}
1304
1305#[derive(Clone, PartialEq, Eq, Debug, Default, Deserialize, Serialize)]
1307pub struct ImportDescriptors {
1308 #[serde(rename = "desc")]
1309 pub descriptor: String,
1310 pub timestamp: Timestamp,
1311 #[serde(skip_serializing_if = "Option::is_none")]
1312 pub active: Option<bool>,
1313 #[serde(skip_serializing_if = "Option::is_none")]
1314 pub range: Option<(usize, usize)>,
1315 #[serde(skip_serializing_if = "Option::is_none")]
1316 pub next_index: Option<usize>,
1317 #[serde(skip_serializing_if = "Option::is_none")]
1318 pub internal: Option<bool>,
1319 #[serde(skip_serializing_if = "Option::is_none")]
1320 pub label: Option<String>,
1321}
1322
1323#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1325pub struct RejectStatus {
1326 pub status: bool,
1328}
1329
1330#[derive(Clone, Debug, Deserialize, Serialize)]
1332pub struct GetPeerInfoResult {
1333 pub id: u64,
1335 pub addr: String,
1338 pub addrbind: String,
1341 pub addrlocal: Option<String>,
1344 pub network: Option<GetPeerInfoResultNetwork>,
1347 pub services: String,
1350 pub relaytxes: bool,
1352 pub lastsend: u64,
1354 pub lastrecv: u64,
1356 pub last_transaction: Option<u64>,
1359 pub last_block: Option<u64>,
1362 pub bytessent: u64,
1364 pub bytesrecv: u64,
1366 pub conntime: u64,
1368 pub timeoffset: i64,
1370 pub pingtime: Option<f64>,
1372 pub minping: Option<f64>,
1374 pub pingwait: Option<f64>,
1376 pub version: u64,
1378 pub subver: String,
1380 pub inbound: bool,
1382 pub addnode: Option<bool>,
1386 pub startingheight: i64,
1388 pub banscore: Option<i64>,
1391 pub synced_headers: i64,
1393 pub synced_blocks: i64,
1395 pub inflight: Vec<u64>,
1397 pub whitelisted: Option<bool>,
1400 #[serde(rename = "minfeefilter", default, with = "bitcoin::amount::serde::as_btc::opt")]
1401 pub min_fee_filter: Option<Amount>,
1402 pub bytessent_per_msg: HashMap<String, u64>,
1404 pub bytesrecv_per_msg: HashMap<String, u64>,
1406 pub connection_type: Option<GetPeerInfoResultConnectionType>,
1409}
1410
1411#[derive(Copy, Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
1412#[serde(rename_all = "snake_case")]
1413pub enum GetPeerInfoResultNetwork {
1414 Ipv4,
1415 Ipv6,
1416 Onion,
1417 #[deprecated]
1418 Unroutable,
1419 NotPubliclyRoutable,
1420 I2p,
1421 Cjdns,
1422 Internal,
1423}
1424
1425#[derive(Copy, Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
1426#[serde(rename_all = "kebab-case")]
1427pub enum GetPeerInfoResultConnectionType {
1428 OutboundFullRelay,
1429 BlockRelayOnly,
1430 Inbound,
1431 Manual,
1432 AddrFetch,
1433 Feeler,
1434}
1435
1436#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1437pub struct GetAddedNodeInfoResult {
1438 #[serde(rename = "addednode")]
1440 pub added_node: String,
1441 pub connected: bool,
1443 pub addresses: Vec<GetAddedNodeInfoResultAddress>,
1445}
1446
1447#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1448pub struct GetAddedNodeInfoResultAddress {
1449 pub address: String,
1451 pub connected: GetAddedNodeInfoResultAddressType,
1453}
1454
1455#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1456#[serde(rename_all = "lowercase")]
1457pub enum GetAddedNodeInfoResultAddressType {
1458 Inbound,
1459 Outbound,
1460}
1461
1462#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1463pub struct GetNodeAddressesResult {
1464 pub time: u64,
1466 pub services: usize,
1468 pub address: String,
1470 pub port: u16,
1472}
1473
1474#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1475pub struct ListBannedResult {
1476 pub address: String,
1477 pub banned_until: u64,
1478 pub ban_created: u64,
1479}
1480
1481#[derive(Clone, Debug, Deserialize, Serialize)]
1483pub struct EstimateSmartFeeResult {
1484 #[serde(
1486 default,
1487 rename = "feerate",
1488 skip_serializing_if = "Option::is_none",
1489 with = "bitcoin::amount::serde::as_btc::opt"
1490 )]
1491 pub fee_rate: Option<Amount>,
1492 pub errors: Option<Vec<String>>,
1494 pub blocks: i64,
1496}
1497
1498#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1500pub struct BlockRef {
1501 pub hash: bitcoin::BlockHash,
1502 pub height: u64,
1503}
1504
1505#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1507pub struct GetDescriptorInfoResult {
1508 pub descriptor: String,
1509 pub checksum: Option<String>,
1510 #[serde(rename = "isrange")]
1511 pub is_range: bool,
1512 #[serde(rename = "issolvable")]
1513 pub is_solvable: bool,
1514 #[serde(rename = "hasprivatekeys")]
1515 pub has_private_keys: bool,
1516}
1517
1518#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1520pub struct GetBlockTemplateOptions {
1521 pub mode: GetBlockTemplateModes,
1522 pub rules: Vec<GetBlockTemplateRules>,
1524 pub capabilities: Vec<GetBlockTemplateCapabilities>,
1526}
1527
1528#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1530#[serde(rename_all = "lowercase")]
1531pub enum GetBlockTemplateCapabilities {
1532 }
1534
1535#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1538#[serde(rename_all = "lowercase")]
1539pub enum GetBlockTemplateRules {
1540 SegWit,
1541 Signet,
1542 Csv,
1543 Taproot,
1544}
1545
1546#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1548#[serde(rename_all = "lowercase")]
1549pub enum GetBlockTemplateModes {
1550 Template,
1553 }
1556
1557#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1559pub struct GetBlockTemplateResult {
1560 #[serde(with = "crate::serde_hex")]
1562 pub bits: Vec<u8>,
1563 #[serde(rename = "previousblockhash")]
1565 pub previous_block_hash: bitcoin::BlockHash,
1566 #[serde(rename = "curtime")]
1570 pub current_time: u64,
1571 pub height: u64,
1573 #[serde(rename = "sigoplimit")]
1575 pub sigop_limit: u32,
1576 #[serde(rename = "sizelimit")]
1578 pub size_limit: u32,
1579 #[serde(rename = "weightlimit")]
1581 pub weight_limit: u32,
1582 pub version: u32,
1584 pub rules: Vec<GetBlockTemplateResultRules>,
1586 pub capabilities: Vec<GetBlockTemplateResultCapabilities>,
1588 #[serde(rename = "vbavailable")]
1590 pub version_bits_available: HashMap<String, u32>,
1591 #[serde(rename = "vbrequired")]
1593 pub version_bits_required: u32,
1594 pub longpollid: String,
1596 pub transactions: Vec<GetBlockTemplateResultTransaction>,
1598 #[serde(default, with = "bitcoin::script::ScriptBuf")]
1600 pub signet_challenge: bitcoin::script::ScriptBuf,
1601 #[serde(with = "bitcoin::script::ScriptBuf", default)]
1605 pub default_witness_commitment: bitcoin::script::ScriptBuf,
1606 pub coinbaseaux: HashMap<String, String>,
1613 #[serde(rename = "coinbasevalue", with = "bitcoin::amount::serde::as_sat", default)]
1615 pub coinbase_value: Amount,
1616 #[serde(with = "crate::serde_hex")]
1618 pub target: Vec<u8>,
1619 #[serde(rename = "mintime")]
1622 pub min_time: u64,
1623 pub mutable: Vec<GetBlockTemplateResulMutations>,
1626 #[serde(with = "crate::serde_hex", rename = "noncerange")]
1628 pub nonce_range: Vec<u8>,
1629}
1630
1631#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1633pub struct GetBlockTemplateResultTransaction {
1634 pub txid: bitcoin::Txid,
1636 #[serde(rename = "hash")]
1638 pub wtxid: bitcoin::Wtxid,
1639 #[serde(with = "crate::serde_hex", rename = "data")]
1641 pub raw_tx: Vec<u8>,
1642 #[serde(with = "bitcoin::amount::serde::as_sat")]
1644 pub fee: Amount,
1645 pub sigops: u32,
1647 pub weight: usize,
1649 pub depends: Vec<u32>,
1653}
1654
1655impl GetBlockTemplateResultTransaction {
1656 pub fn transaction(&self) -> Result<Transaction, encode::Error> {
1657 encode::deserialize(&self.raw_tx)
1658 }
1659}
1660
1661#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1663#[serde(rename_all = "lowercase")]
1664pub enum GetBlockTemplateResultCapabilities {
1665 Proposal,
1666}
1667
1668#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1671#[serde(rename_all = "lowercase")]
1672pub enum GetBlockTemplateResultRules {
1673 #[serde(alias = "!segwit")]
1676 SegWit,
1677 #[serde(alias = "!signet")]
1680 Signet,
1681 Csv,
1684 Taproot,
1687 Testdummy,
1690}
1691
1692#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1697#[serde(rename_all = "lowercase")]
1698pub enum GetBlockTemplateResulMutations {
1699 Time,
1701 Transactions,
1703 #[serde(rename = "prevblock")]
1707 PreviousBlock,
1708}
1709
1710#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1712pub struct WalletCreateFundedPsbtResult {
1713 pub psbt: String,
1714 #[serde(with = "bitcoin::amount::serde::as_btc")]
1715 pub fee: Amount,
1716 #[serde(rename = "changepos")]
1717 pub change_position: i32,
1718}
1719
1720#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1722pub struct WalletProcessPsbtResult {
1723 pub psbt: String,
1724 pub complete: bool,
1725}
1726
1727#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize, Default)]
1729pub struct WalletCreateFundedPsbtOptions {
1730 #[serde(skip_serializing_if = "Option::is_none")]
1733 pub add_inputs: Option<bool>,
1734 #[serde(rename = "changeAddress", skip_serializing_if = "Option::is_none")]
1735 pub change_address: Option<Address<NetworkUnchecked>>,
1736 #[serde(rename = "changePosition", skip_serializing_if = "Option::is_none")]
1737 pub change_position: Option<u16>,
1738 #[serde(skip_serializing_if = "Option::is_none")]
1739 pub change_type: Option<AddressType>,
1740 #[serde(rename = "includeWatching", skip_serializing_if = "Option::is_none")]
1741 pub include_watching: Option<bool>,
1742 #[serde(rename = "lockUnspents", skip_serializing_if = "Option::is_none")]
1743 pub lock_unspent: Option<bool>,
1744 #[serde(
1745 rename = "feeRate",
1746 skip_serializing_if = "Option::is_none",
1747 with = "bitcoin::amount::serde::as_btc::opt"
1748 )]
1749 pub fee_rate: Option<Amount>,
1750 #[serde(rename = "subtractFeeFromOutputs", skip_serializing_if = "Vec::is_empty")]
1751 pub subtract_fee_from_outputs: Vec<u16>,
1752 #[serde(skip_serializing_if = "Option::is_none")]
1753 pub replaceable: Option<bool>,
1754 #[serde(skip_serializing_if = "Option::is_none")]
1755 pub conf_target: Option<u16>,
1756 #[serde(skip_serializing_if = "Option::is_none")]
1757 pub estimate_mode: Option<EstimateMode>,
1758}
1759
1760#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1762pub struct FinalizePsbtResult {
1763 pub psbt: Option<String>,
1764 #[serde(default, with = "crate::serde_hex::opt")]
1765 pub hex: Option<Vec<u8>>,
1766 pub complete: bool,
1767}
1768
1769#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1771pub struct DecodeRawTransactionResult {
1772 pub txid: bitcoin::Txid,
1773 pub hash: bitcoin::Wtxid,
1774 pub size: u32,
1775 pub vsize: u32,
1776 pub weight: u32,
1777 pub version: u32,
1778 pub locktime: u32,
1779 pub vin: Vec<GetRawTransactionResultVin>,
1780 pub vout: Vec<GetRawTransactionResultVout>,
1781}
1782
1783pub type GetChainTipsResult = Vec<GetChainTipsResultTip>;
1785
1786#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1788pub struct GetChainTipsResultTip {
1789 pub height: u64,
1791 pub hash: bitcoin::BlockHash,
1793 #[serde(rename = "branchlen")]
1795 pub branch_length: usize,
1796 pub status: GetChainTipsResultStatus,
1798}
1799
1800#[derive(Copy, Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
1801#[serde(rename_all = "lowercase")]
1802pub enum GetChainTipsResultStatus {
1803 Invalid,
1805 #[serde(rename = "headers-only")]
1807 HeadersOnly,
1808 #[serde(rename = "valid-headers")]
1810 ValidHeaders,
1811 #[serde(rename = "valid-fork")]
1813 ValidFork,
1814 Active,
1816}
1817
1818impl FinalizePsbtResult {
1819 pub fn transaction(&self) -> Option<Result<Transaction, encode::Error>> {
1820 self.hex.as_ref().map(|h| encode::deserialize(h))
1821 }
1822}
1823
1824#[derive(Serialize, Deserialize, Debug, Clone, Copy, Eq, PartialEq, Hash)]
1827#[serde(rename_all = "UPPERCASE")]
1828pub enum EstimateMode {
1829 Unset,
1830 Economical,
1831 Conservative,
1832}
1833
1834pub struct SigHashType(bitcoin::sighash::EcdsaSighashType);
1837
1838impl From<bitcoin::sighash::EcdsaSighashType> for SigHashType {
1839 fn from(sht: bitcoin::sighash::EcdsaSighashType) -> SigHashType {
1840 SigHashType(sht)
1841 }
1842}
1843
1844impl serde::Serialize for SigHashType {
1845 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1846 where
1847 S: serde::Serializer,
1848 {
1849 serializer.serialize_str(match self.0 {
1850 bitcoin::sighash::EcdsaSighashType::All => "ALL",
1851 bitcoin::sighash::EcdsaSighashType::None => "NONE",
1852 bitcoin::sighash::EcdsaSighashType::Single => "SINGLE",
1853 bitcoin::sighash::EcdsaSighashType::AllPlusAnyoneCanPay => "ALL|ANYONECANPAY",
1854 bitcoin::sighash::EcdsaSighashType::NonePlusAnyoneCanPay => "NONE|ANYONECANPAY",
1855 bitcoin::sighash::EcdsaSighashType::SinglePlusAnyoneCanPay => "SINGLE|ANYONECANPAY",
1856 })
1857 }
1858}
1859
1860#[derive(Serialize, Clone, PartialEq, Eq, Debug, Deserialize)]
1862#[serde(rename_all = "camelCase")]
1863pub struct CreateRawTransactionInput {
1864 pub txid: bitcoin::Txid,
1865 pub vout: u32,
1866 #[serde(skip_serializing_if = "Option::is_none")]
1867 pub sequence: Option<u32>,
1868}
1869
1870#[derive(Serialize, Clone, PartialEq, Eq, Debug, Default)]
1871#[serde(rename_all = "camelCase")]
1872pub struct FundRawTransactionOptions {
1873 #[serde(rename = "add_inputs", skip_serializing_if = "Option::is_none")]
1876 pub add_inputs: Option<bool>,
1877 #[serde(skip_serializing_if = "Option::is_none")]
1878 pub change_address: Option<Address>,
1879 #[serde(skip_serializing_if = "Option::is_none")]
1880 pub change_position: Option<u32>,
1881 #[serde(rename = "change_type", skip_serializing_if = "Option::is_none")]
1882 pub change_type: Option<AddressType>,
1883 #[serde(skip_serializing_if = "Option::is_none")]
1884 pub include_watching: Option<bool>,
1885 #[serde(skip_serializing_if = "Option::is_none")]
1886 pub lock_unspents: Option<bool>,
1887 #[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, Serialize)]
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, Serialize)]
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, Serialize)]
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, Deserialize)]
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, Deserialize)]
1955#[serde(rename_all = "snake_case")]
1956pub enum TxOutSetHashType {
1957 HashSerialized2,
1958 Muhash,
1959 None,
1960}
1961
1962#[derive(Clone, Serialize, PartialEq, Eq, Debug, Deserialize)]
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
2150#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
2151pub struct GetZmqNotificationsResult {
2152 #[serde(rename = "type")]
2153 pub notification_type: String,
2154 pub address: String,
2155 pub hwm: u64,
2156}
2157
2158impl<'a> serde::Serialize for PubKeyOrAddress<'a> {
2159 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
2160 where
2161 S: serde::Serializer,
2162 {
2163 match *self {
2164 PubKeyOrAddress::Address(a) => serde::Serialize::serialize(a, serializer),
2165 PubKeyOrAddress::PubKey(k) => serde::Serialize::serialize(k, serializer),
2166 }
2167 }
2168}
2169
2170fn deserialize_hex_array_opt<'de, D>(deserializer: D) -> Result<Option<Vec<Vec<u8>>>, D::Error>
2174where
2175 D: serde::Deserializer<'de>,
2176{
2177 let v: Vec<String> = Vec::deserialize(deserializer)?;
2181 let mut res = Vec::new();
2182 for h in v.into_iter() {
2183 res.push(FromHex::from_hex(&h).map_err(D::Error::custom)?);
2184 }
2185 Ok(Some(res))
2186}
2187
2188fn deserialize_bip70_network<'de, D>(deserializer: D) -> Result<Network, D::Error>
2191where
2192 D: serde::Deserializer<'de>,
2193{
2194 struct NetworkVisitor;
2195 impl<'de> serde::de::Visitor<'de> for NetworkVisitor {
2196 type Value = Network;
2197
2198 fn visit_str<E: serde::de::Error>(self, s: &str) -> Result<Self::Value, E> {
2199 Network::from_core_arg(s).map_err(|_| {
2200 E::invalid_value(
2201 serde::de::Unexpected::Str(s),
2202 &"bitcoin network encoded as a string",
2203 )
2204 })
2205 }
2206
2207 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
2208 write!(formatter, "bitcoin network encoded as a string")
2209 }
2210 }
2211
2212 deserializer.deserialize_str(NetworkVisitor)
2213}
2214
2215#[cfg(test)]
2216mod tests {
2217 use super::*;
2218
2219 #[test]
2220 fn test_softfork_type() {
2221 let buried: SoftforkType = serde_json::from_str("\"buried\"").unwrap();
2222 assert_eq!(buried, SoftforkType::Buried);
2223 let bip9: SoftforkType = serde_json::from_str("\"bip9\"").unwrap();
2224 assert_eq!(bip9, SoftforkType::Bip9);
2225 let other: SoftforkType = serde_json::from_str("\"bip8\"").unwrap();
2226 assert_eq!(other, SoftforkType::Other);
2227 }
2228}