1use std::collections::HashMap;
18pub use bitcoin;
19
20use bitcoin::consensus::encode;
21use bitcoin::hashes::hex::{FromHex, ToHex};
22use bitcoin::hashes::sha256;
23use bitcoin::util::{bip158, bip32};
24use bitcoin::{Address, Amount, PrivateKey, PublicKey, Script, SignedAmount, Transaction};
25use serde::de::Error as SerdeError;
26use serde::{Deserialize, Serialize};
27
28pub mod serde_hex {
34 use bitcoin::hashes::hex::{FromHex, ToHex};
35 use serde::de::Error;
36 use serde::{Deserializer, Serializer};
37
38 pub fn serialize<S: Serializer>(b: &Vec<u8>, s: S) -> Result<S::Ok, S::Error> {
39 s.serialize_str(&b.to_hex())
40 }
41
42 pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result<Vec<u8>, D::Error> {
43 let hex_str: String = ::serde::Deserialize::deserialize(d)?;
44 Ok(FromHex::from_hex(&hex_str).map_err(D::Error::custom)?)
45 }
46
47 pub mod opt {
48 use bitcoin::hashes::hex::{FromHex, ToHex};
49 use serde::de::Error;
50 use serde::{Deserializer, Serializer};
51
52 pub fn serialize<S: Serializer>(b: &Option<Vec<u8>>, s: S) -> Result<S::Ok, S::Error> {
53 match *b {
54 None => s.serialize_none(),
55 Some(ref b) => s.serialize_str(&b.to_hex()),
56 }
57 }
58
59 pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result<Option<Vec<u8>>, D::Error> {
60 let hex_str: String = ::serde::Deserialize::deserialize(d)?;
61 Ok(Some(FromHex::from_hex(&hex_str).map_err(D::Error::custom)?))
62 }
63 }
64}
65
66#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
67pub struct GetNetworkInfoResultNetwork {
68 pub name: String,
69 pub limited: bool,
70 pub reachable: bool,
71 pub proxy: String,
72 pub proxy_randomize_credentials: bool,
73}
74
75#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
76pub struct GetNetworkInfoResultAddress {
77 pub address: String,
78 pub port: usize,
79 pub score: usize,
80}
81
82#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
83pub struct GetNetworkInfoResult {
84 pub version: usize,
85 pub subversion: String,
86 #[serde(rename = "protocolversion")]
87 pub protocol_version: usize,
88 #[serde(rename = "localservices")]
89 pub local_services: String,
90 #[serde(rename = "localrelay")]
91 pub local_relay: bool,
92 #[serde(rename = "timeoffset")]
93 pub time_offset: isize,
94 pub connections: usize,
95 #[serde(rename = "networkactive")]
96 pub network_active: bool,
97 pub networks: Vec<GetNetworkInfoResultNetwork>,
98 #[serde(rename = "relayfee", with = "bitcoin::util::amount::serde::as_btc")]
99 pub relay_fee: Amount,
100 #[serde(rename = "incrementalfee", with = "bitcoin::util::amount::serde::as_btc")]
101 pub incremental_fee: Amount,
102 #[serde(rename = "localaddresses")]
103 pub local_addresses: Vec<GetNetworkInfoResultAddress>,
104 pub warnings: String,
105}
106
107#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
108#[serde(rename_all = "camelCase")]
109pub struct AddMultiSigAddressResult {
110 pub address: Address,
111 pub redeem_script: Script,
112}
113
114#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
115pub struct LoadWalletResult {
116 pub name: String,
117 pub warning: Option<String>,
118}
119
120#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
121pub struct GetWalletInfoResult {
122 #[serde(rename = "walletname")]
123 pub wallet_name: String,
124 #[serde(rename = "walletversion")]
125 pub wallet_version: u32,
126 #[serde(with = "bitcoin::util::amount::serde::as_btc")]
127 pub balance: Amount,
128 #[serde(with = "bitcoin::util::amount::serde::as_btc")]
129 pub unconfirmed_balance: Amount,
130 #[serde(with = "bitcoin::util::amount::serde::as_btc")]
131 pub immature_balance: Amount,
132 #[serde(rename = "txcount")]
133 pub tx_count: usize,
134 #[serde(rename = "keypoololdest")]
135 pub keypool_oldest: usize,
136 #[serde(rename = "keypoolsize")]
137 pub keypool_size: usize,
138 #[serde(rename = "keypoolsize_hd_internal")]
139 pub keypool_size_hd_internal: usize,
140 pub unlocked_until: Option<u64>,
141 #[serde(rename = "paytxfee", with = "bitcoin::util::amount::serde::as_btc")]
142 pub pay_tx_fee: Amount,
143 #[serde(rename = "hdseedid")]
144 pub hd_seed_id: Option<bitcoin::XpubIdentifier>,
145 pub private_keys_enabled: bool,
146 pub avoid_reuse: Option<bool>,
147 pub scanning: Option<ScanningDetails>,
148}
149
150#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
151#[serde(untagged)]
152pub enum ScanningDetails {
153 Scanning {
154 duration: usize,
155 progress: f32,
156 },
157 NotScanning(bool),
159}
160
161impl Eq for ScanningDetails {}
162
163#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
164#[serde(rename_all = "camelCase")]
165pub struct GetBlockResult {
166 pub hash: bitcoin::BlockHash,
167 pub confirmations: u32,
168 pub size: usize,
169 pub strippedsize: Option<usize>,
170 pub weight: usize,
171 pub height: usize,
172 pub version: i32,
173 #[serde(default, with = "serde_hex::opt")]
174 pub version_hex: Option<Vec<u8>>,
175 pub merkleroot: bitcoin::TxMerkleNode,
176 pub tx: Vec<bitcoin::Txid>,
177 pub time: usize,
178 pub mediantime: Option<usize>,
179 pub nonce: u32,
180 pub bits: String,
181 pub difficulty: f64,
182 #[serde(with = "serde_hex")]
183 pub chainwork: Vec<u8>,
184 pub n_tx: usize,
185 pub previousblockhash: Option<bitcoin::BlockHash>,
186 pub nextblockhash: Option<bitcoin::BlockHash>,
187}
188
189#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
190#[serde(rename_all = "camelCase")]
191pub struct GetBlockHeaderResult {
192 pub hash: bitcoin::BlockHash,
193 pub confirmations: u32,
194 pub height: usize,
195 pub version: i32,
196 #[serde(default, with = "serde_hex::opt")]
197 pub version_hex: Option<Vec<u8>>,
198 #[serde(rename = "merkleroot")]
199 pub merkle_root: bitcoin::TxMerkleNode,
200 pub time: usize,
201 #[serde(rename = "mediantime")]
202 pub median_time: Option<usize>,
203 pub nonce: u32,
204 pub bits: String,
205 pub difficulty: f64,
206 #[serde(with = "serde_hex")]
207 pub chainwork: Vec<u8>,
208 pub n_tx: usize,
209 #[serde(rename = "previousblockhash")]
210 pub previous_block_hash: Option<bitcoin::BlockHash>,
211 #[serde(rename = "nextblockhash")]
212 pub next_block_hash: Option<bitcoin::BlockHash>,
213}
214
215#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
216#[serde(rename_all = "camelCase")]
217pub struct GetMiningInfoResult {
218 pub blocks: u32,
219 #[serde(rename = "currentblockweight")]
220 pub current_block_weight: Option<u64>,
221 #[serde(rename = "currentblocktx")]
222 pub current_block_tx: Option<usize>,
223 pub difficulty: f64,
224 #[serde(rename = "networkhashps")]
225 pub network_hash_ps: f64,
226 #[serde(rename = "pooledtx")]
227 pub pooled_tx: usize,
228 pub chain: String,
229 pub warnings: String,
230}
231
232#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
233#[serde(rename_all = "camelCase")]
234pub struct GetRawTransactionResultVinScriptSig {
235 pub asm: String,
236 #[serde(with = "serde_hex")]
237 pub hex: Vec<u8>,
238}
239
240impl GetRawTransactionResultVinScriptSig {
241 pub fn script(&self) -> Result<Script, encode::Error> {
242 Ok(Script::from(self.hex.clone()))
243 }
244}
245
246#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
247#[serde(rename_all = "camelCase")]
248pub struct GetRawTransactionResultVin {
249 pub sequence: u32,
250 #[serde(default, with = "serde_hex::opt")]
252 pub coinbase: Option<Vec<u8>>,
253 pub txid: Option<bitcoin::Txid>,
255 pub vout: Option<u32>,
257 pub script_sig: Option<GetRawTransactionResultVinScriptSig>,
259 #[serde(default, deserialize_with = "deserialize_hex_array_opt")]
261 pub txinwitness: Option<Vec<Vec<u8>>>,
262}
263
264impl GetRawTransactionResultVin {
265 pub fn is_coinbase(&self) -> bool {
269 self.coinbase.is_some()
270 }
271}
272
273#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
274#[serde(rename_all = "camelCase")]
275pub struct GetRawTransactionResultVoutScriptPubKey {
276 pub asm: String,
277 #[serde(with = "serde_hex")]
278 pub hex: Vec<u8>,
279 pub req_sigs: Option<usize>,
280 #[serde(rename = "type")]
281 pub type_: Option<ScriptPubkeyType>,
282 pub addresses: Option<Vec<Address>>,
283}
284
285impl GetRawTransactionResultVoutScriptPubKey {
286 pub fn script(&self) -> Result<Script, encode::Error> {
287 Ok(Script::from(self.hex.clone()))
288 }
289}
290
291#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
292#[serde(rename_all = "camelCase")]
293pub struct GetRawTransactionResultVout {
294 #[serde(with = "bitcoin::util::amount::serde::as_btc")]
295 pub value: Amount,
296 pub n: u32,
297 pub script_pub_key: GetRawTransactionResultVoutScriptPubKey,
298}
299
300#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
301#[serde(rename_all = "camelCase")]
302pub struct GetRawTransactionResult {
303 #[serde(rename = "in_active_chain")]
304 pub in_active_chain: Option<bool>,
305 #[serde(with = "serde_hex")]
306 pub hex: Vec<u8>,
307 pub txid: bitcoin::Txid,
308 pub hash: bitcoin::Wtxid,
309 pub size: usize,
310 pub vsize: usize,
311 pub version: u32,
312 pub locktime: u32,
313 pub vin: Vec<GetRawTransactionResultVin>,
314 pub vout: Vec<GetRawTransactionResultVout>,
315 pub blockhash: Option<bitcoin::BlockHash>,
316 pub confirmations: Option<u32>,
317 pub time: Option<usize>,
318 pub blocktime: Option<usize>,
319}
320
321#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
322pub struct GetBlockFilterResult {
323 pub header: bitcoin::FilterHash,
324 #[serde(with = "serde_hex")]
325 pub filter: Vec<u8>,
326}
327
328impl GetBlockFilterResult {
329 pub fn to_filter(&self) -> bip158::BlockFilter {
333 bip158::BlockFilter::new(&self.filter)
334 }
335
336 pub fn into_filter(self) -> bip158::BlockFilter {
338 bip158::BlockFilter {
339 content: self.filter,
340 }
341 }
342}
343
344impl GetRawTransactionResult {
345 pub fn is_coinbase(&self) -> bool {
347 self.vin.len() == 1 && self.vin[0].is_coinbase()
348 }
349
350 pub fn transaction(&self) -> Result<Transaction, encode::Error> {
351 Ok(encode::deserialize(&self.hex)?)
352 }
353}
354
355#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
357#[serde(rename_all = "lowercase")]
358pub enum Bip125Replaceable {
359 Yes,
360 No,
361 Unknown,
362}
363
364#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
366#[serde(rename_all = "lowercase")]
367pub enum GetTransactionResultDetailCategory {
368 Send,
369 Receive,
370 Generate,
371 Immature,
372 Orphan,
373}
374
375#[derive(Clone, PartialEq, Eq, Debug, Deserialize)]
376pub struct GetTransactionResultDetail {
377 pub address: Option<Address>,
378 pub category: GetTransactionResultDetailCategory,
379 #[serde(with = "bitcoin::util::amount::serde::as_btc")]
380 pub amount: SignedAmount,
381 pub label: Option<String>,
382 pub vout: u32,
383 #[serde(default, with = "bitcoin::util::amount::serde::as_btc::opt")]
384 pub fee: Option<SignedAmount>,
385 pub abandoned: Option<bool>,
386}
387
388#[derive(Clone, PartialEq, Eq, Debug, Deserialize)]
389pub struct WalletTxInfo {
390 pub confirmations: i32,
391 pub blockhash: Option<bitcoin::BlockHash>,
392 pub blockindex: Option<usize>,
393 pub blocktime: Option<u64>,
394 pub blockheight: Option<u32>,
395 pub txid: bitcoin::Txid,
396 pub time: u64,
397 pub timereceived: u64,
398 #[serde(rename = "bip125-replaceable")]
399 pub bip125_replaceable: Bip125Replaceable,
400}
401
402#[derive(Clone, PartialEq, Eq, Debug, Deserialize)]
403pub struct GetTransactionResult {
404 #[serde(flatten)]
405 pub info: WalletTxInfo,
406 #[serde(with = "bitcoin::util::amount::serde::as_btc")]
407 pub amount: SignedAmount,
408 #[serde(default, with = "bitcoin::util::amount::serde::as_btc::opt")]
409 pub fee: Option<SignedAmount>,
410 pub details: Vec<GetTransactionResultDetail>,
411 #[serde(with = "serde_hex")]
412 pub hex: Vec<u8>,
413}
414
415impl GetTransactionResult {
416 pub fn transaction(&self) -> Result<Transaction, encode::Error> {
417 Ok(encode::deserialize(&self.hex)?)
418 }
419}
420
421#[derive(Clone, PartialEq, Eq, Debug, Deserialize)]
422pub struct ListTransactionResult {
423 #[serde(flatten)]
424 pub info: WalletTxInfo,
425 #[serde(flatten)]
426 pub detail: GetTransactionResultDetail,
427
428 pub trusted: Option<bool>,
429 pub comment: Option<String>,
430}
431
432#[derive(Clone, PartialEq, Eq, Debug, Deserialize)]
433pub struct ListSinceBlockResult {
434 pub transactions: Vec<ListTransactionResult>,
435 #[serde(default)]
436 pub removed: Vec<ListTransactionResult>,
437 pub lastblock: bitcoin::BlockHash,
438}
439
440#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
441#[serde(rename_all = "camelCase")]
442pub struct GetTxOutResult {
443 pub bestblock: bitcoin::BlockHash,
444 pub confirmations: u32,
445 #[serde(with = "bitcoin::util::amount::serde::as_btc")]
446 pub value: Amount,
447 pub script_pub_key: GetRawTransactionResultVoutScriptPubKey,
448 pub coinbase: bool,
449}
450
451#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize, Default)]
452#[serde(rename_all = "camelCase")]
453pub struct ListUnspentQueryOptions {
454 #[serde(
455 rename = "minimumAmount",
456 with = "bitcoin::util::amount::serde::as_btc::opt",
457 skip_serializing_if = "Option::is_none"
458 )]
459 pub minimum_amount: Option<Amount>,
460 #[serde(
461 rename = "maximumAmount",
462 with = "bitcoin::util::amount::serde::as_btc::opt",
463 skip_serializing_if = "Option::is_none"
464 )]
465 pub maximum_amount: Option<Amount>,
466 #[serde(rename = "maximumCount", skip_serializing_if = "Option::is_none")]
467 pub maximum_count: Option<usize>,
468 #[serde(
469 rename = "minimumSumAmount",
470 with = "bitcoin::util::amount::serde::as_btc::opt",
471 skip_serializing_if = "Option::is_none"
472 )]
473 pub minimum_sum_amount: Option<Amount>,
474}
475
476#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
477#[serde(rename_all = "camelCase")]
478pub struct ListUnspentResultEntry {
479 pub txid: bitcoin::Txid,
480 pub vout: u32,
481 pub address: Option<Address>,
482 pub label: Option<String>,
483 pub redeem_script: Option<Script>,
484 pub witness_script: Option<Script>,
485 pub script_pub_key: Script,
486 #[serde(with = "bitcoin::util::amount::serde::as_btc")]
487 pub amount: Amount,
488 pub confirmations: u32,
489 pub spendable: bool,
490 pub solvable: bool,
491 #[serde(rename = "desc")]
492 pub descriptor: Option<String>,
493 pub safe: bool,
494}
495
496#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
497#[serde(rename_all = "camelCase")]
498pub struct ListReceivedByAddressResult {
499 #[serde(default, rename = "involvesWatchonly")]
500 pub involved_watch_only: bool,
501 pub address: Address,
502 #[serde(with = "bitcoin::util::amount::serde::as_btc")]
503 pub amount: Amount,
504 pub confirmations: u32,
505 pub label: String,
506 pub txids: Vec<bitcoin::Txid>,
507}
508
509#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
510#[serde(rename_all = "camelCase")]
511pub struct SignRawTransactionResultError {
512 pub txid: bitcoin::Txid,
513 pub vout: u32,
514 pub script_sig: Script,
515 pub sequence: u32,
516 pub error: String,
517}
518
519#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
520#[serde(rename_all = "camelCase")]
521pub struct SignRawTransactionResult {
522 #[serde(with = "serde_hex")]
523 pub hex: Vec<u8>,
524 pub complete: bool,
525 pub errors: Option<Vec<SignRawTransactionResultError>>,
526}
527
528impl SignRawTransactionResult {
529 pub fn transaction(&self) -> Result<Transaction, encode::Error> {
530 Ok(encode::deserialize(&self.hex)?)
531 }
532}
533
534#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
535pub struct TestMempoolAcceptResult {
536 pub txid: bitcoin::Txid,
537 pub allowed: bool,
538 #[serde(rename = "reject-reason")]
539 pub reject_reason: Option<String>,
540}
541
542#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
543#[serde(rename_all = "snake_case")]
544pub enum Bip9SoftforkStatus {
545 Defined,
546 Started,
547 LockedIn,
548 Active,
549 Failed,
550}
551
552#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
553pub struct Bip9SoftforkStatistics {
554 pub period: u32,
555 pub threshold: u32,
556 pub elapsed: u32,
557 pub count: u32,
558 pub possible: bool,
559}
560
561#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
562pub struct Bip9SoftforkInfo {
563 pub status: Bip9SoftforkStatus,
564 pub bit: Option<u8>,
565 pub start_time: i64,
567 pub timeout: u64,
568 pub since: u32,
569 pub statistics: Option<Bip9SoftforkStatistics>,
570}
571
572#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
573#[serde(rename_all = "lowercase")]
574pub enum SoftforkType {
575 Buried,
576 Bip9,
577}
578
579#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
581pub struct Softfork {
582 #[serde(rename = "type")]
583 pub type_: SoftforkType,
584 pub bip9: Option<Bip9SoftforkInfo>,
585 pub height: Option<u32>,
586 pub active: bool,
587}
588
589#[allow(non_camel_case_types)]
590#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
591#[serde(rename_all = "lowercase")]
592pub enum ScriptPubkeyType {
593 Nonstandard,
594 Pubkey,
595 PubkeyHash,
596 ScriptHash,
597 MultiSig,
598 NullData,
599 Witness_v0_KeyHash,
600 Witness_v0_ScriptHash,
601 Witness_Unknown,
602}
603
604#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
605pub struct GetAddressInfoResultEmbedded {
606 pub address: Address,
607 #[serde(rename = "scriptPubKey")]
608 pub script_pub_key: Script,
609 #[serde(rename = "is_script")]
610 pub is_script: Option<bool>,
611 #[serde(rename = "is_witness")]
612 pub is_witness: Option<bool>,
613 pub witness_version: Option<u32>,
614 #[serde(with = "serde_hex")]
615 pub witness_program: Vec<u8>,
616 pub script: Option<ScriptPubkeyType>,
617 #[serde(default, with = "serde_hex::opt")]
619 pub hex: Option<Vec<u8>>,
620 pub pubkeys: Option<Vec<PublicKey>>,
621 #[serde(rename = "sigsrequired")]
622 pub n_signatures_required: Option<usize>,
623 pub pubkey: Option<PublicKey>,
624 #[serde(rename = "is_compressed")]
625 pub is_compressed: Option<bool>,
626 pub label: Option<String>,
627 #[serde(rename = "hdkeypath")]
628 pub hd_key_path: Option<bip32::DerivationPath>,
629 #[serde(rename = "hdseedid")]
630 pub hd_seed_id: Option<bitcoin::XpubIdentifier>,
631 #[serde(default)]
632 pub labels: Vec<GetAddressInfoResultLabel>,
633}
634
635#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
636#[serde(rename_all = "lowercase")]
637pub enum GetAddressInfoResultLabelPurpose {
638 Send,
639 Receive,
640}
641
642#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
643#[serde(untagged)]
644pub enum GetAddressInfoResultLabel {
645 Simple(String),
646 WithPurpose {
647 name: String,
648 purpose: GetAddressInfoResultLabelPurpose,
649 },
650}
651
652#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
653pub struct GetAddressInfoResult {
654 pub address: Address,
655 #[serde(rename = "scriptPubKey")]
656 pub script_pub_key: Script,
657 #[serde(rename = "ismine")]
658 pub is_mine: Option<bool>,
659 #[serde(rename = "iswatchonly")]
660 pub is_watchonly: Option<bool>,
661 #[serde(rename = "isscript")]
662 pub is_script: Option<bool>,
663 #[serde(rename = "iswitness")]
664 pub is_witness: Option<bool>,
665 pub witness_version: Option<u32>,
666 #[serde(default, with = "serde_hex::opt")]
667 pub witness_program: Option<Vec<u8>>,
668 pub script: Option<ScriptPubkeyType>,
669 #[serde(default, with = "serde_hex::opt")]
671 pub hex: Option<Vec<u8>>,
672 pub pubkeys: Option<Vec<PublicKey>>,
673 #[serde(rename = "sigsrequired")]
674 pub n_signatures_required: Option<usize>,
675 pub pubkey: Option<PublicKey>,
676 pub embedded: Option<GetAddressInfoResultEmbedded>,
678 #[serde(rename = "is_compressed")]
679 pub is_compressed: Option<bool>,
680 pub timestamp: Option<u64>,
681 #[serde(rename = "hdkeypath")]
682 pub hd_key_path: Option<bip32::DerivationPath>,
683 #[serde(rename = "hdseedid")]
684 pub hd_seed_id: Option<bitcoin::XpubIdentifier>,
685 pub labels: Vec<GetAddressInfoResultLabel>,
686 #[deprecated(note = "since Core v0.20.0")]
688 pub label: Option<String>,
689}
690
691#[derive(Clone, Debug, Deserialize, Serialize)]
693pub struct GetBlockchainInfoResult {
694 pub chain: String,
696 pub blocks: u64,
698 pub headers: u64,
700 #[serde(rename = "bestblockhash")]
702 pub best_block_hash: bitcoin::BlockHash,
703 pub difficulty: f64,
705 #[serde(rename = "mediantime")]
707 pub median_time: u64,
708 #[serde(rename = "verificationprogress")]
710 pub verification_progress: f64,
711 #[serde(rename = "initialblockdownload")]
713 pub initial_block_download: bool,
714 #[serde(rename = "chainwork", with = "serde_hex")]
716 pub chain_work: Vec<u8>,
717 pub size_on_disk: u64,
719 pub pruned: bool,
721 #[serde(rename = "pruneheight")]
723 pub prune_height: Option<u64>,
724 pub automatic_pruning: Option<bool>,
726 pub prune_target_size: Option<u64>,
728 #[serde(default)]
730 pub softforks: HashMap<String, Softfork>,
731 pub warnings: String,
733}
734
735#[derive(Clone, PartialEq, Eq, Debug)]
736pub enum ImportMultiRequestScriptPubkey<'a> {
737 Address(&'a Address),
738 Script(&'a Script),
739}
740
741#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
742pub struct GetMempoolEntryResult {
743 #[serde(alias = "size")]
746 pub vsize: u64,
747 pub weight: Option<u64>,
749 pub time: u64,
751 pub height: u64,
753 #[serde(rename = "descendantcount")]
755 pub descendant_count: u64,
756 #[serde(rename = "descendantsize")]
758 pub descendant_size: u64,
759 #[serde(rename = "ancestorcount")]
761 pub ancestor_count: u64,
762 #[serde(rename = "ancestorsize")]
764 pub ancestor_size: u64,
765 pub wtxid: bitcoin::Txid,
767 pub fees: GetMempoolEntryResultFees,
769 pub depends: Vec<bitcoin::Txid>,
771 #[serde(rename = "spentby")]
773 pub spent_by: Vec<bitcoin::Txid>,
774 #[serde(rename = "bip125-replaceable")]
776 pub bip125_replaceable: bool,
777}
778
779#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
780pub struct GetMempoolEntryResultFees {
781 #[serde(with = "bitcoin::util::amount::serde::as_btc")]
783 pub base: Amount,
784 #[serde(with = "bitcoin::util::amount::serde::as_btc")]
786 pub modified: Amount,
787 #[serde(with = "bitcoin::util::amount::serde::as_btc")]
789 pub ancestor: Amount,
790 #[serde(with = "bitcoin::util::amount::serde::as_btc")]
792 pub descendant: Amount,
793}
794
795impl<'a> serde::Serialize for ImportMultiRequestScriptPubkey<'a> {
796 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
797 where
798 S: serde::Serializer,
799 {
800 match *self {
801 ImportMultiRequestScriptPubkey::Address(ref addr) => {
802 #[derive(Serialize)]
803 struct Tmp<'a> {
804 pub address: &'a Address,
805 };
806 serde::Serialize::serialize(
807 &Tmp {
808 address: addr,
809 },
810 serializer,
811 )
812 }
813 ImportMultiRequestScriptPubkey::Script(script) => {
814 serializer.serialize_str(&script.as_bytes().to_hex())
815 }
816 }
817 }
818}
819
820#[derive(Clone, PartialEq, Eq, Debug, Default, Serialize)]
824pub struct ImportMultiRequest<'a> {
825 pub timestamp: ImportMultiRescanSince,
826 #[serde(rename = "desc", skip_serializing_if = "Option::is_none")]
828 pub descriptor: Option<&'a str>,
829 #[serde(rename = "scriptPubKey", skip_serializing_if = "Option::is_none")]
830 pub script_pubkey: Option<ImportMultiRequestScriptPubkey<'a>>,
831 #[serde(rename = "redeemscript", skip_serializing_if = "Option::is_none")]
832 pub redeem_script: Option<&'a Script>,
833 #[serde(rename = "witnessscript", skip_serializing_if = "Option::is_none")]
834 pub witness_script: Option<&'a Script>,
835 #[serde(skip_serializing_if = "<[_]>::is_empty")]
836 pub pubkeys: &'a [PublicKey],
837 #[serde(skip_serializing_if = "<[_]>::is_empty")]
838 pub keys: &'a [PrivateKey],
839 #[serde(skip_serializing_if = "Option::is_none")]
840 pub range: Option<(usize, usize)>,
841 #[serde(skip_serializing_if = "Option::is_none")]
842 pub internal: Option<bool>,
843 #[serde(skip_serializing_if = "Option::is_none")]
844 pub watchonly: Option<bool>,
845 #[serde(skip_serializing_if = "Option::is_none")]
846 pub label: Option<&'a str>,
847 #[serde(skip_serializing_if = "Option::is_none")]
848 pub keypool: Option<bool>,
849}
850
851#[derive(Clone, PartialEq, Eq, Debug, Default, Deserialize, Serialize)]
852pub struct ImportMultiOptions {
853 #[serde(skip_serializing_if = "Option::is_none")]
854 pub rescan: Option<bool>,
855}
856
857#[derive(Clone, PartialEq, Eq, Copy, Debug)]
858pub enum ImportMultiRescanSince {
859 Now,
860 Timestamp(u64),
861}
862
863impl serde::Serialize for ImportMultiRescanSince {
864 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
865 where
866 S: serde::Serializer,
867 {
868 match *self {
869 ImportMultiRescanSince::Now => serializer.serialize_str("now"),
870 ImportMultiRescanSince::Timestamp(timestamp) => serializer.serialize_u64(timestamp),
871 }
872 }
873}
874
875impl Default for ImportMultiRescanSince {
876 fn default() -> Self {
877 ImportMultiRescanSince::Timestamp(0)
878 }
879}
880
881#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
882pub struct ImportMultiResultError {
883 pub code: i64,
884 pub message: String,
885}
886
887#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
888pub struct ImportMultiResult {
889 pub success: bool,
890 #[serde(default)]
891 pub warnings: Vec<String>,
892 pub error: Option<ImportMultiResultError>,
893}
894
895#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
897pub struct RejectStatus {
898 pub status: bool,
900}
901
902#[derive(Clone, Debug, Deserialize, Serialize)]
904pub struct GetPeerInfoResult {
905 pub id: u64,
907 pub addr: String,
910 pub addrbind: String,
913 pub addrlocal: Option<String>,
916 pub services: String,
919 pub relaytxes: bool,
921 pub lastsend: u64,
923 pub lastrecv: u64,
925 pub bytessent: u64,
927 pub bytesrecv: u64,
929 pub conntime: u64,
931 pub timeoffset: i64,
933 pub pingtime: Option<f64>,
935 pub minping: Option<f64>,
937 pub pingwait: Option<f64>,
939 pub version: u64,
941 pub subver: String,
943 pub inbound: bool,
945 pub addnode: bool,
948 pub startingheight: i64,
950 pub banscore: i64,
952 pub synced_headers: i64,
954 pub synced_blocks: i64,
956 pub inflight: Vec<u64>,
958 pub whitelisted: bool,
960 #[serde(rename = "minfeefilter", default, with = "bitcoin::util::amount::serde::as_btc::opt")]
961 pub min_fee_filter: Option<Amount>,
962 pub bytessent_per_msg: HashMap<String, u64>,
964 pub bytesrecv_per_msg: HashMap<String, u64>,
966}
967
968#[derive(Clone, Debug, Deserialize, Serialize)]
970pub struct EstimateSmartFeeResult {
971 #[serde(
973 default,
974 rename = "feerate",
975 skip_serializing_if = "Option::is_none",
976 with = "bitcoin::util::amount::serde::as_btc::opt"
977 )]
978 pub fee_rate: Option<Amount>,
979 pub errors: Option<Vec<String>>,
981 pub blocks: i64,
983}
984
985#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
987pub struct BlockRef {
988 pub hash: bitcoin::BlockHash,
989 pub height: u64,
990}
991
992#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
994pub struct GetDescriptorInfoResult {
995 pub descriptor: String,
996 pub checksum: String,
997 #[serde(rename = "isrange")]
998 pub is_range: bool,
999 #[serde(rename = "issolvable")]
1000 pub is_solvable: bool,
1001 #[serde(rename = "hasprivatekeys")]
1002 pub has_private_keys: bool,
1003}
1004
1005#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1007pub struct WalletCreateFundedPsbtResult {
1008 pub psbt: String,
1009 #[serde(with = "bitcoin::util::amount::serde::as_btc")]
1010 pub fee: Amount,
1011 #[serde(rename = "changepos")]
1012 pub change_position: i32,
1013}
1014
1015#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize, Default)]
1017pub struct WalletCreateFundedPsbtOptions {
1018 #[serde(rename = "changeAddress", skip_serializing_if = "Option::is_none")]
1019 pub change_address: Option<Address>,
1020 #[serde(rename = "changePosition", skip_serializing_if = "Option::is_none")]
1021 pub change_position: Option<u16>,
1022 #[serde(skip_serializing_if = "Option::is_none")]
1023 pub change_type: Option<AddressType>,
1024 #[serde(rename = "includeWatching", skip_serializing_if = "Option::is_none")]
1025 pub include_watching: Option<bool>,
1026 #[serde(rename = "lockUnspents", skip_serializing_if = "Option::is_none")]
1027 pub lock_unspent: Option<bool>,
1028 #[serde(
1029 rename = "feeRate",
1030 skip_serializing_if = "Option::is_none",
1031 with = "bitcoin::util::amount::serde::as_btc::opt"
1032 )]
1033 pub fee_rate: Option<Amount>,
1034 #[serde(rename = "subtractFeeFromOutputs", skip_serializing_if = "Vec::is_empty")]
1035 pub subtract_fee_from_outputs: Vec<u16>,
1036 #[serde(skip_serializing_if = "Option::is_none")]
1037 pub replaceable: Option<bool>,
1038 #[serde(skip_serializing_if = "Option::is_none")]
1039 pub conf_target: Option<u16>,
1040 #[serde(skip_serializing_if = "Option::is_none")]
1041 pub estimate_mode: Option<EstimateMode>,
1042}
1043
1044#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1046pub struct FinalizePsbtResult {
1047 pub psbt: Option<String>,
1048 #[serde(default, with = "serde_hex::opt")]
1049 pub hex: Option<Vec<u8>>,
1050 pub complete: bool,
1051}
1052
1053impl FinalizePsbtResult {
1054 pub fn transaction(&self) -> Option<Result<Transaction, encode::Error>> {
1055 self.hex.as_ref().map(|h| encode::deserialize(h))
1056 }
1057}
1058
1059#[derive(Serialize, Deserialize, Debug, Clone, Copy, Eq, PartialEq, Hash)]
1062#[serde(rename_all = "UPPERCASE")]
1063pub enum EstimateMode {
1064 Unset,
1065 Economical,
1066 Conservative,
1067}
1068
1069pub struct SigHashType(bitcoin::SigHashType);
1072
1073impl From<bitcoin::SigHashType> for SigHashType {
1074 fn from(sht: bitcoin::SigHashType) -> SigHashType {
1075 SigHashType(sht)
1076 }
1077}
1078
1079impl serde::Serialize for SigHashType {
1080 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1081 where
1082 S: serde::Serializer,
1083 {
1084 serializer.serialize_str(match self.0 {
1085 bitcoin::SigHashType::All => "ALL",
1086 bitcoin::SigHashType::None => "NONE",
1087 bitcoin::SigHashType::Single => "SINGLE",
1088 bitcoin::SigHashType::AllPlusAnyoneCanPay => "ALL|ANYONECANPAY",
1089 bitcoin::SigHashType::NonePlusAnyoneCanPay => "NONE|ANYONECANPAY",
1090 bitcoin::SigHashType::SinglePlusAnyoneCanPay => "SINGLE|ANYONECANPAY",
1091 })
1092 }
1093}
1094
1095#[derive(Serialize, Clone, PartialEq, Eq, Debug)]
1097#[serde(rename_all = "camelCase")]
1098pub struct CreateRawTransactionInput {
1099 pub txid: bitcoin::Txid,
1100 pub vout: u32,
1101 #[serde(skip_serializing_if = "Option::is_none")]
1102 pub sequence: Option<u32>,
1103}
1104
1105#[derive(Serialize, Clone, PartialEq, Eq, Debug, Default)]
1106#[serde(rename_all = "camelCase")]
1107pub struct FundRawTransactionOptions {
1108 #[serde(skip_serializing_if = "Option::is_none")]
1109 pub change_address: Option<Address>,
1110 #[serde(skip_serializing_if = "Option::is_none")]
1111 pub change_position: Option<u32>,
1112 #[serde(rename = "change_type", skip_serializing_if = "Option::is_none")]
1113 pub change_type: Option<AddressType>,
1114 #[serde(skip_serializing_if = "Option::is_none")]
1115 pub include_watching: Option<bool>,
1116 #[serde(skip_serializing_if = "Option::is_none")]
1117 pub lock_unspents: Option<bool>,
1118 #[serde(
1119 with = "bitcoin::util::amount::serde::as_btc::opt",
1120 skip_serializing_if = "Option::is_none"
1121 )]
1122 pub fee_rate: Option<Amount>,
1123 #[serde(skip_serializing_if = "Option::is_none")]
1124 pub subtract_fee_from_outputs: Option<Vec<u32>>,
1125 #[serde(skip_serializing_if = "Option::is_none")]
1126 pub replaceable: Option<bool>,
1127 #[serde(rename = "conf_target", skip_serializing_if = "Option::is_none")]
1128 pub conf_target: Option<u32>,
1129 #[serde(rename = "estimate_mode", skip_serializing_if = "Option::is_none")]
1130 pub estimate_mode: Option<EstimateMode>,
1131}
1132
1133#[derive(Deserialize, Clone, PartialEq, Eq, Debug)]
1134#[serde(rename_all = "camelCase")]
1135pub struct FundRawTransactionResult {
1136 #[serde(with = "serde_hex")]
1137 pub hex: Vec<u8>,
1138 #[serde(with = "bitcoin::util::amount::serde::as_btc")]
1139 pub fee: Amount,
1140 #[serde(rename = "changepos")]
1141 pub change_position: i32,
1142}
1143
1144#[derive(Deserialize, Clone, PartialEq, Eq, Debug)]
1145pub struct GetBalancesResultEntry {
1146 #[serde(with = "bitcoin::util::amount::serde::as_btc")]
1147 pub trusted: Amount,
1148 #[serde(with = "bitcoin::util::amount::serde::as_btc")]
1149 pub untrusted_pending: Amount,
1150 #[serde(with = "bitcoin::util::amount::serde::as_btc")]
1151 pub immature: Amount,
1152}
1153
1154#[derive(Deserialize, Clone, PartialEq, Eq, Debug)]
1155#[serde(rename_all = "camelCase")]
1156pub struct GetBalancesResult {
1157 pub mine: GetBalancesResultEntry,
1158 pub watchonly: Option<GetBalancesResultEntry>,
1159}
1160
1161impl FundRawTransactionResult {
1162 pub fn transaction(&self) -> Result<Transaction, encode::Error> {
1163 encode::deserialize(&self.hex)
1164 }
1165}
1166
1167#[derive(Serialize, Clone, PartialEq, Debug)]
1169#[serde(rename_all = "camelCase")]
1170pub struct SignRawTransactionInput {
1171 pub txid: bitcoin::Txid,
1172 pub vout: u32,
1173 pub script_pub_key: Script,
1174 #[serde(skip_serializing_if = "Option::is_none")]
1175 pub redeem_script: Option<Script>,
1176 #[serde(
1177 default,
1178 skip_serializing_if = "Option::is_none",
1179 with = "bitcoin::util::amount::serde::as_btc::opt"
1180 )]
1181 pub amount: Option<Amount>,
1182}
1183
1184#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1185pub struct GetTxOutSetInfoResult {
1186 pub height: u64,
1188 #[serde(rename = "bestblock")]
1190 pub best_block: bitcoin::BlockHash,
1191 pub transactions: u64,
1193 #[serde(rename = "txouts")]
1195 pub tx_outs: u64,
1196 pub bogosize: u64,
1198 pub hash_serialized_2: sha256::Hash,
1200 pub disk_size: u64,
1202 #[serde(with = "bitcoin::util::amount::serde::as_btc")]
1204 pub total_amount: Amount,
1205}
1206
1207#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1208pub struct GetNetTotalsResult {
1209 #[serde(rename = "totalbytesrecv")]
1211 pub total_bytes_recv: u64,
1212 #[serde(rename = "totalbytessent")]
1214 pub total_bytes_sent: u64,
1215 #[serde(rename = "timemillis")]
1217 pub time_millis: u64,
1218 #[serde(rename = "uploadtarget")]
1220 pub upload_target: GetNetTotalsResultUploadTarget,
1221}
1222
1223#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
1224pub struct GetNetTotalsResultUploadTarget {
1225 #[serde(rename = "timeframe")]
1227 pub time_frame: u64,
1228 pub target: u64,
1230 pub target_reached: bool,
1232 pub serve_historical_blocks: bool,
1234 pub bytes_left_in_cycle: u64,
1236 pub time_left_in_cycle: u64,
1238}
1239
1240#[derive(Copy, Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
1242#[serde(rename_all = "kebab-case")]
1243pub enum AddressType {
1244 Legacy,
1245 P2shSegwit,
1246 Bech32,
1247}
1248
1249#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
1251pub enum PubKeyOrAddress<'a> {
1252 Address(&'a Address),
1253 PubKey(&'a PublicKey),
1254}
1255
1256#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
1257#[serde(untagged)]
1258pub enum ScanTxOutRequest {
1260 Single(String),
1262 Extended {
1264 desc: String,
1266 range: (u64, u64),
1268 },
1269}
1270
1271#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
1272pub struct ScanTxOutResult {
1273 pub success: Option<bool>,
1274 #[serde(rename = "txouts")]
1275 pub tx_outs: Option<u64>,
1276 pub height: Option<u64>,
1277 #[serde(rename = "bestblock")]
1278 pub best_block_hash: Option<bitcoin::BlockHash>,
1279 pub unspents: Vec<Utxo>,
1280 #[serde(with = "bitcoin::util::amount::serde::as_btc")]
1281 pub total_amount: bitcoin::Amount,
1282}
1283
1284#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
1285#[serde(rename_all = "camelCase")]
1286pub struct Utxo {
1287 pub txid: bitcoin::Txid,
1288 pub vout: u32,
1289 pub script_pub_key: bitcoin::Script,
1290 #[serde(rename = "desc")]
1291 pub descriptor: String,
1292 #[serde(with = "bitcoin::util::amount::serde::as_btc")]
1293 pub amount: bitcoin::Amount,
1294 pub height: u64,
1295}
1296
1297impl<'a> serde::Serialize for PubKeyOrAddress<'a> {
1298 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1299 where
1300 S: serde::Serializer,
1301 {
1302 match *self {
1303 PubKeyOrAddress::Address(a) => serde::Serialize::serialize(a, serializer),
1304 PubKeyOrAddress::PubKey(k) => serde::Serialize::serialize(k, serializer),
1305 }
1306 }
1307}
1308
1309fn deserialize_hex_array_opt<'de, D>(deserializer: D) -> Result<Option<Vec<Vec<u8>>>, D::Error>
1313where
1314 D: serde::Deserializer<'de>,
1315{
1316 let v: Vec<String> = Vec::deserialize(deserializer)?;
1320 let mut res = Vec::new();
1321 for h in v.into_iter() {
1322 res.push(FromHex::from_hex(&h).map_err(D::Error::custom)?);
1323 }
1324 Ok(Some(res))
1325}