CW-959: Swap Status on Transaction Screen (#2299)

* feat(swap-status-monitor): add real-time swap status monitoring and UI updates

- Introduce SwapManager for automatic tracking of active-wallet swaps.
- Automatically queues new or updated trades from the Hive box.
- Periodically fetch and persist swap statuses via the corresponding trade provider.
- Implement start(wallet, providers), stop(), and dispose() for lifecycle control.
- Apply user's ExchangeApiMode(disabled, tor-only, enabled) when fetching updates.
- Remove swaps from the watchlist on any final state (completed, expired, failed).
- Dispose SwapManager in AppState.dispose() to cancel polling and the Hive subscription.

* refactor(swap-status): replace SwapManager with TradeMonitor for improved trade monitoring.

This change improves the flow by simplifying the trade monitoring logic.

- Removes SwapManager class and replace with TradeMonitor implementation
- Update di and Appstate to register and dispose TradeMonitor
- Modify DashboardViewModel to use TradeMonitor instead of SwapManager

* fix: Modify trade monitoring logic to ensure trade timers are properly disposed when wallet switching occurs

* fix(swap-status): Fix receive amount for exchanges showing as .00 because of null values

* feat(swap-status): Enhance Trade Monitoring

This change:
- Adds a privacy settings option to disable automatic exchange status updates.
- Prevents trade monitoring when privacy settings option is enabled.
- Disables trade monitoring when the app is in background, we only want to run these checks in foreground.
- Refactors the trade monitoring logic to remove unneccessary checks and use of resources.

* feat(swap-status): Enhance Trade Monitoring

This change:
- Adds a privacy settings option to disable automatic exchange status updates.
- Prevents trade monitoring when privacy settings option is enabled.
- Disables trade monitoring when the app is in background, we only want to run these checks in foreground.
- Refactors the trade monitoring logic to remove unneccessary checks and use of resources.

* fix(swap-staus): Prevent unneccessary calls

* feat(swap-status): Prevent api request calls as long as last update time is less than specified interval
This commit is contained in:
David Adegoke
2025-06-04 18:24:56 +03:00
committed by GitHub
parent 1134915920
commit 1d6e594e04
39 changed files with 455 additions and 82 deletions
@@ -23,7 +23,6 @@ import 'package:cake_wallet/store/dashboard/trades_store.dart';
import 'package:cake_wallet/store/dashboard/transaction_filter_store.dart';
import 'package:cake_wallet/store/settings_store.dart';
import 'package:cake_wallet/store/yat/yat_store.dart';
import 'package:cake_wallet/themes/core/material_base_theme.dart';
import 'package:cake_wallet/view_model/dashboard/action_list_item.dart';
import 'package:cake_wallet/view_model/dashboard/anonpay_transaction_list_item.dart';
import 'package:cake_wallet/view_model/dashboard/balance_view_model.dart';
@@ -56,6 +55,8 @@ import 'package:mobx/mobx.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:cake_wallet/core/trade_monitor.dart';
part 'dashboard_view_model.g.dart';
class DashboardViewModel = DashboardViewModelBase with _$DashboardViewModel;
@@ -63,6 +64,7 @@ class DashboardViewModel = DashboardViewModelBase with _$DashboardViewModel;
abstract class DashboardViewModelBase with Store {
DashboardViewModelBase(
{required this.balanceViewModel,
required this.tradeMonitor,
required this.appStore,
required this.tradesStore,
required this.tradeFilterStore,
@@ -270,6 +272,9 @@ abstract class DashboardViewModelBase with Store {
_checkMweb();
showDecredInfoCard = wallet?.type == WalletType.decred &&
sharedPreferences.getBool(PreferencesKey.showDecredInfoCard) != false;
tradeMonitor.stopTradeMonitoring();
tradeMonitor.monitorActiveTrades(wallet!.id);
});
_transactionDisposer?.reaction.dispose();
@@ -298,6 +303,10 @@ abstract class DashboardViewModelBase with Store {
_checkMweb();
reaction((_) => settingsStore.mwebAlwaysScan, (bool value) => _checkMweb());
reaction((_) => tradesStore.trades, (_) => tradeMonitor.monitorActiveTrades(wallet.id));
tradeMonitor.monitorActiveTrades(wallet.id);
}
bool _isTransactionDisposerCallbackRunning = false;
@@ -773,6 +782,8 @@ abstract class DashboardViewModelBase with Store {
BalanceViewModel balanceViewModel;
TradeMonitor tradeMonitor;
AppStore appStore;
SettingsStore settingsStore;
@@ -33,9 +33,8 @@ abstract class PrivacySettingsViewModelBase with Store {
@action
void setAutoGenerateSubaddresses(bool value) {
_wallet.isEnabledAutoGenerateSubaddress = value;
_settingsStore.autoGenerateSubaddressStatus = value
? AutoGenerateSubaddressStatus.enabled
: AutoGenerateSubaddressStatus.disabled;
_settingsStore.autoGenerateSubaddressStatus =
value ? AutoGenerateSubaddressStatus.enabled : AutoGenerateSubaddressStatus.disabled;
}
bool get isAutoGenerateSubaddressesVisible => [
@@ -61,6 +60,10 @@ abstract class PrivacySettingsViewModelBase with Store {
@computed
bool get disableTradeOption => _settingsStore.disableTradeOption;
@computed
bool get disableAutomaticExchangeStatusUpdates =>
_settingsStore.disableAutomaticExchangeStatusUpdates;
@computed
bool get disableBulletin => _settingsStore.disableBulletin;
@@ -129,6 +132,10 @@ abstract class PrivacySettingsViewModelBase with Store {
@action
void setDisableTradeOption(bool value) => _settingsStore.disableTradeOption = value;
@action
void setDisableAutomaticExchangeStatusUpdates(bool value) =>
_settingsStore.disableAutomaticExchangeStatusUpdates = value;
@action
void setDisableBulletin(bool value) => _settingsStore.disableBulletin = value;
@@ -146,7 +153,7 @@ abstract class PrivacySettingsViewModelBase with Store {
@action
void setLookupsWellKnown(bool value) => _settingsStore.lookupsWellKnown = value;
@action
void setLookupsYatService(bool value) => _settingsStore.lookupsYatService = value;
@@ -175,8 +182,7 @@ abstract class PrivacySettingsViewModelBase with Store {
}
@action
void setUseMempoolFeeAPI(bool value) =>
_settingsStore.useMempoolFeeAPI = value;
void setUseMempoolFeeAPI(bool value) => _settingsStore.useMempoolFeeAPI = value;
@action
void setUsePayjoin(bool value) {