Cw 220 fix grey exchange screen (#641)

* Fix nullability issue for ChangeNow rateId * Handle concurrent modification error from Splay Tree

Omar Hatem committed Nov 22, 2022 at 03:52 UTC bcf09b048c635206e978ea1628ecb23201228c99
1 file changed +83 -75
lib/view_model/exchange/exchange_view_model.dart
+83 -75
@@ -7,7 +7,6 @@ import 'package:cake_wallet/exchange/sideshift/sideshift_exchange_provider.dart'
7 import 'package:cake_wallet/exchange/sideshift/sideshift_request.dart';
8 import 'package:cake_wallet/exchange/simpleswap/simpleswap_exchange_provider.dart';
9 import 'package:cake_wallet/view_model/settings/settings_view_model.dart';
10 -import 'package:cw_core/transaction_priority.dart';
10 import 'package:cake_wallet/exchange/simpleswap/simpleswap_request.dart';
11 import 'package:cw_core/wallet_base.dart';
12 import 'package:cw_core/crypto_currency.dart';
@@ -375,96 +374,105 @@ abstract class ExchangeViewModelBase with Store {
374 TradeRequest? request;
375 String amount = '';
376
378 - for (var provider in _sortedAvailableProviders.values) {
379 - if (!(await provider.checkIsAvailable())) {
380 - continue;
381 - }
382 -
383 - if (provider is SideShiftExchangeProvider) {
384 - request = SideShiftRequest(
385 - depositMethod: depositCurrency,
386 - settleMethod: receiveCurrency,
387 - depositAmount: depositAmount.replaceAll(',', '.'),
388 - settleAddress: receiveAddress,
389 - refundAddress: depositAddress,
390 - );
391 - amount = depositAmount;
392 - }
377 + try {
378 + for (var provider in _sortedAvailableProviders.values) {
379 + if (!(await provider.checkIsAvailable())) {
380 + continue;
381 + }
382
394 - if (provider is SimpleSwapExchangeProvider) {
395 - request = SimpleSwapRequest(
396 - from: depositCurrency,
397 - to: receiveCurrency,
398 - amount: depositAmount.replaceAll(',', '.'),
399 - address: receiveAddress,
400 - refundAddress: depositAddress,
401 - );
402 - amount = depositAmount;
403 - }
383 + if (provider is SideShiftExchangeProvider) {
384 + request = SideShiftRequest(
385 + depositMethod: depositCurrency,
386 + settleMethod: receiveCurrency,
387 + depositAmount: depositAmount.replaceAll(',', '.'),
388 + settleAddress: receiveAddress,
389 + refundAddress: depositAddress,
390 + );
391 + amount = depositAmount;
392 + }
393
405 - if (provider is XMRTOExchangeProvider) {
406 - request = XMRTOTradeRequest(
394 + if (provider is SimpleSwapExchangeProvider) {
395 + request = SimpleSwapRequest(
396 from: depositCurrency,
397 to: receiveCurrency,
398 amount: depositAmount.replaceAll(',', '.'),
410 - receiveAmount: receiveAmount.replaceAll(',', '.'),
399 address: receiveAddress,
400 refundAddress: depositAddress,
413 - isBTCRequest: isReceiveAmountEntered);
414 - amount = depositAmount;
415 - }
401 + );
402 + amount = depositAmount;
403 + }
404
417 - if (provider is ChangeNowExchangeProvider) {
418 - request = ChangeNowRequest(
419 - from: depositCurrency,
420 - to: receiveCurrency,
421 - fromAmount: depositAmount.replaceAll(',', '.'),
422 - toAmount: receiveAmount.replaceAll(',', '.'),
423 - refundAddress: depositAddress,
424 - address: receiveAddress,
425 - isReverse: isReverse);
426 - amount = isReverse ? receiveAmount : depositAmount;
427 - }
405 + if (provider is XMRTOExchangeProvider) {
406 + request = XMRTOTradeRequest(
407 + from: depositCurrency,
408 + to: receiveCurrency,
409 + amount: depositAmount.replaceAll(',', '.'),
410 + receiveAmount: receiveAmount.replaceAll(',', '.'),
411 + address: receiveAddress,
412 + refundAddress: depositAddress,
413 + isBTCRequest: isReceiveAmountEntered);
414 + amount = depositAmount;
415 + }
416
429 - if (provider is MorphTokenExchangeProvider) {
430 - request = MorphTokenRequest(
431 - from: depositCurrency,
432 - to: receiveCurrency,
433 - amount: depositAmount.replaceAll(',', '.'),
434 - refundAddress: depositAddress,
435 - address: receiveAddress);
436 - amount = depositAmount;
437 - }
417 + if (provider is ChangeNowExchangeProvider) {
418 + request = ChangeNowRequest(
419 + from: depositCurrency,
420 + to: receiveCurrency,
421 + fromAmount: depositAmount.replaceAll(',', '.'),
422 + toAmount: receiveAmount.replaceAll(',', '.'),
423 + refundAddress: depositAddress,
424 + address: receiveAddress,
425 + isReverse: isReverse);
426 + amount = isReverse ? receiveAmount : depositAmount;
427 + }
428
439 - amount = amount.replaceAll(',', '.');
429 + if (provider is MorphTokenExchangeProvider) {
430 + request = MorphTokenRequest(
431 + from: depositCurrency,
432 + to: receiveCurrency,
433 + amount: depositAmount.replaceAll(',', '.'),
434 + refundAddress: depositAddress,
435 + address: receiveAddress);
436 + amount = depositAmount;
437 + }
438
441 - if (limitsState is LimitsLoadedSuccessfully) {
442 - if (double.parse(amount) < limits.min!) {
443 - continue;
444 - } else if (limits.max != null && double.parse(amount) > limits.max!) {
445 - continue;
446 - } else {
447 - try {
448 - tradeState = TradeIsCreating();
449 - final trade = await provider.createTrade(
450 - request: request!, isFixedRateMode: isFixedRateMode);
451 - trade.walletId = wallet.id;
452 - tradesStore.setTrade(trade);
453 - await trades.add(trade);
454 - tradeState = TradeIsCreatedSuccessfully(trade: trade);
455 - /// return after the first successful trade
456 - return;
457 - } catch (e) {
439 + amount = amount.replaceAll(',', '.');
440 +
441 + if (limitsState is LimitsLoadedSuccessfully) {
442 + if (double.parse(amount) < limits.min!) {
443 continue;
444 + } else if (limits.max != null && double.parse(amount) > limits.max!) {
445 + continue;
446 + } else {
447 + try {
448 + tradeState = TradeIsCreating();
449 + final trade = await provider.createTrade(
450 + request: request!, isFixedRateMode: isFixedRateMode);
451 + trade.walletId = wallet.id;
452 + tradesStore.setTrade(trade);
453 + await trades.add(trade);
454 + tradeState = TradeIsCreatedSuccessfully(trade: trade);
455 + /// return after the first successful trade
456 + return;
457 + } catch (e) {
458 + continue;
459 + }
460 }
461 }
462 }
462 - }
463
464 - /// if the code reached here then none of the providers succeeded
465 - tradeState = TradeIsCreatedFailure(
466 - title: S.current.trade_not_created,
467 - error: S.current.none_of_selected_providers_can_exchange);
464 + /// if the code reached here then none of the providers succeeded
465 + tradeState = TradeIsCreatedFailure(
466 + title: S.current.trade_not_created,
467 + error: S.current.none_of_selected_providers_can_exchange);
468 + } on ConcurrentModificationError {
469 + /// if create trade happened at the exact same time of the scheduled rate update
470 + /// then delay the create trade a bit and try again
471 + ///
472 + /// this is because the limitation of the SplayTreeMap that
473 + /// you can't modify it while iterating through it
474 + Future.delayed(Duration(milliseconds: 500), createTrade);
475 + }
476 }
477
478 @action