@@ -9,32 +9,38 @@ use crate::storage::StorageManager;
99#[ cfg( feature = "terminal-ui" ) ]
1010use crate :: terminal:: TerminalUI ;
1111use crate :: types:: { ChainState , SpvStats , SyncProgress } ;
12+ use key_wallet_manager:: wallet_interface:: WalletInterface ;
1213
1314/// Status display manager for updating UI and reporting sync progress.
14- pub struct StatusDisplay < ' a , S : StorageManager > {
15+ pub struct StatusDisplay < ' a , S : StorageManager , W : WalletInterface > {
1516 state : & ' a Arc < RwLock < ChainState > > ,
1617 stats : & ' a Arc < RwLock < SpvStats > > ,
1718 storage : Arc < Mutex < S > > ,
19+ wallet : Option < & ' a Arc < RwLock < W > > > ,
1820 #[ cfg( feature = "terminal-ui" ) ]
1921 terminal_ui : & ' a Option < Arc < TerminalUI > > ,
2022 #[ allow( dead_code) ]
2123 config : & ' a ClientConfig ,
2224}
2325
24- impl < ' a , S : StorageManager + Send + Sync + ' static > StatusDisplay < ' a , S > {
26+ impl < ' a , S : StorageManager + Send + Sync + ' static , W : WalletInterface + Send + Sync + ' static >
27+ StatusDisplay < ' a , S , W >
28+ {
2529 /// Create a new status display manager.
2630 #[ cfg( feature = "terminal-ui" ) ]
2731 pub fn new (
2832 state : & ' a Arc < RwLock < ChainState > > ,
2933 stats : & ' a Arc < RwLock < SpvStats > > ,
3034 storage : Arc < Mutex < S > > ,
35+ wallet : Option < & ' a Arc < RwLock < W > > > ,
3136 terminal_ui : & ' a Option < Arc < TerminalUI > > ,
3237 config : & ' a ClientConfig ,
3338 ) -> Self {
3439 Self {
3540 state,
3641 stats,
3742 storage,
43+ wallet,
3844 terminal_ui,
3945 config,
4046 }
@@ -46,13 +52,15 @@ impl<'a, S: StorageManager + Send + Sync + 'static> StatusDisplay<'a, S> {
4652 state : & ' a Arc < RwLock < ChainState > > ,
4753 stats : & ' a Arc < RwLock < SpvStats > > ,
4854 storage : Arc < Mutex < S > > ,
55+ wallet : Option < & ' a Arc < RwLock < W > > > ,
4956 _terminal_ui : & ' a Option < ( ) > ,
5057 config : & ' a ClientConfig ,
5158 ) -> Self {
5259 Self {
5360 state,
5461 stats,
5562 storage,
63+ wallet,
5664 config,
5765 }
5866 }
@@ -140,6 +148,42 @@ impl<'a, S: StorageManager + Send + Sync + 'static> StatusDisplay<'a, S> {
140148 state. clone ( )
141149 }
142150
151+ /// Helper to try to get wallet balance if W implements Any.
152+ /// This is a wrapper that handles the case where W might not implement Any.
153+ fn try_get_balance_if_any ( wallet : & W ) -> Option < u64 >
154+ where
155+ W : ' static ,
156+ {
157+ // Try to use Any trait for downcasting
158+ // We check if W is WalletManager<ManagedWalletInfo> using TypeId
159+ use key_wallet:: wallet:: managed_wallet_info:: ManagedWalletInfo ;
160+ use key_wallet_manager:: wallet_manager:: WalletManager ;
161+ use std:: any:: TypeId ;
162+
163+ // Check if W is WalletManager<ManagedWalletInfo>
164+ let wallet_type_id = TypeId :: of :: < W > ( ) ;
165+ let wallet_manager_type_id = TypeId :: of :: < WalletManager < ManagedWalletInfo > > ( ) ;
166+
167+ if wallet_type_id == wallet_manager_type_id {
168+ // Unsafe downcast: we've verified the types match, so this is safe
169+ unsafe {
170+ let wallet_ptr = wallet as * const W as * const WalletManager < ManagedWalletInfo > ;
171+ let wallet_ref = & * wallet_ptr;
172+ return Some ( wallet_ref. get_total_balance ( ) ) ;
173+ }
174+ }
175+
176+ None
177+ }
178+
179+ /// Format balance in DASH with 8 decimal places.
180+ fn format_balance ( satoshis : u64 ) -> String {
181+ use dashcore:: Amount ;
182+ use dashcore:: Denomination ;
183+ let amount = Amount :: from_sat ( satoshis) ;
184+ amount. to_string_with_denomination ( Denomination :: Dash )
185+ }
186+
143187 /// Update the status display.
144188 pub async fn update_status_display ( & self ) {
145189 #[ cfg( feature = "terminal-ui" ) ]
@@ -219,23 +263,39 @@ impl<'a, S: StorageManager + Send + Sync + 'static> StatusDisplay<'a, S> {
219263
220264 // Get filter and block processing statistics
221265 let stats = self . stats . read ( ) . await ;
266+ let filters_received = stats. filters_received ;
222267 let filters_matched = stats. filters_matched ;
223268 let blocks_with_relevant_transactions = stats. blocks_with_relevant_transactions ;
224269 let blocks_processed = stats. blocks_processed ;
225270 drop ( stats) ;
226271
272+ // Get wallet balance if available
273+ let balance_str = if let Some ( wallet_ref) = self . wallet {
274+ let wallet_guard = wallet_ref. read ( ) . await ;
275+ // Try to get balance if W implements Any (for WalletManager support)
276+ // We use a helper that requires W: Any, so we need to handle this carefully
277+ // For now, we'll attempt to get balance only if possible
278+ Self :: try_get_balance_if_any ( & * wallet_guard)
279+ . map ( |balance_sat| format ! ( " | Balance: {}" , Self :: format_balance( balance_sat) ) )
280+ . unwrap_or_default ( )
281+ } else {
282+ String :: new ( )
283+ } ;
284+
227285 tracing:: info!(
228- "📊 [SYNC STATUS] Headers: {} | Filter Headers: {} | Latest ChainLock: {} | Filters Matched: {} | Blocks w/ Relevant Txs: {} | Blocks Processed: {}" ,
286+ "📊 [SYNC STATUS] Headers: {} | Filter Headers: {} | Filters: {} | Latest ChainLock: {} | Filters Matched: {} | Blocks w/ Relevant Txs: {} | Blocks Processed: {} {}" ,
229287 header_height,
230288 filter_height,
289+ filters_received,
231290 if chainlock_height > 0 {
232291 format!( "#{}" , chainlock_height)
233292 } else {
234293 "None" . to_string( )
235294 } ,
236295 filters_matched,
237296 blocks_with_relevant_transactions,
238- blocks_processed
297+ blocks_processed,
298+ balance_str
239299 ) ;
240300 }
241301 }
0 commit comments