rustywallet_mempool/
types.rs

1//! Data types for Mempool.space API responses.
2
3use serde::{Deserialize, Serialize};
4
5/// Recommended fee rates from mempool.space.
6///
7/// All values are in satoshis per virtual byte (sat/vB).
8#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
9#[serde(rename_all = "camelCase")]
10pub struct FeeEstimates {
11    /// Fee for next block confirmation (~10 min)
12    pub fastest_fee: u64,
13    /// Fee for confirmation within ~30 minutes
14    pub half_hour_fee: u64,
15    /// Fee for confirmation within ~1 hour
16    pub hour_fee: u64,
17    /// Fee for confirmation within ~6 hours
18    pub economy_fee: u64,
19    /// Minimum relay fee
20    pub minimum_fee: u64,
21}
22
23impl FeeEstimates {
24    /// Get fee rate for target confirmation time.
25    ///
26    /// - `blocks <= 1`: fastest
27    /// - `blocks <= 3`: half_hour
28    /// - `blocks <= 6`: hour
29    /// - `blocks > 6`: economy
30    pub fn for_blocks(&self, blocks: u32) -> u64 {
31        match blocks {
32            0..=1 => self.fastest_fee,
33            2..=3 => self.half_hour_fee,
34            4..=6 => self.hour_fee,
35            _ => self.economy_fee,
36        }
37    }
38}
39
40/// Address information from mempool.space.
41#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
42pub struct AddressInfo {
43    /// The address
44    pub address: String,
45    /// On-chain statistics
46    pub chain_stats: ChainStats,
47    /// Mempool (unconfirmed) statistics
48    pub mempool_stats: MempoolStats,
49}
50
51impl AddressInfo {
52    /// Get confirmed balance in satoshis.
53    pub fn confirmed_balance(&self) -> i64 {
54        self.chain_stats.funded_txo_sum as i64 - self.chain_stats.spent_txo_sum as i64
55    }
56
57    /// Get unconfirmed balance change in satoshis.
58    pub fn unconfirmed_balance(&self) -> i64 {
59        self.mempool_stats.funded_txo_sum as i64 - self.mempool_stats.spent_txo_sum as i64
60    }
61
62    /// Get total balance (confirmed + unconfirmed) in satoshis.
63    pub fn total_balance(&self) -> i64 {
64        self.confirmed_balance() + self.unconfirmed_balance()
65    }
66
67    /// Get total transaction count.
68    pub fn tx_count(&self) -> u64 {
69        self.chain_stats.tx_count + self.mempool_stats.tx_count
70    }
71}
72
73/// On-chain statistics for an address.
74#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
75pub struct ChainStats {
76    /// Number of funded transaction outputs
77    pub funded_txo_count: u64,
78    /// Total value of funded outputs (satoshis)
79    pub funded_txo_sum: u64,
80    /// Number of spent transaction outputs
81    pub spent_txo_count: u64,
82    /// Total value of spent outputs (satoshis)
83    pub spent_txo_sum: u64,
84    /// Total transaction count
85    pub tx_count: u64,
86}
87
88/// Mempool (unconfirmed) statistics for an address.
89#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
90pub struct MempoolStats {
91    /// Number of funded transaction outputs in mempool
92    pub funded_txo_count: u64,
93    /// Total value of funded outputs in mempool (satoshis)
94    pub funded_txo_sum: u64,
95    /// Number of spent transaction outputs in mempool
96    pub spent_txo_count: u64,
97    /// Total value of spent outputs in mempool (satoshis)
98    pub spent_txo_sum: u64,
99    /// Transaction count in mempool
100    pub tx_count: u64,
101}
102
103/// Unspent transaction output (UTXO).
104#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
105pub struct Utxo {
106    /// Transaction ID
107    pub txid: String,
108    /// Output index
109    pub vout: u32,
110    /// Value in satoshis
111    pub value: u64,
112    /// Confirmation status
113    pub status: UtxoStatus,
114}
115
116impl Utxo {
117    /// Check if this UTXO is confirmed.
118    pub fn is_confirmed(&self) -> bool {
119        self.status.confirmed
120    }
121
122    /// Get the outpoint string (txid:vout).
123    pub fn outpoint(&self) -> String {
124        format!("{}:{}", self.txid, self.vout)
125    }
126}
127
128/// UTXO confirmation status.
129#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
130pub struct UtxoStatus {
131    /// Whether the UTXO is confirmed
132    pub confirmed: bool,
133    /// Block height (if confirmed)
134    pub block_height: Option<u64>,
135    /// Block hash (if confirmed)
136    pub block_hash: Option<String>,
137    /// Block time (if confirmed)
138    pub block_time: Option<u64>,
139}
140
141/// Transaction information.
142#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
143pub struct Transaction {
144    /// Transaction ID
145    pub txid: String,
146    /// Transaction version
147    pub version: i32,
148    /// Lock time
149    pub locktime: u32,
150    /// Transaction size in bytes
151    pub size: u32,
152    /// Transaction weight
153    pub weight: u32,
154    /// Transaction fee in satoshis
155    pub fee: u64,
156    /// Confirmation status
157    pub status: TxStatus,
158}
159
160impl Transaction {
161    /// Check if this transaction is confirmed.
162    pub fn is_confirmed(&self) -> bool {
163        self.status.confirmed
164    }
165
166    /// Get virtual size (vsize) in vbytes.
167    pub fn vsize(&self) -> u32 {
168        self.weight.div_ceil(4)
169    }
170
171    /// Get fee rate in sat/vB.
172    pub fn fee_rate(&self) -> f64 {
173        self.fee as f64 / self.vsize() as f64
174    }
175}
176
177/// Transaction confirmation status.
178#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
179pub struct TxStatus {
180    /// Whether the transaction is confirmed
181    pub confirmed: bool,
182    /// Block height (if confirmed)
183    pub block_height: Option<u64>,
184    /// Block hash (if confirmed)
185    pub block_hash: Option<String>,
186    /// Block time (if confirmed)
187    pub block_time: Option<u64>,
188}
189
190/// Block information.
191#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
192pub struct BlockInfo {
193    /// Block hash
194    pub id: String,
195    /// Block height
196    pub height: u64,
197    /// Block version
198    pub version: i32,
199    /// Block timestamp
200    pub timestamp: u64,
201    /// Number of transactions
202    pub tx_count: u32,
203    /// Block size in bytes
204    pub size: u32,
205    /// Block weight
206    pub weight: u32,
207    /// Merkle root
208    pub merkle_root: String,
209    /// Previous block hash
210    pub previousblockhash: String,
211    /// Nonce
212    pub nonce: u32,
213    /// Difficulty bits
214    pub bits: u32,
215}