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