Cw 897 stable coins exchanges rate issue (#1939)

* update amount in UI when best rate changes * minor fixes * update rate when amount has changed

Serhii committed Jan 24, 2025 at 20:03 UTC c88809133f9029c8ed2e04008477db5355bb6958
5 files changed +36 -21
lib/exchange/provider/letsexchange_exchange_provider.dart
+2 -1
@@ -11,6 +11,7 @@ import 'package:cake_wallet/exchange/trade_request.dart';
11 import 'package:cake_wallet/exchange/trade_state.dart';
12 import 'package:cake_wallet/exchange/utils/currency_pairs_utils.dart';
13 import 'package:cw_core/crypto_currency.dart';
14 +import 'package:cw_core/utils/print_verbose.dart';
15 import 'package:http/http.dart' as http;
16
17 class LetsExchangeExchangeProvider extends ExchangeProvider {
@@ -101,7 +102,7 @@ class LetsExchangeExchangeProvider extends ExchangeProvider {
102
103 return isFixedRateMode ? amount / amountToGet : amountToGet / amount;
104 } catch (e) {
104 - log(e.toString());
105 + printV(e.toString());
106 return 0.0;
107 }
108 }
lib/exchange/provider/sideshift_exchange_provider.dart
+2 -1
@@ -12,6 +12,7 @@ import 'package:cake_wallet/exchange/trade_request.dart';
12 import 'package:cake_wallet/exchange/trade_state.dart';
13 import 'package:cake_wallet/exchange/utils/currency_pairs_utils.dart';
14 import 'package:cw_core/crypto_currency.dart';
15 +import 'package:cw_core/utils/print_verbose.dart';
16 import 'package:http/http.dart';
17
18 class SideShiftExchangeProvider extends ExchangeProvider {
@@ -152,7 +153,7 @@ class SideShiftExchangeProvider extends ExchangeProvider {
153
154 return double.parse(responseJSON['rate'] as String);
155 } catch (e) {
155 - log('Error fetching rate in SideShift Provider: ${e.toString()}');
156 + printV(e.toString());
157 return 0.00;
158 }
159 }
lib/exchange/provider/trocador_exchange_provider.dart
+3
@@ -138,6 +138,9 @@ class TrocadorExchangeProvider extends ExchangeProvider {
138 final response = await get(uri, headers: {'API-Key': apiKey});
139
140 final responseJSON = json.decode(response.body) as Map<String, dynamic>;
141 +
142 + if (responseJSON['error'] != null) throw Exception(responseJSON['error']);
143 +
144 final fromAmount = double.parse(responseJSON['amount_from'].toString());
145 final toAmount = double.parse(responseJSON['amount_to'].toString());
146 final rateId = responseJSON['trade_id'] as String? ?? '';
lib/src/screens/exchange/exchange_page.dart
+10
@@ -478,6 +478,14 @@ class ExchangePage extends BasePage {
478 }
479 });
480
481 + reaction((_) => exchangeViewModel.bestRate, (double rate) {
482 + if (exchangeViewModel.isFixedRateMode) {
483 + exchangeViewModel.changeReceiveAmount(amount: receiveAmountController.text);
484 + } else {
485 + exchangeViewModel.changeDepositAmount(amount: depositAmountController.text);
486 + }
487 + });
488 +
489 depositAddressController
490 .addListener(() => exchangeViewModel.depositAddress = depositAddressController.text);
491
@@ -493,6 +501,7 @@ class ExchangePage extends BasePage {
501 : Debounce(Duration(milliseconds: 500));
502
503 _depositAmountDebounce.run(() {
504 + exchangeViewModel.calculateBestRate();
505 exchangeViewModel.changeDepositAmount(amount: depositAmountController.text);
506 exchangeViewModel.isReceiveAmountEntered = false;
507 });
@@ -505,6 +514,7 @@ class ExchangePage extends BasePage {
514 receiveAmountController.addListener(() {
515 if (receiveAmountController.text != exchangeViewModel.receiveAmount) {
516 _receiveAmountDebounce.run(() {
517 + exchangeViewModel.calculateBestRate();
518 exchangeViewModel.changeReceiveAmount(amount: receiveAmountController.text);
519 exchangeViewModel.isReceiveAmountEntered = true;
520 });
lib/view_model/exchange/exchange_view_model.dart
+19 -19
@@ -115,9 +115,9 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
115 .toList());
116
117 _setAvailableProviders();
118 - _calculateBestRate();
118 + calculateBestRate();
119
120 - bestRateSync = Timer.periodic(Duration(seconds: 10), (timer) => _calculateBestRate());
120 + bestRateSync = Timer.periodic(Duration(seconds: 10), (timer) => calculateBestRate());
121
122 isDepositAddressEnabled = !(depositCurrency == wallet.currency);
123 depositAmount = '';
@@ -144,8 +144,8 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
144 loadLimits();
145 reaction((_) => isFixedRateMode, (Object _) {
146 loadLimits();
147 - _bestRate = 0;
148 - _calculateBestRate();
147 + bestRate = 0;
148 + calculateBestRate();
149 });
150
151 if (isElectrumWallet) {
@@ -334,7 +334,8 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
334
335 final ContactListViewModel contactListViewModel;
336
337 - double _bestRate = 0.0;
337 + @observable
338 + double bestRate = 0.0;
339
340 late Timer bestRateSync;
341
@@ -366,15 +367,15 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
367
368 final _enteredAmount = double.tryParse(amount.replaceAll(',', '.')) ?? 0;
369
369 - if (_bestRate == 0) {
370 + if (bestRate == 0) {
371 depositAmount = S.current.fetching;
372
372 - await _calculateBestRate();
373 + await calculateBestRate();
374 }
375 _cryptoNumberFormat.maximumFractionDigits = depositMaxDigits;
376
377 depositAmount = _cryptoNumberFormat
377 - .format(_enteredAmount / _bestRate)
378 + .format(_enteredAmount / bestRate)
379 .toString()
380 .replaceAll(RegExp('\\,'), '');
381 }
@@ -392,15 +393,15 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
393 final _enteredAmount = double.tryParse(amount.replaceAll(',', '.')) ?? 0;
394
395 /// in case the best rate was not calculated yet
395 - if (_bestRate == 0) {
396 + if (bestRate == 0) {
397 receiveAmount = S.current.fetching;
398
398 - await _calculateBestRate();
399 + await calculateBestRate();
400 }
401 _cryptoNumberFormat.maximumFractionDigits = receiveMaxDigits;
402
403 receiveAmount = _cryptoNumberFormat
403 - .format(_bestRate * _enteredAmount)
404 + .format(bestRate * _enteredAmount)
405 .toString()
406 .replaceAll(RegExp('\\,'), '');
407 }
@@ -416,8 +417,7 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
417
418 return true;
419 }
419 -
420 - Future<void> _calculateBestRate() async {
420 + Future<void> calculateBestRate() async {
421 final amount = double.tryParse(isFixedRateMode ? receiveAmount : depositAmount) ?? 1;
422
423 final _providers = _tradeAvailableProviders
@@ -453,7 +453,7 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
453 }
454 }
455 }
456 - if (_sortedAvailableProviders.isNotEmpty) _bestRate = _sortedAvailableProviders.keys.first;
456 + if (_sortedAvailableProviders.isNotEmpty) bestRate = _sortedAvailableProviders.keys.first;
457 }
458
459 @action
@@ -533,7 +533,7 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
533
534 if (!(await provider.checkIsAvailable())) continue;
535
536 - _bestRate = providerRate;
536 + bestRate = providerRate;
537 await changeDepositAmount(amount: depositAmount);
538
539 final request = TradeRequest(
@@ -693,8 +693,8 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
693 receiveAmount = '';
694 loadLimits();
695 _setAvailableProviders();
696 - _bestRate = 0;
697 - _calculateBestRate();
696 + bestRate = 0;
697 + calculateBestRate();
698 }
699
700 void _initialPairBasedOnWallet() {
@@ -785,8 +785,8 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
785 isFixedRateMode = false;
786 _defineIsReceiveAmountEditable();
787 loadLimits();
788 - _bestRate = 0;
789 - _calculateBestRate();
788 + bestRate = 0;
789 + calculateBestRate();
790
791 final Map<String, dynamic> exchangeProvidersSelection =
792 json.decode(sharedPreferences.getString(PreferencesKey.exchangeProvidersSelection) ?? "{}")