diff --git a/packages/komodo_defi_local_auth/lib/src/trezor/trezor_connection_monitor.dart b/packages/komodo_defi_local_auth/lib/src/trezor/trezor_connection_monitor.dart index 4aee6a80..909d57be 100644 --- a/packages/komodo_defi_local_auth/lib/src/trezor/trezor_connection_monitor.dart +++ b/packages/komodo_defi_local_auth/lib/src/trezor/trezor_connection_monitor.dart @@ -23,9 +23,11 @@ class TrezorConnectionMonitor { /// [onConnectionRestored] will be called when the device becomes connected /// after being disconnected/unreachable. /// [onStatusChanged] will be called for any status change. + /// [maxDuration] sets the maximum time to monitor before timing out. void startMonitoring({ String? devicePubkey, Duration pollInterval = const Duration(seconds: 1), + Duration maxDuration = const Duration(minutes: 30), VoidCallback? onConnectionLost, VoidCallback? onConnectionRestored, void Function(TrezorConnectionStatus)? onStatusChanged, @@ -38,6 +40,7 @@ class TrezorConnectionMonitor { .watchConnectionStatus( devicePubkey: devicePubkey, pollInterval: pollInterval, + maxDuration: maxDuration, ) .listen( (status) { @@ -60,9 +63,12 @@ class TrezorConnectionMonitor { onConnectionRestored?.call(); } }, - onError: (Object error) { - _log.severe('Error monitoring Trezor connection: $error'); - onConnectionLost?.call(); + onError: (Object error, StackTrace stackTrace) { + _log.severe('Error monitoring Trezor connection: $error', error, stackTrace); + // Only call onConnectionLost if this is a real connection error, not a disposal + if (_connectionSubscription != null) { + onConnectionLost?.call(); + } }, onDone: () { _log.info('Trezor connection monitoring stopped'); diff --git a/packages/komodo_defi_local_auth/lib/src/trezor/trezor_connection_status.dart b/packages/komodo_defi_local_auth/lib/src/trezor/trezor_connection_status.dart index 2410ec4a..c84fe5c4 100644 --- a/packages/komodo_defi_local_auth/lib/src/trezor/trezor_connection_status.dart +++ b/packages/komodo_defi_local_auth/lib/src/trezor/trezor_connection_status.dart @@ -53,7 +53,8 @@ enum TrezorConnectionStatus { /// Check if the status indicates the device is not available bool get isUnavailable => this == TrezorConnectionStatus.disconnected || - this == TrezorConnectionStatus.unreachable; + this == TrezorConnectionStatus.unreachable || + this == TrezorConnectionStatus.busy; /// Check if the device should continue being monitored bool get shouldContinueMonitoring => diff --git a/packages/komodo_defi_local_auth/lib/src/trezor/trezor_repository.dart b/packages/komodo_defi_local_auth/lib/src/trezor/trezor_repository.dart index 103022ed..b582c794 100644 --- a/packages/komodo_defi_local_auth/lib/src/trezor/trezor_repository.dart +++ b/packages/komodo_defi_local_auth/lib/src/trezor/trezor_repository.dart @@ -209,12 +209,15 @@ class TrezorRepository { /// /// The stream immediately yields the current status, then continues to poll /// using [pollInterval]. If the status changes, a new value is emitted. The - /// stream closes once a `Disconnected` status is observed. + /// stream closes once a `Disconnected` status is observed or [maxDuration] is reached. Stream watchConnectionStatus({ String? devicePubkey, Duration pollInterval = const Duration(seconds: 1), + Duration maxDuration = const Duration(minutes: 30), }) async* { TrezorConnectionStatus? last; + final stopwatch = Stopwatch()..start(); + try { last = await getConnectionStatus(devicePubkey: devicePubkey); yield last; @@ -226,7 +229,7 @@ class TrezorRepository { ); } - while (last!.shouldContinueMonitoring) { + while (last!.shouldContinueMonitoring && stopwatch.elapsed < maxDuration) { await Future.delayed(pollInterval); try { final current = await getConnectionStatus(devicePubkey: devicePubkey); @@ -239,6 +242,10 @@ class TrezorRepository { return; } } + + if (stopwatch.elapsed >= maxDuration) { + yield TrezorConnectionStatus.unreachable; + } } /// Cancel all active initializations and clean up resources