Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 84 additions & 13 deletions lib/view_model/buy/buy_sell_view_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -307,7 +315,7 @@ abstract class BuySellViewModelBase extends WalletChangeListenerViewModel with S
}).toList();

final updatedQuoteOptions = List<SelectableItem>.from([
OptionTitle(title: 'Recommended'),
if (sortedRecommendedQuotes.isNotEmpty) OptionTitle(title: 'Recommended'),
...sortedRecommendedQuotes,
if (sortedQuotes.isNotEmpty) OptionTitle(title: 'All Providers'),
...sortedQuotes,
Expand Down Expand Up @@ -351,15 +359,23 @@ abstract class BuySellViewModelBase extends WalletChangeListenerViewModel with S
Future<void> _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),
onTimeout: () => [],
)));

final List<PaymentMethod> 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<PaymentType, PaymentMethod> uniquePaymentMethods = {};
for (var methods in result) {
for (var method in methods) {
final alreadyExists = tempPaymentMethods.any((m) {
Expand All @@ -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<void> calculateBestRate() async {
buySellQuotState = BuySellQuotLoading();

final List<BuyProvider> validProviders = providerList.where((provider) {
final List<BuyProvider> validProvidersNative = providerList.where((provider) {
if (isBuyAction) {
return provider.supportedCryptoList.any((pair) =>
pair.from == cryptoCurrency && pair.to == fiatCurrency);
Expand All @@ -399,12 +429,25 @@ abstract class BuySellViewModelBase extends WalletChangeListenerViewModel with S
}
}).toList();

if (validProviders.isEmpty) {
final List<BuyProvider> 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<List<Quote>?>(validProviders.map((element) => element
final resultNative = await Future.wait<List<Quote>?>(validProvidersNative.map((element) => element
.fetchQuote(
cryptoCurrency: cryptoCurrency,
fiatCurrency: fiatCurrency,
Expand All @@ -419,43 +462,67 @@ abstract class BuySellViewModelBase extends WalletChangeListenerViewModel with S
onTimeout: () => null,
)));

final resultSepa = await Future.wait<List<Quote>?>(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<String> addedProviders = {};
final List<Quote> uniqueProviderQuotes = validQuotes.where((element) {

final List<Quote> uniqueProviderQuotesSepa = validQuotesSepa.where((element) {
if (addedProviders.contains(element.provider.title)) return false;
addedProviders.add(element.provider.title);
return true;
}).toList();

final List<Quote> successRateQuotes = validQuotes.where((element) =>

final List<Quote> successRateQuotes = [...validQuotesNative, ...validQuotesSepa].where((element) =>
element.provider is OnRamperBuyProvider &&
element.recommendations.contains(ProviderRecommendation.successRate)
).toList();

final List<Quote> uniqueProviderQuotes = [];

for (final quote in successRateQuotes) {
if (!uniqueProviderQuotes.contains(quote)) {
if (!uniqueProviderQuotesSepa.contains(quote)) {
uniqueProviderQuotes.add(quote);
}
}

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
Expand All @@ -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();
Expand Down