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

This reverts commit eede8fa6c7.
This commit is contained in:
Omar Hatem 2025-05-27 04:11:26 +03:00 committed by GitHub
parent 2f2b45f844
commit 41fa97a203
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 55 additions and 322 deletions

View file

@ -1,211 +0,0 @@
import 'dart:async';
import 'package:cake_wallet/exchange/provider/simpleswap_exchange_provider.dart';
import 'package:cake_wallet/exchange/trade.dart';
import 'package:cake_wallet/exchange/trade_state.dart';
import 'package:cake_wallet/store/dashboard/trades_store.dart';
import 'package:cake_wallet/store/settings_store.dart';
import 'package:cake_wallet/entities/exchange_api_mode.dart';
import 'package:cake_wallet/exchange/exchange_provider_description.dart';
import 'package:cake_wallet/exchange/provider/chainflip_exchange_provider.dart';
import 'package:cake_wallet/exchange/provider/changenow_exchange_provider.dart';
import 'package:cake_wallet/exchange/provider/exchange_provider.dart';
import 'package:cake_wallet/exchange/provider/exolix_exchange_provider.dart';
import 'package:cake_wallet/exchange/provider/letsexchange_exchange_provider.dart';
import 'package:cake_wallet/exchange/provider/swaptrade_exchange_provider.dart';
import 'package:cake_wallet/exchange/provider/sideshift_exchange_provider.dart';
import 'package:cake_wallet/exchange/provider/stealth_ex_exchange_provider.dart';
import 'package:cake_wallet/exchange/provider/thorchain_exchange.provider.dart';
import 'package:cake_wallet/exchange/provider/trocador_exchange_provider.dart';
import 'package:cake_wallet/exchange/provider/xoswap_exchange_provider.dart';
import 'package:cw_core/utils/print_verbose.dart';
import 'package:hive/hive.dart';
class TradeMonitor {
static const int _tradeCheckIntervalMinutes = 1;
static const int _maxTradeAgeHours = 24;
TradeMonitor({
required this.tradesStore,
required this.settingsStore,
required this.trades,
});
final TradesStore tradesStore;
final Box<Trade> trades;
final SettingsStore settingsStore;
final Map<String, Timer> _tradeTimers = {};
ExchangeProvider? _getProviderByDescription(ExchangeProviderDescription description) {
switch (description) {
case ExchangeProviderDescription.changeNow:
return ChangeNowExchangeProvider(settingsStore: settingsStore);
case ExchangeProviderDescription.sideShift:
return SideShiftExchangeProvider();
case ExchangeProviderDescription.simpleSwap:
return SimpleSwapExchangeProvider();
case ExchangeProviderDescription.trocador:
return TrocadorExchangeProvider();
case ExchangeProviderDescription.exolix:
return ExolixExchangeProvider();
case ExchangeProviderDescription.thorChain:
return ThorChainExchangeProvider(tradesStore: trades);
case ExchangeProviderDescription.swapTrade:
return SwapTradeExchangeProvider();
case ExchangeProviderDescription.letsExchange:
return LetsExchangeExchangeProvider();
case ExchangeProviderDescription.stealthEx:
return StealthExExchangeProvider();
case ExchangeProviderDescription.chainflip:
return ChainflipExchangeProvider(tradesStore: trades);
case ExchangeProviderDescription.xoSwap:
return XOSwapExchangeProvider();
}
return null;
}
void monitorActiveTrades(String walletId) {
final now = DateTime.now();
final trades = tradesStore.trades;
final tradesToCancel = <String>[];
for (final item in trades) {
final trade = item.trade;
if (_shouldCancelTradeTimer(trade, walletId, now)) {
if (_tradeTimers.containsKey(trade.id)) {
tradesToCancel.add(trade.id);
}
continue;
}
if (!_tradeTimers.containsKey(trade.id)) {
printV('Starting trade monitoring for ${trade.id}');
_startTradeMonitoring(trade);
}
}
_cancelTradeTimers(tradesToCancel);
}
bool _shouldCancelTradeTimer(Trade trade, String walletId, DateTime now) {
if (trade.walletId != walletId) return true;
final createdAt = trade.createdAt;
if (createdAt == null) return true;
if (now.difference(createdAt).inHours > _maxTradeAgeHours) return true;
return _isFinalState(trade.state);
}
void _startTradeMonitoring(Trade trade) {
if (_tradeTimers.containsKey(trade.id)) return;
_checkTradeStatus(trade);
final timer = Timer.periodic(
Duration(minutes: _tradeCheckIntervalMinutes),
(_) => _checkTradeStatus(trade)
);
_tradeTimers[trade.id] = timer;
}
Future<void> _checkTradeStatus(Trade trade) async {
printV('Checking trade status for ${trade.id}');
if (_isTradeOld(trade)) {
printV('The trade ${trade.id} is older than $_maxTradeAgeHours hours, we will cancel the timer');
_cancelTradeTimer(trade.id);
return;
}
final provider = _getProviderByDescription(trade.provider);
if (provider == null) {
printV('No provider found for trade ${trade.id}');
return;
}
if (!_isExchangeModeEnabled(provider)) {
return;
}
try {
await _updateTradeStatus(trade, provider);
} catch (e) {
printV('Error fetching status for ${trade.id}: $e');
}
}
bool _isTradeOld(Trade trade) {
final now = DateTime.now();
final createdAt = trade.createdAt;
return createdAt != null && now.difference(createdAt).inHours > _maxTradeAgeHours;
}
bool _isExchangeModeEnabled(ExchangeProvider provider) {
final exchangeApiMode = settingsStore.exchangeStatus;
if (exchangeApiMode == ExchangeApiMode.disabled) {
printV('Exchange API mode is disabled');
return false;
}
if (exchangeApiMode == ExchangeApiMode.torOnly && !provider.supportsOnionAddress) {
printV('Skipping ${provider.description}, no TOR support');
return false;
}
return true;
}
Future<void> _updateTradeStatus(Trade trade, ExchangeProvider provider) async {
final updated = await provider.findTradeById(id: trade.id);
trade
..stateRaw = updated.state.raw
..receiveAmount = updated.receiveAmount ?? trade.receiveAmount
..outputTransaction = updated.outputTransaction ?? trade.outputTransaction;
printV('Trade ${trade.id} updated: ${trade.state}');
await trade.save();
if (_isFinalState(updated.state)) {
printV('Trade ${trade.id} is in final state');
_cancelTradeTimer(trade.id);
}
}
void _cancelTradeTimer(String tradeId) {
_tradeTimers[tradeId]?.cancel();
_tradeTimers.remove(tradeId);
}
void _cancelTradeTimers(List<String> tradeIds) {
for (final tradeId in tradeIds) {
_cancelTradeTimer(tradeId);
}
}
void cancelAllTradeTimers() {
for (final timer in _tradeTimers.values) {
timer.cancel();
}
_tradeTimers.clear();
}
bool _isFinalState(TradeState state) {
return {
TradeState.completed.raw,
TradeState.success.raw,
TradeState.confirmed.raw,
TradeState.settled.raw,
TradeState.finished.raw,
TradeState.expired.raw,
TradeState.failed.raw,
TradeState.notFound.raw,
}.contains(state.raw);
}
void dispose() {
cancelAllTradeTimers();
}
}

