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