Revert "CW-959: Swap Status on Transaction Screen (#2247)" (#2295)

This reverts commit eede8fa6c733010711176b6480e5408c738dd329.

Omar Hatem committed May 27, 2025 at 04:11 UTC 41fa97a20335f5b91738810bbb44a063649b9d5a
6 files changed +55 -322
lib/core/trade_monitor.dart deleted
-211
@@ -1,211 +0,0 @@
1 -import 'dart:async';
2 -import 'package:cake_wallet/exchange/provider/simpleswap_exchange_provider.dart';
3 -import 'package:cake_wallet/exchange/trade.dart';
4 -import 'package:cake_wallet/exchange/trade_state.dart';
5 -import 'package:cake_wallet/store/dashboard/trades_store.dart';
6 -import 'package:cake_wallet/store/settings_store.dart';
7 -import 'package:cake_wallet/entities/exchange_api_mode.dart';
8 -import 'package:cake_wallet/exchange/exchange_provider_description.dart';
9 -import 'package:cake_wallet/exchange/provider/chainflip_exchange_provider.dart';
10 -import 'package:cake_wallet/exchange/provider/changenow_exchange_provider.dart';
11 -import 'package:cake_wallet/exchange/provider/exchange_provider.dart';
12 -import 'package:cake_wallet/exchange/provider/exolix_exchange_provider.dart';
13 -import 'package:cake_wallet/exchange/provider/letsexchange_exchange_provider.dart';
14 -import 'package:cake_wallet/exchange/provider/swaptrade_exchange_provider.dart';
15 -import 'package:cake_wallet/exchange/provider/sideshift_exchange_provider.dart';
16 -import 'package:cake_wallet/exchange/provider/stealth_ex_exchange_provider.dart';
17 -import 'package:cake_wallet/exchange/provider/thorchain_exchange.provider.dart';
18 -import 'package:cake_wallet/exchange/provider/trocador_exchange_provider.dart';
19 -import 'package:cake_wallet/exchange/provider/xoswap_exchange_provider.dart';
20 -import 'package:cw_core/utils/print_verbose.dart';
21 -import 'package:hive/hive.dart';
22 -
23 -class TradeMonitor {
24 - static const int _tradeCheckIntervalMinutes = 1;
25 - static const int _maxTradeAgeHours = 24;
26 -
27 - TradeMonitor({
28 - required this.tradesStore,
29 - required this.settingsStore,
30 - required this.trades,
31 - });
32 -
33 - final TradesStore tradesStore;
34 - final Box<Trade> trades;
35 - final SettingsStore settingsStore;
36 - final Map<String, Timer> _tradeTimers = {};
37 -
38 - ExchangeProvider? _getProviderByDescription(ExchangeProviderDescription description) {
39 - switch (description) {
40 - case ExchangeProviderDescription.changeNow:
41 - return ChangeNowExchangeProvider(settingsStore: settingsStore);
42 - case ExchangeProviderDescription.sideShift:
43 - return SideShiftExchangeProvider();
44 - case ExchangeProviderDescription.simpleSwap:
45 - return SimpleSwapExchangeProvider();
46 - case ExchangeProviderDescription.trocador:
47 - return TrocadorExchangeProvider();
48 - case ExchangeProviderDescription.exolix:
49 - return ExolixExchangeProvider();
50 - case ExchangeProviderDescription.thorChain:
51 - return ThorChainExchangeProvider(tradesStore: trades);
52 - case ExchangeProviderDescription.swapTrade:
53 - return SwapTradeExchangeProvider();
54 - case ExchangeProviderDescription.letsExchange:
55 - return LetsExchangeExchangeProvider();
56 - case ExchangeProviderDescription.stealthEx:
57 - return StealthExExchangeProvider();
58 - case ExchangeProviderDescription.chainflip:
59 - return ChainflipExchangeProvider(tradesStore: trades);
60 - case ExchangeProviderDescription.xoSwap:
61 - return XOSwapExchangeProvider();
62 - }
63 - return null;
64 - }
65 -
66 - void monitorActiveTrades(String walletId) {
67 - final now = DateTime.now();
68 - final trades = tradesStore.trades;
69 - final tradesToCancel = <String>[];
70 -
71 - for (final item in trades) {
72 - final trade = item.trade;
73 -
74 - if (_shouldCancelTradeTimer(trade, walletId, now)) {
75 - if (_tradeTimers.containsKey(trade.id)) {
76 - tradesToCancel.add(trade.id);
77 - }
78 - continue;
79 - }
80 -
81 - if (!_tradeTimers.containsKey(trade.id)) {
82 - printV('Starting trade monitoring for ${trade.id}');
83 - _startTradeMonitoring(trade);
84 - }
85 - }
86 -
87 - _cancelTradeTimers(tradesToCancel);
88 - }
89 -
90 - bool _shouldCancelTradeTimer(Trade trade, String walletId, DateTime now) {
91 - if (trade.walletId != walletId) return true;
92 -
93 - final createdAt = trade.createdAt;
94 - if (createdAt == null) return true;
95 -
96 - if (now.difference(createdAt).inHours > _maxTradeAgeHours) return true;
97 -
98 - return _isFinalState(trade.state);
99 - }
100 -
101 - void _startTradeMonitoring(Trade trade) {
102 - if (_tradeTimers.containsKey(trade.id)) return;
103 -
104 - _checkTradeStatus(trade);
105 -
106 - final timer = Timer.periodic(
107 - Duration(minutes: _tradeCheckIntervalMinutes),
108 - (_) => _checkTradeStatus(trade)
109 - );
110 -
111 - _tradeTimers[trade.id] = timer;
112 - }
113 -
114 - Future<void> _checkTradeStatus(Trade trade) async {
115 - printV('Checking trade status for ${trade.id}');
116 -
117 - if (_isTradeOld(trade)) {
118 - printV('The trade ${trade.id} is older than $_maxTradeAgeHours hours, we will cancel the timer');
119 - _cancelTradeTimer(trade.id);
120 - return;
121 - }
122 -
123 - final provider = _getProviderByDescription(trade.provider);
124 - if (provider == null) {
125 - printV('No provider found for trade ${trade.id}');
126 - return;
127 - }
128 -
129 - if (!_isExchangeModeEnabled(provider)) {
130 - return;
131 - }
132 -
133 - try {
134 - await _updateTradeStatus(trade, provider);
135 - } catch (e) {
136 - printV('Error fetching status for ${trade.id}: $e');
137 - }
138 - }
139 -
140 - bool _isTradeOld(Trade trade) {
141 - final now = DateTime.now();
142 - final createdAt = trade.createdAt;
143 - return createdAt != null && now.difference(createdAt).inHours > _maxTradeAgeHours;
144 - }
145 -
146 - bool _isExchangeModeEnabled(ExchangeProvider provider) {
147 - final exchangeApiMode = settingsStore.exchangeStatus;
148 -
149 - if (exchangeApiMode == ExchangeApiMode.disabled) {
150 - printV('Exchange API mode is disabled');
151 - return false;
152 - }
153 -
154 - if (exchangeApiMode == ExchangeApiMode.torOnly && !provider.supportsOnionAddress) {
155 - printV('Skipping ${provider.description}, no TOR support');
156 - return false;
157 - }
158 -
159 - return true;
160 - }
161 -
162 - Future<void> _updateTradeStatus(Trade trade, ExchangeProvider provider) async {
163 - final updated = await provider.findTradeById(id: trade.id);
164 - trade
165 - ..stateRaw = updated.state.raw
166 - ..receiveAmount = updated.receiveAmount ?? trade.receiveAmount
167 - ..outputTransaction = updated.outputTransaction ?? trade.outputTransaction;
168 - printV('Trade ${trade.id} updated: ${trade.state}');
169 - await trade.save();
170 -
171 - if (_isFinalState(updated.state)) {
172 - printV('Trade ${trade.id} is in final state');
173 - _cancelTradeTimer(trade.id);
174 - }
175 - }
176 -
177 - void _cancelTradeTimer(String tradeId) {
178 - _tradeTimers[tradeId]?.cancel();
179 - _tradeTimers.remove(tradeId);
180 - }
181 -
182 - void _cancelTradeTimers(List<String> tradeIds) {
183 - for (final tradeId in tradeIds) {
184 - _cancelTradeTimer(tradeId);
185 - }
186 - }
187 -
188 - void cancelAllTradeTimers() {
189 - for (final timer in _tradeTimers.values) {
190 - timer.cancel();
191 - }
192 - _tradeTimers.clear();
193 - }
194 -
195 - bool _isFinalState(TradeState state) {
196 - return {
197 - TradeState.completed.raw,
198 - TradeState.success.raw,
199 - TradeState.confirmed.raw,
200 - TradeState.settled.raw,
201 - TradeState.finished.raw,
202 - TradeState.expired.raw,
203 - TradeState.failed.raw,
204 - TradeState.notFound.raw,
205 - }.contains(state.raw);
206 - }
207 -
208 - void dispose() {
209 - cancelAllTradeTimers();
210 - }
211 -}
lib/di.dart
+25 -35
@@ -275,7 +275,6 @@ import 'src/screens/buy/buy_sell_page.dart';
275 import 'cake_pay/cake_pay_payment_credantials.dart';
276 import 'package:cake_wallet/view_model/dev/background_sync_logs_view_model.dart';
277 import 'package:cake_wallet/src/screens/dev/background_sync_logs_page.dart';
278 -import 'package:cake_wallet/core/trade_monitor.dart';
278
279 final getIt = GetIt.instance;
280
@@ -508,41 +507,19 @@ Future<void> setup({
507 settingsStore: getIt.get<SettingsStore>(),
508 fiatConvertationStore: getIt.get<FiatConversionStore>()));
509
511 - getIt.registerFactory(
512 - () => ExchangeViewModel(
513 - getIt.get<AppStore>(),
514 - _tradesSource,
515 - getIt.get<ExchangeTemplateStore>(),
516 - getIt.get<TradesStore>(),
517 - getIt.get<AppStore>().settingsStore,
518 - getIt.get<SharedPreferences>(),
519 - getIt.get<ContactListViewModel>(),
520 - getIt.get<FeesViewModel>(),
521 - ),
522 - );
523 -
524 - getIt.registerSingleton(
525 - TradeMonitor(
526 - tradesStore: getIt.get<TradesStore>(),
527 - settingsStore: getIt.get<SettingsStore>(),
528 - trades: _tradesSource
529 - ),
530 - );
531 -
510 getIt.registerFactory(() => DashboardViewModel(
533 - tradeMonitor: getIt.get<TradeMonitor>(),
534 - balanceViewModel: getIt.get<BalanceViewModel>(),
535 - appStore: getIt.get<AppStore>(),
536 - tradesStore: getIt.get<TradesStore>(),
537 - tradeFilterStore: getIt.get<TradeFilterStore>(),
538 - transactionFilterStore: getIt.get<TransactionFilterStore>(),
539 - settingsStore: settingsStore,
540 - yatStore: getIt.get<YatStore>(),
541 - ordersStore: getIt.get<OrdersStore>(),
542 - anonpayTransactionsStore: getIt.get<AnonpayTransactionsStore>(),
543 - payjoinTransactionsStore: getIt.get<PayjoinTransactionsStore>(),
544 - sharedPreferences: getIt.get<SharedPreferences>(),
545 - keyService: getIt.get<KeyService>()));
511 + balanceViewModel: getIt.get<BalanceViewModel>(),
512 + appStore: getIt.get<AppStore>(),
513 + tradesStore: getIt.get<TradesStore>(),
514 + tradeFilterStore: getIt.get<TradeFilterStore>(),
515 + transactionFilterStore: getIt.get<TransactionFilterStore>(),
516 + settingsStore: settingsStore,
517 + yatStore: getIt.get<YatStore>(),
518 + ordersStore: getIt.get<OrdersStore>(),
519 + anonpayTransactionsStore: getIt.get<AnonpayTransactionsStore>(),
520 + payjoinTransactionsStore: getIt.get<PayjoinTransactionsStore>(),
521 + sharedPreferences: getIt.get<SharedPreferences>(),
522 + keyService: getIt.get<KeyService>()));
523
524 getIt.registerFactory<AuthService>(
525 () => AuthService(
@@ -1074,6 +1051,19 @@ Future<void> setup({
1051
1052 getIt.registerFactoryParam<WebViewPage, String, Uri>((title, uri) => WebViewPage(title, uri));
1053
1054 + getIt.registerFactory(
1055 + () => ExchangeViewModel(
1056 + getIt.get<AppStore>(),
1057 + _tradesSource,
1058 + getIt.get<ExchangeTemplateStore>(),
1059 + getIt.get<TradesStore>(),
1060 + getIt.get<SettingsStore>(),
1061 + getIt.get<SharedPreferences>(),
1062 + getIt.get<ContactListViewModel>(),
1063 + getIt.get<FeesViewModel>(),
1064 + ),
1065 + );
1066 +
1067 getIt.registerFactory<FeesViewModel>(
1068 () => FeesViewModel(
1069 getIt.get<AppStore>(),
lib/main.dart
-1
@@ -51,7 +51,6 @@ import 'package:cw_core/root_dir.dart';
51 import 'package:shared_preferences/shared_preferences.dart';
52 import 'package:cw_core/window_size.dart';
53 import 'package:logging/logging.dart';
54 -import 'package:cake_wallet/core/trade_monitor.dart';
54
55 final navigatorKey = GlobalKey<NavigatorState>();
56 final rootKey = GlobalKey<RootState>();
lib/src/screens/dashboard/pages/transactions_page.dart
+10 -12
@@ -166,19 +166,17 @@ class TransactionsPage extends StatelessWidget {
166
167 return Observer(
168 builder: (_) => TradeRow(
169 - key: item.key,
170 - onTap: () => Navigator.of(context)
171 - .pushNamed(Routes.tradeDetails, arguments: trade),
172 - swapState: trade.state,
169 + key: item.key,
170 + onTap: () => Navigator.of(context)
171 + .pushNamed(Routes.tradeDetails, arguments: trade),
172 provider: trade.provider,
174 - from: trade.from,
175 - to: trade.to,
176 - createdAtFormattedDate: trade.createdAt != null
177 - ? DateFormat('HH:mm').format(trade.createdAt!)
178 - : null,
179 - formattedAmount: item.tradeFormattedAmount,
180 - formattedReceiveAmount: item.tradeFormattedReceiveAmount
181 - ),
173 + from: trade.from,
174 + to: trade.to,
175 + createdAtFormattedDate: trade.createdAt != null
176 + ? DateFormat('HH:mm').format(trade.createdAt!)
177 + : null,
178 + formattedAmount: item.tradeFormattedAmount,
179 + formattedReceiveAmount: item.tradeFormattedReceiveAmount),
180 );
181 }
182 if (item is OrderListItem) {
lib/src/screens/dashboard/widgets/trade_row.dart
+19 -54
@@ -1,9 +1,7 @@
1 -import 'package:cake_wallet/exchange/trade_state.dart';
2 -import 'package:cake_wallet/palette.dart';
1 import 'package:cake_wallet/utils/image_utill.dart';
2 import 'package:flutter/material.dart';
5 -import 'package:cake_wallet/exchange/exchange_provider_description.dart';
3 import 'package:cw_core/crypto_currency.dart';
4 +import 'package:cake_wallet/exchange/exchange_provider_description.dart';
5
6 class TradeRow extends StatelessWidget {
7 TradeRow({
@@ -14,7 +12,6 @@ class TradeRow extends StatelessWidget {
12 this.onTap,
13 this.formattedAmount,
14 this.formattedReceiveAmount,
17 - required this.swapState,
15 super.key,
16 });
17
@@ -25,7 +22,6 @@ class TradeRow extends StatelessWidget {
22 final String? createdAtFormattedDate;
23 final String? formattedAmount;
24 final String? formattedReceiveAmount;
28 - final TradeState swapState;
25
26 @override
27 Widget build(BuildContext context) {
@@ -33,39 +29,25 @@ class TradeRow extends StatelessWidget {
29 final receiveAmountCrypto = to.toString();
30
31 return InkWell(
36 - onTap: onTap,
37 - child: Container(
38 - padding: EdgeInsets.fromLTRB(24, 8, 24, 8),
39 - color: Colors.transparent,
40 - child: Row(
41 - mainAxisSize: MainAxisSize.max,
42 - crossAxisAlignment: CrossAxisAlignment.center,
43 - children: [
44 - Stack(
45 - clipBehavior: Clip.none,
46 - children: [
47 - ClipRRect(
48 - borderRadius: BorderRadius.circular(50),
49 - child: ImageUtil.getImageFromPath(
50 - imagePath: provider.image, height: 36, width: 36),),
51 - Positioned(
52 - right: 0,
53 - bottom: 2,
54 - child: Container(
55 - height: 8,
56 - width: 8,
57 - padding: EdgeInsets.symmetric(horizontal: 8, vertical: 2),
58 - decoration: BoxDecoration(
59 - color: _statusColor(context, swapState),
60 - borderRadius: BorderRadius.circular(12),
61 - ),
62 - ),
63 - ),
64 - ],
32 + onTap: onTap,
33 + child: Container(
34 + padding: EdgeInsets.fromLTRB(24, 8, 24, 8),
35 + color: Colors.transparent,
36 + child: Row(
37 + mainAxisSize: MainAxisSize.max,
38 + crossAxisAlignment: CrossAxisAlignment.center,
39 + children: [
40 + ClipRRect(
41 + borderRadius: BorderRadius.circular(50),
42 + child: ImageUtil.getImageFromPath(
43 + imagePath: provider.image,
44 + height: 36,
45 + width: 36,
46 ),
66 - SizedBox(width: 12),
67 - Expanded(
68 - child: Column(
47 + ),
48 + SizedBox(width: 12),
49 + Expanded(
50 + child: Column(
51 mainAxisSize: MainAxisSize.min,
52 children: [
53 Row(
@@ -122,21 +104,4 @@ class TradeRow extends StatelessWidget {
104 ),
105 );
106 }
125 -
126 - Color _statusColor(BuildContext context, TradeState status) {
127 - switch (status) {
128 - case TradeState.complete:
129 - case TradeState.completed:
130 - case TradeState.finished:
131 - case TradeState.success:
132 - case TradeState.settled:
133 - return PaletteDark.brightGreen;
134 - case TradeState.failed:
135 - case TradeState.expired:
136 - case TradeState.notFound:
137 - return Palette.darkRed;
138 - default:
139 - return const Color(0xffff6600);
140 - }
141 - }
107 }
lib/view_model/dashboard/dashboard_view_model.dart
+1 -9
@@ -23,6 +23,7 @@ import 'package:cake_wallet/store/dashboard/trades_store.dart';
23 import 'package:cake_wallet/store/dashboard/transaction_filter_store.dart';
24 import 'package:cake_wallet/store/settings_store.dart';
25 import 'package:cake_wallet/store/yat/yat_store.dart';
26 +import 'package:cake_wallet/themes/core/material_base_theme.dart';
27 import 'package:cake_wallet/view_model/dashboard/action_list_item.dart';
28 import 'package:cake_wallet/view_model/dashboard/anonpay_transaction_list_item.dart';
29 import 'package:cake_wallet/view_model/dashboard/balance_view_model.dart';
@@ -55,8 +56,6 @@ import 'package:mobx/mobx.dart';
56 import 'package:permission_handler/permission_handler.dart';
57 import 'package:shared_preferences/shared_preferences.dart';
58
58 -import 'package:cake_wallet/core/trade_monitor.dart';
59 -
59 part 'dashboard_view_model.g.dart';
60
61 class DashboardViewModel = DashboardViewModelBase with _$DashboardViewModel;
@@ -64,7 +63,6 @@ class DashboardViewModel = DashboardViewModelBase with _$DashboardViewModel;
63 abstract class DashboardViewModelBase with Store {
64 DashboardViewModelBase(
65 {required this.balanceViewModel,
67 - required this.tradeMonitor,
66 required this.appStore,
67 required this.tradesStore,
68 required this.tradeFilterStore,
@@ -300,10 +298,6 @@ abstract class DashboardViewModelBase with Store {
298
299 _checkMweb();
300 reaction((_) => settingsStore.mwebAlwaysScan, (bool value) => _checkMweb());
303 -
304 - reaction((_) => tradesStore.trades, (_) => tradeMonitor.monitorActiveTrades(wallet.id));
305 -
306 - tradeMonitor.monitorActiveTrades(wallet.id);
301 }
302
303 bool _isTransactionDisposerCallbackRunning = false;
@@ -779,8 +773,6 @@ abstract class DashboardViewModelBase with Store {
773
774 BalanceViewModel balanceViewModel;
775
782 - TradeMonitor tradeMonitor;
783 -
776 AppStore appStore;
777
778 SettingsStore settingsStore;