View file

@ -275,7 +275,6 @@ import 'src/screens/buy/buy_sell_page.dart';
import 'cake_pay/cake_pay_payment_credantials.dart';
import 'package:cake_wallet/view_model/dev/background_sync_logs_view_model.dart';
import 'package:cake_wallet/src/screens/dev/background_sync_logs_page.dart';
import 'package:cake_wallet/core/trade_monitor.dart';
final getIt = GetIt.instance;
@ -508,41 +507,19 @@ Future<void> setup({
settingsStore: getIt.get<SettingsStore>(),
fiatConvertationStore: getIt.get<FiatConversionStore>()));
getIt.registerFactory(
() => ExchangeViewModel(
getIt.get<AppStore>(),
_tradesSource,
getIt.get<ExchangeTemplateStore>(),
getIt.get<TradesStore>(),
getIt.get<AppStore>().settingsStore,
getIt.get<SharedPreferences>(),
getIt.get<ContactListViewModel>(),
getIt.get<FeesViewModel>(),
),
);
getIt.registerSingleton(
TradeMonitor(
tradesStore: getIt.get<TradesStore>(),
settingsStore: getIt.get<SettingsStore>(),
trades: _tradesSource
),
);
getIt.registerFactory(() => DashboardViewModel(
tradeMonitor: getIt.get<TradeMonitor>(),
balanceViewModel: getIt.get<BalanceViewModel>(),
appStore: getIt.get<AppStore>(),
tradesStore: getIt.get<TradesStore>(),
tradeFilterStore: getIt.get<TradeFilterStore>(),
transactionFilterStore: getIt.get<TransactionFilterStore>(),
settingsStore: settingsStore,
yatStore: getIt.get<YatStore>(),
ordersStore: getIt.get<OrdersStore>(),
anonpayTransactionsStore: getIt.get<AnonpayTransactionsStore>(),
payjoinTransactionsStore: getIt.get<PayjoinTransactionsStore>(),
sharedPreferences: getIt.get<SharedPreferences>(),
keyService: getIt.get<KeyService>()));
balanceViewModel: getIt.get<BalanceViewModel>(),
appStore: getIt.get<AppStore>(),
tradesStore: getIt.get<TradesStore>(),
tradeFilterStore: getIt.get<TradeFilterStore>(),
transactionFilterStore: getIt.get<TransactionFilterStore>(),
settingsStore: settingsStore,
yatStore: getIt.get<YatStore>(),
ordersStore: getIt.get<OrdersStore>(),
anonpayTransactionsStore: getIt.get<AnonpayTransactionsStore>(),
payjoinTransactionsStore: getIt.get<PayjoinTransactionsStore>(),
sharedPreferences: getIt.get<SharedPreferences>(),
keyService: getIt.get<KeyService>()));
getIt.registerFactory<AuthService>(
() => AuthService(
@ -1074,6 +1051,19 @@ Future<void> setup({
getIt.registerFactoryParam<WebViewPage, String, Uri>((title, uri) => WebViewPage(title, uri));
getIt.registerFactory(
() => ExchangeViewModel(
getIt.get<AppStore>(),
_tradesSource,
getIt.get<ExchangeTemplateStore>(),
getIt.get<TradesStore>(),
getIt.get<SettingsStore>(),
getIt.get<SharedPreferences>(),
getIt.get<ContactListViewModel>(),
getIt.get<FeesViewModel>(),
),
);
getIt.registerFactory<FeesViewModel>(
() => FeesViewModel(
getIt.get<AppStore>(),

View file

@ -51,7 +51,6 @@ import 'package:cw_core/root_dir.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:cw_core/window_size.dart';
import 'package:logging/logging.dart';
import 'package:cake_wallet/core/trade_monitor.dart';
final navigatorKey = GlobalKey<NavigatorState>();
final rootKey = GlobalKey<RootState>();

View file

@ -166,19 +166,17 @@ class TransactionsPage extends StatelessWidget {
return Observer(
builder: (_) => TradeRow(
key: item.key,
onTap: () => Navigator.of(context)
.pushNamed(Routes.tradeDetails, arguments: trade),
swapState: trade.state,
key: item.key,
onTap: () => Navigator.of(context)
.pushNamed(Routes.tradeDetails, arguments: trade),
provider: trade.provider,
from: trade.from,
to: trade.to,
createdAtFormattedDate: trade.createdAt != null
? DateFormat('HH:mm').format(trade.createdAt!)
: null,
formattedAmount: item.tradeFormattedAmount,
formattedReceiveAmount: item.tradeFormattedReceiveAmount
),
from: trade.from,
to: trade.to,
createdAtFormattedDate: trade.createdAt != null
? DateFormat('HH:mm').format(trade.createdAt!)
: null,
formattedAmount: item.tradeFormattedAmount,
formattedReceiveAmount: item.tradeFormattedReceiveAmount),
);
}
if (item is OrderListItem) {

View file

@ -1,9 +1,7 @@
import 'package:cake_wallet/exchange/trade_state.dart';
import 'package:cake_wallet/palette.dart';
import 'package:cake_wallet/utils/image_utill.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/exchange/exchange_provider_description.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cake_wallet/exchange/exchange_provider_description.dart';
class TradeRow extends StatelessWidget {
TradeRow({
@ -14,7 +12,6 @@ class TradeRow extends StatelessWidget {
this.onTap,
this.formattedAmount,
this.formattedReceiveAmount,
required this.swapState,
super.key,
});
@ -25,7 +22,6 @@ class TradeRow extends StatelessWidget {
final String? createdAtFormattedDate;
final String? formattedAmount;
final String? formattedReceiveAmount;
final TradeState swapState;
@override
Widget build(BuildContext context) {
@ -33,39 +29,25 @@ class TradeRow extends StatelessWidget {
final receiveAmountCrypto = to.toString();
return InkWell(
onTap: onTap,
child: Container(
padding: EdgeInsets.fromLTRB(24, 8, 24, 8),
color: Colors.transparent,
child: Row(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Stack(
clipBehavior: Clip.none,
children: [
ClipRRect(
borderRadius: BorderRadius.circular(50),
child: ImageUtil.getImageFromPath(
imagePath: provider.image, height: 36, width: 36),),
Positioned(
right: 0,
bottom: 2,
child: Container(
height: 8,
width: 8,
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 2),
decoration: BoxDecoration(
color: _statusColor(context, swapState),
borderRadius: BorderRadius.circular(12),
),
),
),
],
onTap: onTap,
child: Container(
padding: EdgeInsets.fromLTRB(24, 8, 24, 8),
color: Colors.transparent,
child: Row(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
ClipRRect(
borderRadius: BorderRadius.circular(50),
child: ImageUtil.getImageFromPath(
imagePath: provider.image,
height: 36,
width: 36,
),
SizedBox(width: 12),
Expanded(
child: Column(
),
SizedBox(width: 12),
Expanded(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Row(
@ -122,21 +104,4 @@ class TradeRow extends StatelessWidget {
),
);
}
Color _statusColor(BuildContext context, TradeState status) {
switch (status) {
case TradeState.complete:
case TradeState.completed:
case TradeState.finished:
case TradeState.success:
case TradeState.settled:
return PaletteDark.brightGreen;
case TradeState.failed:
case TradeState.expired:
case TradeState.notFound:
return Palette.darkRed;
default:
return const Color(0xffff6600);
}
}
}

View file

@ -23,6 +23,7 @@ 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';
@ -55,8 +56,6 @@ 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;
@ -64,7 +63,6 @@ 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,
@ -300,10 +298,6 @@ 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;
@ -779,8 +773,6 @@ abstract class DashboardViewModelBase with Store {
BalanceViewModel balanceViewModel;
TradeMonitor tradeMonitor;
AppStore appStore;
SettingsStore settingsStore;