1use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
7pub struct Balance {
8 pub confirmed: u64,
10 pub unconfirmed: i64,
12}
13
14impl Balance {
15 #[inline]
18 pub fn total(&self) -> i64 {
19 self.confirmed as i64 + self.unconfirmed
20 }
21
22 #[inline]
24 pub fn has_balance(&self) -> bool {
25 self.confirmed > 0 || self.unconfirmed != 0
26 }
27
28 #[inline]
30 pub fn has_unconfirmed(&self) -> bool {
31 self.unconfirmed != 0
32 }
33}
34
35#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
37pub struct Utxo {
38 #[serde(rename = "tx_hash")]
40 pub txid: String,
41 #[serde(rename = "tx_pos")]
43 pub vout: u32,
44 pub value: u64,
46 pub height: u64,
48}
49
50impl Utxo {
51 #[inline]
53 pub fn is_confirmed(&self) -> bool {
54 self.height > 0
55 }
56
57 pub fn outpoint(&self) -> String {
59 format!("{}:{}", self.txid, self.vout)
60 }
61}
62
63#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
65pub struct TxHistory {
66 #[serde(rename = "tx_hash")]
68 pub txid: String,
69 pub height: i64,
71 #[serde(default)]
73 pub fee: Option<u64>,
74}
75
76impl TxHistory {
77 #[inline]
79 pub fn is_confirmed(&self) -> bool {
80 self.height > 0
81 }
82}
83
84#[derive(Debug, Clone, PartialEq, Eq)]
86pub struct ServerVersion {
87 pub server_software: String,
89 pub protocol_version: String,
91}
92
93#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
95pub struct ServerFeatures {
96 #[serde(default)]
98 pub server_version: String,
99 #[serde(default)]
101 pub protocol_max: String,
102 #[serde(default)]
104 pub genesis_hash: String,
105 #[serde(default)]
107 pub hash_function: String,
108}
109
110#[derive(Debug, Clone)]
112pub struct ClientConfig {
113 pub server: String,
115 pub port: u16,
117 pub use_tls: bool,
119 pub timeout: std::time::Duration,
121 pub retry_count: u32,
123 pub retry_delay: std::time::Duration,
125 pub skip_tls_verify: bool,
127}
128
129impl ClientConfig {
130 pub fn tcp(server: impl Into<String>) -> Self {
132 Self {
133 server: server.into(),
134 port: 50001,
135 use_tls: false,
136 timeout: std::time::Duration::from_secs(30),
137 retry_count: 3,
138 retry_delay: std::time::Duration::from_secs(1),
139 skip_tls_verify: false,
140 }
141 }
142
143 pub fn ssl(server: impl Into<String>) -> Self {
145 Self {
146 server: server.into(),
147 port: 50002,
148 use_tls: true,
149 timeout: std::time::Duration::from_secs(30),
150 retry_count: 3,
151 retry_delay: std::time::Duration::from_secs(1),
152 skip_tls_verify: false,
153 }
154 }
155
156 pub fn with_port(mut self, port: u16) -> Self {
158 self.port = port;
159 self
160 }
161
162 pub fn with_timeout(mut self, timeout: std::time::Duration) -> Self {
164 self.timeout = timeout;
165 self
166 }
167
168 pub fn with_retry(mut self, count: u32, delay: std::time::Duration) -> Self {
170 self.retry_count = count;
171 self.retry_delay = delay;
172 self
173 }
174
175 pub fn with_skip_tls_verify(mut self) -> Self {
181 self.skip_tls_verify = true;
182 self
183 }
184
185 pub fn address(&self) -> String {
187 format!("{}:{}", self.server, self.port)
188 }
189}
190
191impl Default for ClientConfig {
192 fn default() -> Self {
193 Self::ssl("electrum.blockstream.info")
194 }
195}
196
197pub const DEFAULT_SERVERS: &[(&str, u16, bool)] = &[
199 ("electrum.blockstream.info", 50002, true),
200 ("electrum.blockstream.info", 50001, false),
201 ("electrum1.bluewallet.io", 443, true),
202 ("electrum2.bluewallet.io", 443, true),
203 ("bitcoin.aranguren.org", 50002, true),
204 ("electrum.bitaroo.net", 50002, true),
205];