diff --git a/lib/view_model/exchange/exchange_view_model.dart b/lib/view_model/exchange/exchange_view_model.dart index 6a3b32b9b..3a0ca3f1f 100644 --- a/lib/view_model/exchange/exchange_view_model.dart +++ b/lib/view_model/exchange/exchange_view_model.dart @@ -116,7 +116,6 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with .toList()); _setAvailableProviders(); - calculateBestRate(); autorun((_) { if (selectedProviders.any((provider) => provider is TrocadorExchangeProvider)) { @@ -154,9 +153,8 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with _defineIsReceiveAmountEditable(); loadLimits(); reaction((_) => isFixedRateMode, (Object _) { + bestRate = 0.0; loadLimits(); - bestRate = 0; - calculateBestRate(); }); if (isElectrumWallet) { @@ -210,6 +208,8 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with final List _tradeAvailableProviders = []; + Map _providerLimits = {}; + @observable ObservableList selectedProviders; @@ -433,9 +433,24 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with return true; } Future calculateBestRate() async { - final amount = double.tryParse(isFixedRateMode ? receiveAmount : depositAmount) ?? 1; + if (depositCurrency == receiveCurrency) { + bestRate = 0.0; + return; + } + final amount = double.tryParse(isFixedRateMode ? receiveAmount : depositAmount) + ?? initialAmountByAssets(isFixedRateMode ? receiveCurrency : depositCurrency); - final _providers = _tradeAvailableProviders + final validProvidersForAmount = _tradeAvailableProviders.where((provider) { + final limits = _providerLimits[provider]; + + if (limits == null) return false; + if (limits.min != null && amount < limits.min!) return false; + if (limits.max != null && amount > limits.max!) return false; + + return true; + }).toList(); + + final _providers = validProvidersForAmount .where((element) => !isFixedRateMode || element.supportsFixedRate) .toList(); @@ -473,6 +488,10 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with @action Future loadLimits() async { + if (depositCurrency == receiveCurrency) { + limitsState = LimitsLoadedSuccessfully(limits: Limits(min: 0, max: 0)); + return; + }; if (selectedProviders.isEmpty) return; limitsState = LimitsIsLoading(); @@ -484,23 +503,27 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with double? highestMax = 0.0; try { - final result = await Future.wait( - selectedProviders.where((provider) => providersForCurrentPair().contains(provider)).map( - (provider) => provider - .fetchLimits( - from: from, - to: to, - isFixedRateMode: isFixedRateMode, - ) - .onError((error, stackTrace) => Limits(max: 0.0, min: double.maxFinite)) - .timeout( - Duration(seconds: 7), - onTimeout: () => Limits(max: 0.0, min: double.maxFinite), - ), - ), - ); + final futures = selectedProviders + .where((provider) => providersForCurrentPair().contains(provider)) + .map((provider) async { + final limits = await provider + .fetchLimits( + from: from, + to: to, + isFixedRateMode: isFixedRateMode, + ) + .onError((error, stackTrace) => Limits(max: 0.0, min: double.maxFinite)) + .timeout( + Duration(seconds: 7), + onTimeout: () => Limits(max: 0.0, min: double.maxFinite), + ); + return MapEntry(provider, limits); + }).toList(); - result.forEach((tempLimits) { + final entries = await Future.wait(futures); + _providerLimits = Map.fromEntries(entries); + + _providerLimits.values.forEach((tempLimits) { if (lowestMin != null && (tempLimits.min ?? -1) < lowestMin!) { lowestMin = tempLimits.min; } @@ -525,10 +548,18 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with } else { limitsState = LimitsLoadedFailure(error: 'Limits loading failed'); } + + calculateBestRate(); } @action Future createTrade() async { + if (depositCurrency == receiveCurrency) { + tradeState = TradeIsCreatedFailure( + title: S.current.trade_not_created, + error: 'Can\'t exchange the same currency'); + return; + } if (isSendAllEnabled) { await calculateDepositAllAmount(); final amount = double.tryParse(depositAmount); @@ -706,10 +737,9 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with void _onPairChange() { depositAmount = ''; receiveAmount = ''; + bestRate = 0.0; loadLimits(); _setAvailableProviders(); - bestRate = 0; - calculateBestRate(); } void _initialPairBasedOnWallet() { @@ -803,9 +833,8 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with receiveAmount = ''; isFixedRateMode = false; _defineIsReceiveAmountEditable(); + bestRate = 0.0; loadLimits(); - bestRate = 0; - calculateBestRate(); final Map exchangeProvidersSelection = json.decode(sharedPreferences.getString(PreferencesKey.exchangeProvidersSelection) ?? "{}") @@ -988,4 +1017,21 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with return false; } } + + double initialAmountByAssets (CryptoCurrency ticker) { + final amount = switch (ticker) { + CryptoCurrency.trx => 1000, + CryptoCurrency.nano => 10, + CryptoCurrency.zano => 10, + CryptoCurrency.wow => 1000, + CryptoCurrency.ada => 1000, + CryptoCurrency.dash => 10, + CryptoCurrency.rune => 10, + + _ => 1 + }; + return amount.toDouble(); + } + + }