@@ -232,164 +232,6 @@ impl FFIDashSpvClient {
232232 }
233233 }
234234
235- /// Start the event listener task to handle events from the SPV client.
236- fn start_event_listener ( & self ) {
237- let inner = self . inner . clone ( ) ;
238- let event_callbacks = self . event_callbacks . clone ( ) ;
239- let runtime = self . runtime . clone ( ) ;
240- let shutdown_signal = self . shutdown_signal . clone ( ) ;
241-
242- let handle = std:: thread:: spawn ( move || {
243- runtime. block_on ( async {
244- let event_rx = {
245- let mut guard = inner. lock ( ) . unwrap ( ) ;
246- if let Some ( ref mut client) = * guard {
247- client. take_event_receiver ( )
248- } else {
249- None
250- }
251- } ;
252-
253- if let Some ( mut rx) = event_rx {
254- tracing:: info!( "🎧 FFI event listener started successfully" ) ;
255- loop {
256- // Check shutdown signal
257- if shutdown_signal. load ( Ordering :: Relaxed ) {
258- tracing:: info!( "🛑 FFI event listener received shutdown signal" ) ;
259- break ;
260- }
261-
262- // Use recv with timeout to periodically check shutdown signal
263- match tokio:: time:: timeout ( Duration :: from_millis ( 100 ) , rx. recv ( ) ) . await {
264- Ok ( Some ( event) ) => {
265- tracing:: info!( "🎧 FFI received event: {:?}" , event) ;
266- let callbacks = event_callbacks. lock ( ) . unwrap ( ) ;
267- match event {
268- dash_spv:: types:: SpvEvent :: BalanceUpdate { confirmed, unconfirmed, total } => {
269- tracing:: info!( "💰 Balance update event: confirmed={}, unconfirmed={}, total={}" ,
270- confirmed, unconfirmed, total) ;
271- callbacks. call_balance_update ( confirmed, unconfirmed) ;
272- }
273- dash_spv:: types:: SpvEvent :: FilterHeadersProgress { filter_header_height, header_height, percentage } => {
274- tracing:: info!( "📊 Filter headers progress event: filter={}, header={}, pct={:.2}" ,
275- filter_header_height, header_height, percentage) ;
276- callbacks
277- . call_filter_headers_progress (
278- filter_header_height,
279- header_height,
280- percentage,
281- ) ;
282- }
283- dash_spv:: types:: SpvEvent :: TransactionDetected { ref txid, confirmed, ref addresses, amount, block_height, .. } => {
284- tracing:: info!( "💸 Transaction detected: txid={}, confirmed={}, amount={}, addresses={:?}, height={:?}" ,
285- txid, confirmed, amount, addresses, block_height) ;
286- // Parse the txid string to a Txid type
287- if let Ok ( txid_parsed) = txid. parse :: < dashcore:: Txid > ( ) {
288- // Call the general transaction callback
289- callbacks. call_transaction ( & txid_parsed, confirmed, amount, addresses, block_height) ;
290-
291- // Also try to provide wallet-specific context
292- // Note: For now, we provide basic wallet context.
293- // In a more advanced implementation, we could enhance this
294- // to look up the actual wallet/account that owns this transaction.
295- let wallet_id_hex = "unknown" ; // Placeholder - would need wallet lookup
296- let account_index = 0 ; // Default account index
297- let block_height = block_height. unwrap_or ( 0 ) ;
298- let is_ours = amount != 0 ; // Simple heuristic
299-
300- callbacks. call_wallet_transaction (
301- wallet_id_hex,
302- account_index,
303- & txid_parsed,
304- confirmed,
305- amount,
306- addresses,
307- block_height,
308- is_ours,
309- ) ;
310- } else {
311- tracing:: error!( "Failed to parse transaction ID: {}" , txid) ;
312- }
313- }
314- dash_spv:: types:: SpvEvent :: BlockProcessed { height, ref hash, transactions_count, relevant_transactions } => {
315- tracing:: info!( "📦 Block processed: height={}, hash={}, total_tx={}, relevant_tx={}" ,
316- height, hash, transactions_count, relevant_transactions) ;
317- // Parse the block hash string to a BlockHash type
318- if let Ok ( hash_parsed) = hash. parse :: < dashcore:: BlockHash > ( ) {
319- callbacks. call_block ( height, & hash_parsed) ;
320- } else {
321- tracing:: error!( "Failed to parse block hash: {}" , hash) ;
322- }
323- }
324- dash_spv:: types:: SpvEvent :: SyncProgress { .. } => {
325- // Sync progress is handled via existing progress callback
326- tracing:: debug!( "📊 Sync progress event (handled separately)" ) ;
327- }
328- dash_spv:: types:: SpvEvent :: ChainLockReceived { height, hash } => {
329- // ChainLock events can be handled here
330- tracing:: info!( "🔒 ChainLock received for height {} hash {}" , height, hash) ;
331- }
332- dash_spv:: types:: SpvEvent :: MempoolTransactionAdded { ref txid, transaction : _, amount, ref addresses, is_instant_send } => {
333- tracing:: info!( "➕ Mempool transaction added: txid={}, amount={}, addresses={:?}, instant_send={}" ,
334- txid, amount, addresses, is_instant_send) ;
335- // Call the mempool-specific callback
336- callbacks. call_mempool_transaction_added ( txid, amount, addresses, is_instant_send) ;
337- }
338- dash_spv:: types:: SpvEvent :: MempoolTransactionConfirmed { ref txid, block_height, ref block_hash } => {
339- tracing:: info!( "✅ Mempool transaction confirmed: txid={}, height={}, hash={}" ,
340- txid, block_height, block_hash) ;
341- // Call the mempool confirmed callback
342- callbacks. call_mempool_transaction_confirmed ( txid, block_height, block_hash) ;
343- }
344- dash_spv:: types:: SpvEvent :: MempoolTransactionRemoved { ref txid, ref reason } => {
345- tracing:: info!( "❌ Mempool transaction removed: txid={}, reason={:?}" ,
346- txid, reason) ;
347- // Convert reason to u8 for FFI using existing conversion
348- let ffi_reason: crate :: types:: FFIMempoolRemovalReason = reason. clone ( ) . into ( ) ;
349- let reason_code = ffi_reason as u8 ;
350- callbacks. call_mempool_transaction_removed ( txid, reason_code) ;
351- }
352- dash_spv:: types:: SpvEvent :: CompactFilterMatched { hash } => {
353- tracing:: info!( "📄 Compact filter matched: block={}" , hash) ;
354-
355- // Try to provide richer information by looking up which wallet matched
356- // Since we don't have direct access to filter details, we'll provide basic info
357- if let Ok ( block_hash_parsed) = hash. parse :: < dashcore:: BlockHash > ( ) {
358- // For now, we'll call with empty matched scripts and unknown wallet
359- // In a more advanced implementation, we could enhance the SpvEvent to include this info
360- callbacks. call_compact_filter_matched (
361- & block_hash_parsed,
362- & [ ] , // matched_scripts - empty for now
363- "unknown" , // wallet_id - unknown for now
364- ) ;
365- } else {
366- tracing:: error!( "Failed to parse compact filter block hash: {}" , hash) ;
367- }
368- }
369- }
370- }
371- Ok ( None ) => {
372- // Channel closed, exit loop
373- tracing:: info!( "🎧 FFI event channel closed" ) ;
374- break ;
375- }
376- Err ( _) => {
377- // Timeout, continue to check shutdown signal
378- continue ;
379- }
380- }
381- }
382- tracing:: info!( "🎧 FFI event listener stopped" ) ;
383- } else {
384- tracing:: error!( "❌ Failed to get event receiver from SPV client" ) ;
385- }
386- } ) ;
387- } ) ;
388-
389- // Store thread handle
390- self . active_threads . lock ( ) . unwrap ( ) . push ( handle) ;
391- }
392-
393235 /// Drain pending events and invoke configured callbacks (non-blocking).
394236 fn drain_events_internal ( & self ) {
395237 let mut rx_guard = self . event_rx . lock ( ) . unwrap ( ) ;
0 commit comments