diff --git a/lib/view_model/buy/buy_sell_view_model.dart b/lib/view_model/buy/buy_sell_view_model.dart index fbc091ef3e..4f863afbbc 100644 --- a/lib/view_model/buy/buy_sell_view_model.dart +++ b/lib/view_model/buy/buy_sell_view_model.dart @@ -213,6 +213,10 @@ abstract class BuySellViewModelBase extends WalletChangeListenerViewModel with S } if (bestRateQuote != null) { + if (bestRateQuote!.fiatCurrency != fiatCurrency) { + cryptoAmount = ''; + return; + } _cryptoNumberFormat.maximumFractionDigits = cryptoCurrency.decimals; cryptoAmount = _cryptoNumberFormat .format(enteredAmount / bestRateQuote!.rate) @@ -244,6 +248,10 @@ abstract class BuySellViewModelBase extends WalletChangeListenerViewModel with S } if (bestRateQuote != null) { + if (bestRateQuote!.cryptoCurrency != cryptoCurrency) { + fiatAmount = ''; + return; + } fiatAmount = _cryptoNumberFormat .format(enteredAmount * bestRateQuote!.rate) .toString() @@ -307,7 +315,7 @@ abstract class BuySellViewModelBase extends WalletChangeListenerViewModel with S }).toList(); final updatedQuoteOptions = List.from([ - OptionTitle(title: 'Recommended'), + if (sortedRecommendedQuotes.isNotEmpty) OptionTitle(title: 'Recommended'), ...sortedRecommendedQuotes, if (sortedQuotes.isNotEmpty) OptionTitle(title: 'All Providers'), ...sortedQuotes, @@ -351,7 +359,7 @@ abstract class BuySellViewModelBase extends WalletChangeListenerViewModel with S Future _getAvailablePaymentTypes() async { paymentMethodState = PaymentMethodLoading(); selectedPaymentMethod = null; - final result = await Future.wait(providerList.map((element) => element + final resultNative = await Future.wait(providerList.map((element) => element .getAvailablePaymentTypes(fiatCurrency.title, cryptoCurrency, isBuyAction) .timeout( Duration(seconds: 10), @@ -359,7 +367,15 @@ abstract class BuySellViewModelBase extends WalletChangeListenerViewModel with S ))); final List tempPaymentMethods = []; - + + final resultSepa = await Future.wait(providerList.map((element) => element + .getAvailablePaymentTypes(FiatCurrency.eur.title, cryptoCurrency, isBuyAction) + .timeout( + Duration(seconds: 10), + onTimeout: () => [], + ))); + final result = [...resultNative, ...resultSepa]; + final Map uniquePaymentMethods = {}; for (var methods in result) { for (var method in methods) { final alreadyExists = tempPaymentMethods.any((m) { @@ -384,12 +400,26 @@ abstract class BuySellViewModelBase extends WalletChangeListenerViewModel with S paymentMethodState = PaymentMethodFailed(); } } + static const currenciesWithSepa = [ + // 'ALL', // Albanian lek + FiatCurrency.bgn, // Bulgarian lev + FiatCurrency.czk, // Czech koruna + FiatCurrency.dkk, // Danish krone + FiatCurrency.huf, // Hungarian forint + FiatCurrency.isk, // Icelandic króna + FiatCurrency.chf, // Liechtenstein/Swiss franc + FiatCurrency.nok, // Norwegian krone + FiatCurrency.pln, // Polish złoty + FiatCurrency.ron, // Romanian leu + FiatCurrency.sek, // Swedish krona + FiatCurrency.gbp, // British pound sterling + ]; @action Future calculateBestRate() async { buySellQuotState = BuySellQuotLoading(); - final List validProviders = providerList.where((provider) { + final List validProvidersNative = providerList.where((provider) { if (isBuyAction) { return provider.supportedCryptoList.any((pair) => pair.from == cryptoCurrency && pair.to == fiatCurrency); @@ -399,12 +429,25 @@ abstract class BuySellViewModelBase extends WalletChangeListenerViewModel with S } }).toList(); - if (validProviders.isEmpty) { + final List validProvidersSepa = providerList.where((provider) { + if (currenciesWithSepa.contains(fiatCurrency)) { + if (isBuyAction) { + return provider.supportedCryptoList.any((pair) => + pair.from == cryptoCurrency && pair.to == FiatCurrency.eur); + } else { + return provider.supportedFiatList.any((pair) => + pair.from == FiatCurrency.eur && pair.to == cryptoCurrency); + } + } + return false; + }).toList(); + + if (validProvidersNative.isEmpty && validProvidersSepa.isEmpty) { buySellQuotState = BuySellQuotFailed(); return; } - final result = await Future.wait?>(validProviders.map((element) => element + final resultNative = await Future.wait?>(validProvidersNative.map((element) => element .fetchQuote( cryptoCurrency: cryptoCurrency, fiatCurrency: fiatCurrency, @@ -419,35 +462,59 @@ abstract class BuySellViewModelBase extends WalletChangeListenerViewModel with S onTimeout: () => null, ))); + final resultSepa = await Future.wait?>(validProvidersSepa.map((element) => element + .fetchQuote( + cryptoCurrency: cryptoCurrency, + fiatCurrency: FiatCurrency.eur, + amount: amount, + paymentType: selectedPaymentMethod?.paymentMethodType, + isBuyAction: isBuyAction, + walletAddress: wallet.walletAddresses.address, + ) + .timeout( + Duration(seconds: 10), + onTimeout: () => null, + ))); + sortedRecommendedQuotes.clear(); sortedQuotes.clear(); - final validQuotes = result + final validQuotesNative = resultNative .where((element) => element != null && element.isNotEmpty) .expand((element) => element!) .toList(); - if (validQuotes.isEmpty) { + final validQuotesSepa = resultSepa + .where((element) => element != null && element.isNotEmpty) + .expand((element) => element!) + .toList(); + + if (validQuotesNative.isEmpty && validQuotesSepa.isEmpty) { buySellQuotState = BuySellQuotFailed(); return; } - validQuotes.sort((a, b) => a.rate.compareTo(b.rate)); + validQuotesNative.sort((a, b) => a.rate.compareTo(b.rate)); + validQuotesSepa.sort((a, b) => a.rate.compareTo(b.rate)); final Set addedProviders = {}; - final List uniqueProviderQuotes = validQuotes.where((element) { + + final List uniqueProviderQuotesSepa = validQuotesSepa.where((element) { if (addedProviders.contains(element.provider.title)) return false; addedProviders.add(element.provider.title); return true; }).toList(); - final List successRateQuotes = validQuotes.where((element) => + + final List successRateQuotes = [...validQuotesNative, ...validQuotesSepa].where((element) => element.provider is OnRamperBuyProvider && element.recommendations.contains(ProviderRecommendation.successRate) ).toList(); + final List uniqueProviderQuotes = []; + for (final quote in successRateQuotes) { - if (!uniqueProviderQuotes.contains(quote)) { + if (!uniqueProviderQuotesSepa.contains(quote)) { uniqueProviderQuotes.add(quote); } } @@ -455,7 +522,7 @@ abstract class BuySellViewModelBase extends WalletChangeListenerViewModel with S sortedRecommendedQuotes.addAll(uniqueProviderQuotes); sortedQuotes = ObservableList.of( - validQuotes.where((element) => !uniqueProviderQuotes.contains(element)).toList()); + [...validQuotesNative, ...validQuotesSepa].where((element) => !uniqueProviderQuotes.contains(element)).toList()); if (sortedRecommendedQuotes.isNotEmpty) { sortedRecommendedQuotes.first @@ -471,6 +538,10 @@ abstract class BuySellViewModelBase extends WalletChangeListenerViewModel with S selectedQuote = sortedRecommendedQuotes.first; sortedRecommendedQuotes.first.setIsSelected = true; + } else if (sortedQuotes.isNotEmpty) { + sortedQuotes.first.setIsSelected = true; + bestRateQuote = sortedQuotes.first; + selectedQuote = sortedQuotes.first; } buySellQuotState = BuySellQuotLoaded();