mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2025-01-03 17:29:23 +00:00
exchange form state implementation and various small bug fixes
This commit is contained in:
parent
d87c9981c6
commit
bb12e149f6
13 changed files with 1288 additions and 1161 deletions
|
@ -18,6 +18,7 @@ import 'package:path_provider/path_provider.dart';
|
|||
import 'package:stackwallet/hive/db.dart';
|
||||
import 'package:stackwallet/models/exchange/change_now/exchange_transaction.dart';
|
||||
import 'package:stackwallet/models/exchange/change_now/exchange_transaction_status.dart';
|
||||
import 'package:stackwallet/models/exchange/exchange_form_state.dart';
|
||||
import 'package:stackwallet/models/exchange/response_objects/trade.dart';
|
||||
import 'package:stackwallet/models/isar/models/log.dart';
|
||||
import 'package:stackwallet/models/models.dart';
|
||||
|
@ -35,8 +36,6 @@ import 'package:stackwallet/pages_desktop_specific/home/desktop_home_view.dart';
|
|||
import 'package:stackwallet/providers/exchange/available_currencies_state_provider.dart';
|
||||
import 'package:stackwallet/providers/exchange/available_floating_rate_pairs_state_provider.dart';
|
||||
import 'package:stackwallet/providers/exchange/changenow_initial_load_status.dart';
|
||||
import 'package:stackwallet/providers/exchange/estimate_rate_exchange_form_provider.dart';
|
||||
import 'package:stackwallet/providers/exchange/fixed_rate_exchange_form_provider.dart';
|
||||
import 'package:stackwallet/providers/exchange/fixed_rate_market_pairs_provider.dart';
|
||||
import 'package:stackwallet/providers/global/auto_swb_service_provider.dart';
|
||||
import 'package:stackwallet/providers/global/base_currencies_provider.dart';
|
||||
|
@ -47,6 +46,7 @@ import 'package:stackwallet/providers/ui/color_theme_provider.dart';
|
|||
import 'package:stackwallet/route_generator.dart';
|
||||
import 'package:stackwallet/services/debug_service.dart';
|
||||
import 'package:stackwallet/services/exchange/change_now/change_now_api.dart';
|
||||
import 'package:stackwallet/services/exchange/change_now/change_now_exchange.dart';
|
||||
import 'package:stackwallet/services/locale_service.dart';
|
||||
import 'package:stackwallet/services/node_service.dart';
|
||||
import 'package:stackwallet/services/notifications_api.dart';
|
||||
|
@ -271,15 +271,15 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme>
|
|||
response2.value!;
|
||||
|
||||
if (response.value!.length > 1) {
|
||||
if (ref.read(estimatedRateExchangeFormProvider).from == null) {
|
||||
if (ref.read(exchangeFormStateProvider).from == null) {
|
||||
if (response.value!.where((e) => e.ticker == "btc").isNotEmpty) {
|
||||
await ref.read(estimatedRateExchangeFormProvider).updateFrom(
|
||||
await ref.read(exchangeFormStateProvider).updateFrom(
|
||||
response.value!.firstWhere((e) => e.ticker == "btc"), false);
|
||||
}
|
||||
}
|
||||
if (ref.read(estimatedRateExchangeFormProvider).to == null) {
|
||||
if (ref.read(exchangeFormStateProvider).to == null) {
|
||||
if (response.value!.where((e) => e.ticker == "doge").isNotEmpty) {
|
||||
await ref.read(estimatedRateExchangeFormProvider).updateTo(
|
||||
await ref.read(exchangeFormStateProvider).updateTo(
|
||||
response.value!.firstWhere((e) => e.ticker == "doge"), false);
|
||||
}
|
||||
}
|
||||
|
@ -319,12 +319,12 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme>
|
|||
ref.read(fixedRateMarketPairsStateProvider.state).state =
|
||||
response3.value!;
|
||||
|
||||
if (ref.read(fixedRateExchangeFormProvider).market == null) {
|
||||
if (ref.read(exchangeFormStateProvider).market == null) {
|
||||
final matchingMarkets =
|
||||
response3.value!.where((e) => e.to == "doge" && e.from == "btc");
|
||||
if (matchingMarkets.isNotEmpty) {
|
||||
await ref
|
||||
.read(fixedRateExchangeFormProvider)
|
||||
.read(exchangeFormStateProvider)
|
||||
.updateMarket(matchingMarkets.first, true);
|
||||
}
|
||||
}
|
||||
|
@ -355,6 +355,7 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme>
|
|||
|
||||
@override
|
||||
void initState() {
|
||||
ref.read(exchangeFormStateProvider).exchange = ChangeNowExchange();
|
||||
final colorScheme = DB.instance
|
||||
.get<dynamic>(boxName: DB.boxNameTheme, key: "colorScheme") as String?;
|
||||
|
||||
|
|
|
@ -35,8 +35,10 @@ class EstimatedExchangeAmount {
|
|||
factory EstimatedExchangeAmount.fromJson(Map<String, dynamic> json) {
|
||||
try {
|
||||
return EstimatedExchangeAmount(
|
||||
estimatedAmount: Decimal.parse(json["estimatedAmount"].toString()),
|
||||
transactionSpeedForecast: json["transactionSpeedForecast"] as String,
|
||||
estimatedAmount: Decimal.parse(json["estimatedAmount"]?.toString() ??
|
||||
json["estimatedDeposit"].toString()),
|
||||
transactionSpeedForecast:
|
||||
json["transactionSpeedForecast"] as String? ?? "",
|
||||
warningMessage: json["warningMessage"] as String?,
|
||||
rateId: json["rateId"] as String?,
|
||||
networkFee: Decimal.tryParse(json["networkFee"].toString()),
|
||||
|
|
|
@ -1,282 +1,282 @@
|
|||
import 'package:decimal/decimal.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:stackwallet/models/exchange/response_objects/currency.dart';
|
||||
import 'package:stackwallet/services/exchange/change_now/change_now_api.dart';
|
||||
import 'package:stackwallet/utilities/logger.dart';
|
||||
|
||||
class EstimatedRateExchangeFormState extends ChangeNotifier {
|
||||
/// used in testing to inject mock
|
||||
ChangeNowAPI? cnTesting;
|
||||
|
||||
Decimal? _fromAmount;
|
||||
Decimal? _toAmount;
|
||||
|
||||
Decimal? _minFromAmount;
|
||||
Decimal? _minToAmount;
|
||||
|
||||
Decimal? rate;
|
||||
|
||||
Currency? _from;
|
||||
Currency? _to;
|
||||
|
||||
void Function(String)? _onError;
|
||||
|
||||
Currency? get from => _from;
|
||||
Currency? get to => _to;
|
||||
|
||||
String get fromAmountString =>
|
||||
_fromAmount == null ? "" : _fromAmount!.toStringAsFixed(8);
|
||||
String get toAmountString =>
|
||||
_toAmount == null ? "" : _toAmount!.toStringAsFixed(8);
|
||||
|
||||
String get rateDisplayString {
|
||||
if (rate == null || from == null || to == null) {
|
||||
return "N/A";
|
||||
} else {
|
||||
return "1 ${from!.ticker.toUpperCase()} ~${rate!.toStringAsFixed(8)} ${to!.ticker.toUpperCase()}";
|
||||
}
|
||||
}
|
||||
|
||||
bool get canExchange {
|
||||
return _fromAmount != null &&
|
||||
_fromAmount != Decimal.zero &&
|
||||
_toAmount != null &&
|
||||
rate != null &&
|
||||
minimumSendWarning.isEmpty;
|
||||
}
|
||||
|
||||
String get minimumSendWarning {
|
||||
if (_from != null &&
|
||||
_fromAmount != null &&
|
||||
_minFromAmount != null &&
|
||||
_fromAmount! < _minFromAmount!) {
|
||||
return "Minimum amount ${_minFromAmount!.toString()} ${from!.ticker.toUpperCase()}";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
Future<void> init(Currency? from, Currency? to) async {
|
||||
_from = from;
|
||||
_to = to;
|
||||
}
|
||||
|
||||
void clearAmounts(bool shouldNotifyListeners) {
|
||||
_fromAmount = null;
|
||||
_toAmount = null;
|
||||
_minFromAmount = null;
|
||||
_minToAmount = null;
|
||||
rate = null;
|
||||
|
||||
if (shouldNotifyListeners) {
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> swap() async {
|
||||
final Decimal? newToAmount = _fromAmount;
|
||||
final Decimal? newFromAmount = _toAmount;
|
||||
|
||||
final Decimal? newMinFromAmount = _minToAmount;
|
||||
final Decimal? newMinToAmount = _minFromAmount;
|
||||
|
||||
final Currency? newTo = from;
|
||||
final Currency? newFrom = to;
|
||||
|
||||
_fromAmount = newFromAmount;
|
||||
_toAmount = newToAmount;
|
||||
|
||||
_minToAmount = newMinToAmount;
|
||||
_minFromAmount = newMinFromAmount;
|
||||
|
||||
// rate = newRate;
|
||||
|
||||
_to = newTo;
|
||||
_from = newFrom;
|
||||
|
||||
await _updateMinFromAmount(shouldNotifyListeners: false);
|
||||
|
||||
await updateRate();
|
||||
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
Future<void> updateTo(Currency to, bool shouldNotifyListeners) async {
|
||||
try {
|
||||
_to = to;
|
||||
if (_from == null) {
|
||||
rate = null;
|
||||
notifyListeners();
|
||||
return;
|
||||
}
|
||||
|
||||
await _updateMinFromAmount(shouldNotifyListeners: shouldNotifyListeners);
|
||||
|
||||
await updateRate(shouldNotifyListeners: shouldNotifyListeners);
|
||||
|
||||
debugPrint(
|
||||
"_updated TO: _from=${_from!.ticker} _to=${_to!.ticker} _fromAmount=$_fromAmount _toAmount=$_toAmount rate:$rate");
|
||||
|
||||
if (shouldNotifyListeners) {
|
||||
notifyListeners();
|
||||
}
|
||||
} catch (e, s) {
|
||||
Logging.instance.log("$e\n$s", level: LogLevel.Error);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> updateFrom(Currency from, bool shouldNotifyListeners) async {
|
||||
try {
|
||||
_from = from;
|
||||
|
||||
if (_to == null) {
|
||||
rate = null;
|
||||
notifyListeners();
|
||||
return;
|
||||
}
|
||||
|
||||
await _updateMinFromAmount(shouldNotifyListeners: shouldNotifyListeners);
|
||||
|
||||
await updateRate(shouldNotifyListeners: shouldNotifyListeners);
|
||||
|
||||
debugPrint(
|
||||
"_updated FROM: _from=${_from!.ticker} _to=${_to!.ticker} _fromAmount=$_fromAmount _toAmount=$_toAmount rate:$rate");
|
||||
if (shouldNotifyListeners) {
|
||||
notifyListeners();
|
||||
}
|
||||
} catch (e, s) {
|
||||
Logging.instance.log("$e\n$s", level: LogLevel.Error);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _updateMinFromAmount(
|
||||
{required bool shouldNotifyListeners}) async {
|
||||
_minFromAmount = await getStandardMinExchangeAmount(from: from!, to: to!);
|
||||
if (shouldNotifyListeners) {
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
// Future<void> setToAmountAndCalculateFromAmount(
|
||||
// Decimal newToAmount,
|
||||
// bool shouldNotifyListeners,
|
||||
// ) async {
|
||||
// if (newToAmount == Decimal.zero) {
|
||||
// _fromAmount = Decimal.zero;
|
||||
// }
|
||||
//
|
||||
// _toAmount = newToAmount;
|
||||
// await updateRate();
|
||||
// if (shouldNotifyListeners) {
|
||||
// notifyListeners();
|
||||
// }
|
||||
// }
|
||||
|
||||
Future<void> setFromAmountAndCalculateToAmount(
|
||||
Decimal newFromAmount,
|
||||
bool shouldNotifyListeners,
|
||||
) async {
|
||||
if (newFromAmount == Decimal.zero) {
|
||||
_toAmount = Decimal.zero;
|
||||
}
|
||||
|
||||
_fromAmount = newFromAmount;
|
||||
await updateRate(shouldNotifyListeners: shouldNotifyListeners);
|
||||
|
||||
if (shouldNotifyListeners) {
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
Future<Decimal?> getStandardEstimatedToAmount({
|
||||
required Decimal fromAmount,
|
||||
required Currency from,
|
||||
required Currency to,
|
||||
}) async {
|
||||
final response =
|
||||
await (cnTesting ?? ChangeNowAPI.instance).getEstimatedExchangeAmount(
|
||||
fromTicker: from.ticker,
|
||||
toTicker: to.ticker,
|
||||
fromAmount: fromAmount,
|
||||
);
|
||||
|
||||
if (response.value != null) {
|
||||
return response.value!.estimatedAmount;
|
||||
} else {
|
||||
_onError?.call(
|
||||
"Failed to fetch estimated amount: ${response.exception?.toString()}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Future<Decimal?> getStandardEstimatedFromAmount({
|
||||
// required Decimal toAmount,
|
||||
// required Currency from,
|
||||
// required Currency to,
|
||||
// }) async {
|
||||
// final response = await (cnTesting ?? ChangeNow.instance)
|
||||
// .getEstimatedExchangeAmount(
|
||||
// fromTicker: from.ticker,
|
||||
// toTicker: to.ticker,
|
||||
// fromAmount: toAmount, );
|
||||
//
|
||||
// if (response.value != null) {
|
||||
// return response.value!.fromAmount;
|
||||
// } else {
|
||||
// _onError?.call(
|
||||
// "Failed to fetch estimated amount: ${response.exception?.toString()}");
|
||||
// return null;
|
||||
// }
|
||||
// }
|
||||
|
||||
Future<Decimal?> getStandardMinExchangeAmount({
|
||||
required Currency from,
|
||||
required Currency to,
|
||||
}) async {
|
||||
final response = await (cnTesting ?? ChangeNowAPI.instance)
|
||||
.getMinimalExchangeAmount(fromTicker: from.ticker, toTicker: to.ticker);
|
||||
|
||||
if (response.value != null) {
|
||||
return response.value!;
|
||||
} else {
|
||||
_onError?.call(
|
||||
"Could not update minimal exchange amounts: ${response.exception?.toString()}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
void setOnError({
|
||||
required void Function(String)? onError,
|
||||
bool shouldNotifyListeners = false,
|
||||
}) {
|
||||
_onError = onError;
|
||||
if (shouldNotifyListeners) {
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> updateRate({bool shouldNotifyListeners = false}) async {
|
||||
rate = null;
|
||||
final amount = _fromAmount;
|
||||
final minAmount = _minFromAmount;
|
||||
if (amount != null && amount > Decimal.zero) {
|
||||
Decimal? amt;
|
||||
if (minAmount != null) {
|
||||
if (minAmount <= amount) {
|
||||
amt = await getStandardEstimatedToAmount(
|
||||
fromAmount: amount, from: _from!, to: _to!);
|
||||
if (amt != null) {
|
||||
rate = (amt / amount).toDecimal(scaleOnInfinitePrecision: 12);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (rate != null && amt != null) {
|
||||
_toAmount = amt;
|
||||
}
|
||||
}
|
||||
if (shouldNotifyListeners) {
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
}
|
||||
// import 'package:decimal/decimal.dart';
|
||||
// import 'package:flutter/cupertino.dart';
|
||||
// import 'package:flutter/material.dart';
|
||||
// import 'package:stackwallet/models/exchange/response_objects/currency.dart';
|
||||
// import 'package:stackwallet/services/exchange/change_now/change_now_api.dart';
|
||||
// import 'package:stackwallet/utilities/logger.dart';
|
||||
//
|
||||
// class EstimatedRateExchangeFormState extends ChangeNotifier {
|
||||
// /// used in testing to inject mock
|
||||
// ChangeNowAPI? cnTesting;
|
||||
//
|
||||
// Decimal? _fromAmount;
|
||||
// Decimal? _toAmount;
|
||||
//
|
||||
// Decimal? _minFromAmount;
|
||||
// Decimal? _minToAmount;
|
||||
//
|
||||
// Decimal? rate;
|
||||
//
|
||||
// Currency? _from;
|
||||
// Currency? _to;
|
||||
//
|
||||
// void Function(String)? _onError;
|
||||
//
|
||||
// Currency? get from => _from;
|
||||
// Currency? get to => _to;
|
||||
//
|
||||
// String get fromAmountString =>
|
||||
// _fromAmount == null ? "" : _fromAmount!.toStringAsFixed(8);
|
||||
// String get toAmountString =>
|
||||
// _toAmount == null ? "" : _toAmount!.toStringAsFixed(8);
|
||||
//
|
||||
// String get rateDisplayString {
|
||||
// if (rate == null || from == null || to == null) {
|
||||
// return "N/A";
|
||||
// } else {
|
||||
// return "1 ${from!.ticker.toUpperCase()} ~${rate!.toStringAsFixed(8)} ${to!.ticker.toUpperCase()}";
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// bool get canExchange {
|
||||
// return _fromAmount != null &&
|
||||
// _fromAmount != Decimal.zero &&
|
||||
// _toAmount != null &&
|
||||
// rate != null &&
|
||||
// minimumSendWarning.isEmpty;
|
||||
// }
|
||||
//
|
||||
// String get minimumSendWarning {
|
||||
// if (_from != null &&
|
||||
// _fromAmount != null &&
|
||||
// _minFromAmount != null &&
|
||||
// _fromAmount! < _minFromAmount!) {
|
||||
// return "Minimum amount ${_minFromAmount!.toString()} ${from!.ticker.toUpperCase()}";
|
||||
// }
|
||||
//
|
||||
// return "";
|
||||
// }
|
||||
//
|
||||
// Future<void> init(Currency? from, Currency? to) async {
|
||||
// _from = from;
|
||||
// _to = to;
|
||||
// }
|
||||
//
|
||||
// void clearAmounts(bool shouldNotifyListeners) {
|
||||
// _fromAmount = null;
|
||||
// _toAmount = null;
|
||||
// _minFromAmount = null;
|
||||
// _minToAmount = null;
|
||||
// rate = null;
|
||||
//
|
||||
// if (shouldNotifyListeners) {
|
||||
// notifyListeners();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// Future<void> swap() async {
|
||||
// final Decimal? newToAmount = _fromAmount;
|
||||
// final Decimal? newFromAmount = _toAmount;
|
||||
//
|
||||
// final Decimal? newMinFromAmount = _minToAmount;
|
||||
// final Decimal? newMinToAmount = _minFromAmount;
|
||||
//
|
||||
// final Currency? newTo = from;
|
||||
// final Currency? newFrom = to;
|
||||
//
|
||||
// _fromAmount = newFromAmount;
|
||||
// _toAmount = newToAmount;
|
||||
//
|
||||
// _minToAmount = newMinToAmount;
|
||||
// _minFromAmount = newMinFromAmount;
|
||||
//
|
||||
// // rate = newRate;
|
||||
//
|
||||
// _to = newTo;
|
||||
// _from = newFrom;
|
||||
//
|
||||
// await _updateMinFromAmount(shouldNotifyListeners: false);
|
||||
//
|
||||
// await updateRate();
|
||||
//
|
||||
// notifyListeners();
|
||||
// }
|
||||
//
|
||||
// Future<void> updateTo(Currency to, bool shouldNotifyListeners) async {
|
||||
// try {
|
||||
// _to = to;
|
||||
// if (_from == null) {
|
||||
// rate = null;
|
||||
// notifyListeners();
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// await _updateMinFromAmount(shouldNotifyListeners: shouldNotifyListeners);
|
||||
//
|
||||
// await updateRate(shouldNotifyListeners: shouldNotifyListeners);
|
||||
//
|
||||
// debugPrint(
|
||||
// "_updated TO: _from=${_from!.ticker} _to=${_to!.ticker} _fromAmount=$_fromAmount _toAmount=$_toAmount rate:$rate");
|
||||
//
|
||||
// if (shouldNotifyListeners) {
|
||||
// notifyListeners();
|
||||
// }
|
||||
// } catch (e, s) {
|
||||
// Logging.instance.log("$e\n$s", level: LogLevel.Error);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// Future<void> updateFrom(Currency from, bool shouldNotifyListeners) async {
|
||||
// try {
|
||||
// _from = from;
|
||||
//
|
||||
// if (_to == null) {
|
||||
// rate = null;
|
||||
// notifyListeners();
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// await _updateMinFromAmount(shouldNotifyListeners: shouldNotifyListeners);
|
||||
//
|
||||
// await updateRate(shouldNotifyListeners: shouldNotifyListeners);
|
||||
//
|
||||
// debugPrint(
|
||||
// "_updated FROM: _from=${_from!.ticker} _to=${_to!.ticker} _fromAmount=$_fromAmount _toAmount=$_toAmount rate:$rate");
|
||||
// if (shouldNotifyListeners) {
|
||||
// notifyListeners();
|
||||
// }
|
||||
// } catch (e, s) {
|
||||
// Logging.instance.log("$e\n$s", level: LogLevel.Error);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// Future<void> _updateMinFromAmount(
|
||||
// {required bool shouldNotifyListeners}) async {
|
||||
// _minFromAmount = await getStandardMinExchangeAmount(from: from!, to: to!);
|
||||
// if (shouldNotifyListeners) {
|
||||
// notifyListeners();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // Future<void> setToAmountAndCalculateFromAmount(
|
||||
// // Decimal newToAmount,
|
||||
// // bool shouldNotifyListeners,
|
||||
// // ) async {
|
||||
// // if (newToAmount == Decimal.zero) {
|
||||
// // _fromAmount = Decimal.zero;
|
||||
// // }
|
||||
// //
|
||||
// // _toAmount = newToAmount;
|
||||
// // await updateRate();
|
||||
// // if (shouldNotifyListeners) {
|
||||
// // notifyListeners();
|
||||
// // }
|
||||
// // }
|
||||
//
|
||||
// Future<void> setFromAmountAndCalculateToAmount(
|
||||
// Decimal newFromAmount,
|
||||
// bool shouldNotifyListeners,
|
||||
// ) async {
|
||||
// if (newFromAmount == Decimal.zero) {
|
||||
// _toAmount = Decimal.zero;
|
||||
// }
|
||||
//
|
||||
// _fromAmount = newFromAmount;
|
||||
// await updateRate(shouldNotifyListeners: shouldNotifyListeners);
|
||||
//
|
||||
// if (shouldNotifyListeners) {
|
||||
// notifyListeners();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// Future<Decimal?> getStandardEstimatedToAmount({
|
||||
// required Decimal fromAmount,
|
||||
// required Currency from,
|
||||
// required Currency to,
|
||||
// }) async {
|
||||
// final response =
|
||||
// await (cnTesting ?? ChangeNowAPI.instance).getEstimatedExchangeAmount(
|
||||
// fromTicker: from.ticker,
|
||||
// toTicker: to.ticker,
|
||||
// fromAmount: fromAmount,
|
||||
// );
|
||||
//
|
||||
// if (response.value != null) {
|
||||
// return response.value!.estimatedAmount;
|
||||
// } else {
|
||||
// _onError?.call(
|
||||
// "Failed to fetch estimated amount: ${response.exception?.toString()}");
|
||||
// return null;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // Future<Decimal?> getStandardEstimatedFromAmount({
|
||||
// // required Decimal toAmount,
|
||||
// // required Currency from,
|
||||
// // required Currency to,
|
||||
// // }) async {
|
||||
// // final response = await (cnTesting ?? ChangeNow.instance)
|
||||
// // .getEstimatedExchangeAmount(
|
||||
// // fromTicker: from.ticker,
|
||||
// // toTicker: to.ticker,
|
||||
// // fromAmount: toAmount, );
|
||||
// //
|
||||
// // if (response.value != null) {
|
||||
// // return response.value!.fromAmount;
|
||||
// // } else {
|
||||
// // _onError?.call(
|
||||
// // "Failed to fetch estimated amount: ${response.exception?.toString()}");
|
||||
// // return null;
|
||||
// // }
|
||||
// // }
|
||||
//
|
||||
// Future<Decimal?> getStandardMinExchangeAmount({
|
||||
// required Currency from,
|
||||
// required Currency to,
|
||||
// }) async {
|
||||
// final response = await (cnTesting ?? ChangeNowAPI.instance)
|
||||
// .getMinimalExchangeAmount(fromTicker: from.ticker, toTicker: to.ticker);
|
||||
//
|
||||
// if (response.value != null) {
|
||||
// return response.value!;
|
||||
// } else {
|
||||
// _onError?.call(
|
||||
// "Could not update minimal exchange amounts: ${response.exception?.toString()}");
|
||||
// return null;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// void setOnError({
|
||||
// required void Function(String)? onError,
|
||||
// bool shouldNotifyListeners = false,
|
||||
// }) {
|
||||
// _onError = onError;
|
||||
// if (shouldNotifyListeners) {
|
||||
// notifyListeners();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// Future<void> updateRate({bool shouldNotifyListeners = false}) async {
|
||||
// rate = null;
|
||||
// final amount = _fromAmount;
|
||||
// final minAmount = _minFromAmount;
|
||||
// if (amount != null && amount > Decimal.zero) {
|
||||
// Decimal? amt;
|
||||
// if (minAmount != null) {
|
||||
// if (minAmount <= amount) {
|
||||
// amt = await getStandardEstimatedToAmount(
|
||||
// fromAmount: amount, from: _from!, to: _to!);
|
||||
// if (amt != null) {
|
||||
// rate = (amt / amount).toDecimal(scaleOnInfinitePrecision: 12);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// if (rate != null && amt != null) {
|
||||
// _toAmount = amt;
|
||||
// }
|
||||
// }
|
||||
// if (shouldNotifyListeners) {
|
||||
// notifyListeners();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
|
390
lib/models/exchange/exchange_form_state.dart
Normal file
390
lib/models/exchange/exchange_form_state.dart
Normal file
|
@ -0,0 +1,390 @@
|
|||
import 'package:decimal/decimal.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:stackwallet/models/exchange/response_objects/currency.dart';
|
||||
import 'package:stackwallet/models/exchange/response_objects/estimate.dart';
|
||||
import 'package:stackwallet/models/exchange/response_objects/fixed_rate_market.dart';
|
||||
import 'package:stackwallet/pages/exchange_view/sub_widgets/exchange_rate_sheet.dart';
|
||||
import 'package:stackwallet/services/exchange/exchange.dart';
|
||||
import 'package:stackwallet/utilities/logger.dart';
|
||||
|
||||
final exchangeFormStateProvider =
|
||||
ChangeNotifierProvider<ExchangeFormState>((ref) => ExchangeFormState());
|
||||
|
||||
class ExchangeFormState extends ChangeNotifier {
|
||||
Exchange? _exchange;
|
||||
Exchange? get exchange => _exchange;
|
||||
set exchange(Exchange? value) {
|
||||
_exchange = value;
|
||||
_onExchangeTypeChanged();
|
||||
}
|
||||
|
||||
ExchangeRateType _exchangeType = ExchangeRateType.estimated;
|
||||
ExchangeRateType get exchangeType => _exchangeType;
|
||||
set exchangeType(ExchangeRateType value) {
|
||||
_exchangeType = value;
|
||||
_onExchangeRateTypeChanged();
|
||||
}
|
||||
|
||||
bool reversed = false;
|
||||
|
||||
Decimal? fromAmount;
|
||||
Decimal? toAmount;
|
||||
|
||||
Decimal? minAmount;
|
||||
Decimal? maxAmount;
|
||||
|
||||
Decimal? rate;
|
||||
Estimate? estimate;
|
||||
|
||||
FixedRateMarket? _market;
|
||||
FixedRateMarket? get market => _market;
|
||||
|
||||
Currency? _from;
|
||||
Currency? _to;
|
||||
|
||||
String? get fromTicker {
|
||||
switch (exchangeType) {
|
||||
case ExchangeRateType.estimated:
|
||||
return _from?.ticker;
|
||||
case ExchangeRateType.fixed:
|
||||
return _market?.from;
|
||||
}
|
||||
}
|
||||
|
||||
String? get toTicker {
|
||||
switch (exchangeType) {
|
||||
case ExchangeRateType.estimated:
|
||||
return _to?.ticker;
|
||||
case ExchangeRateType.fixed:
|
||||
return _market?.to;
|
||||
}
|
||||
}
|
||||
|
||||
void Function(String)? _onError;
|
||||
|
||||
Currency? get from => _from;
|
||||
Currency? get to => _to;
|
||||
|
||||
void setCurrencies(Currency from, Currency to) {
|
||||
_from = from;
|
||||
_to = to;
|
||||
}
|
||||
|
||||
String get warning {
|
||||
if (reversed) {
|
||||
if (toTicker != null && toAmount != null) {
|
||||
if (minAmount != null && toAmount! < minAmount!) {
|
||||
return "Minimum amount ${minAmount!.toString()} ${toTicker!.toUpperCase()}";
|
||||
} else if (maxAmount != null && toAmount! > maxAmount!) {
|
||||
return "Maximum amount ${maxAmount!.toString()} ${toTicker!.toUpperCase()}";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (fromTicker != null && fromAmount != null) {
|
||||
if (minAmount != null && fromAmount! < minAmount!) {
|
||||
return "Minimum amount ${minAmount!.toString()} ${fromTicker!.toUpperCase()}";
|
||||
} else if (maxAmount != null && fromAmount! > maxAmount!) {
|
||||
return "Maximum amount ${maxAmount!.toString()} ${fromTicker!.toUpperCase()}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
String get fromAmountString => fromAmount?.toStringAsFixed(8) ?? "";
|
||||
String get toAmountString => toAmount?.toStringAsFixed(8) ?? "";
|
||||
|
||||
bool get canExchange {
|
||||
switch (exchangeType) {
|
||||
case ExchangeRateType.estimated:
|
||||
return fromAmount != null &&
|
||||
fromAmount != Decimal.zero &&
|
||||
toAmount != null &&
|
||||
rate != null &&
|
||||
warning.isEmpty;
|
||||
case ExchangeRateType.fixed:
|
||||
return _market != null &&
|
||||
fromAmount != null &&
|
||||
toAmount != null &&
|
||||
warning.isEmpty;
|
||||
}
|
||||
}
|
||||
|
||||
void clearAmounts(bool shouldNotifyListeners) {
|
||||
fromAmount = null;
|
||||
toAmount = null;
|
||||
minAmount = null;
|
||||
maxAmount = null;
|
||||
rate = null;
|
||||
|
||||
if (shouldNotifyListeners) {
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> setFromAmountAndCalculateToAmount(
|
||||
Decimal newFromAmount,
|
||||
bool shouldNotifyListeners,
|
||||
) async {
|
||||
if (newFromAmount == Decimal.zero) {
|
||||
toAmount = Decimal.zero;
|
||||
}
|
||||
|
||||
fromAmount = newFromAmount;
|
||||
reversed = false;
|
||||
|
||||
await updateRanges(shouldNotifyListeners: false);
|
||||
|
||||
await updateEstimate(
|
||||
shouldNotifyListeners: false,
|
||||
reversed: reversed,
|
||||
);
|
||||
|
||||
if (shouldNotifyListeners) {
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> setToAmountAndCalculateFromAmount(
|
||||
Decimal newToAmount,
|
||||
bool shouldNotifyListeners,
|
||||
) async {
|
||||
if (newToAmount == Decimal.zero) {
|
||||
fromAmount = Decimal.zero;
|
||||
}
|
||||
|
||||
toAmount = newToAmount;
|
||||
reversed = true;
|
||||
|
||||
await updateRanges(shouldNotifyListeners: false);
|
||||
|
||||
await updateEstimate(
|
||||
shouldNotifyListeners: false,
|
||||
reversed: reversed,
|
||||
);
|
||||
|
||||
if (shouldNotifyListeners) {
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> updateTo(Currency to, bool shouldNotifyListeners) async {
|
||||
try {
|
||||
_to = to;
|
||||
if (_from == null) {
|
||||
rate = null;
|
||||
notifyListeners();
|
||||
return;
|
||||
}
|
||||
|
||||
await updateRanges(shouldNotifyListeners: false);
|
||||
|
||||
await updateEstimate(
|
||||
shouldNotifyListeners: false,
|
||||
reversed: reversed,
|
||||
);
|
||||
|
||||
debugPrint(
|
||||
"_updated TO: _from=${_from!.ticker} _to=${_to!.ticker} _fromAmount=$fromAmount _toAmount=$toAmount rate:$rate");
|
||||
|
||||
if (shouldNotifyListeners) {
|
||||
notifyListeners();
|
||||
}
|
||||
} catch (e, s) {
|
||||
Logging.instance.log("$e\n$s", level: LogLevel.Error);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> updateFrom(Currency from, bool shouldNotifyListeners) async {
|
||||
try {
|
||||
_from = from;
|
||||
|
||||
if (_to == null) {
|
||||
rate = null;
|
||||
notifyListeners();
|
||||
return;
|
||||
}
|
||||
|
||||
await updateRanges(shouldNotifyListeners: false);
|
||||
|
||||
await updateEstimate(
|
||||
shouldNotifyListeners: false,
|
||||
reversed: reversed,
|
||||
);
|
||||
|
||||
debugPrint(
|
||||
"_updated FROM: _from=${_from!.ticker} _to=${_to!.ticker} _fromAmount=$fromAmount _toAmount=$toAmount rate:$rate");
|
||||
if (shouldNotifyListeners) {
|
||||
notifyListeners();
|
||||
}
|
||||
} catch (e, s) {
|
||||
Logging.instance.log("$e\n$s", level: LogLevel.Error);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> updateMarket(
|
||||
FixedRateMarket? market,
|
||||
bool shouldNotifyListeners,
|
||||
) async {
|
||||
_market = market;
|
||||
|
||||
if (_market == null) {
|
||||
fromAmount = null;
|
||||
toAmount = null;
|
||||
} else {
|
||||
if (fromAmount != null) {
|
||||
if (fromAmount! <= Decimal.zero) {
|
||||
toAmount = Decimal.zero;
|
||||
} else {
|
||||
await updateRanges(shouldNotifyListeners: false);
|
||||
await updateEstimate(
|
||||
shouldNotifyListeners: false,
|
||||
reversed: reversed,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldNotifyListeners) {
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
void _onExchangeRateTypeChanged() {
|
||||
print("_onExchangeRateTypeChanged");
|
||||
}
|
||||
|
||||
void _onExchangeTypeChanged() {
|
||||
print("_onExchangeTypeChanged");
|
||||
}
|
||||
|
||||
Future<void> updateRanges({required bool shouldNotifyListeners}) async {
|
||||
final _fromTicker = reversed ? toTicker : fromTicker;
|
||||
final _toTicker = reversed ? fromTicker : toTicker;
|
||||
if (_fromTicker == null || _toTicker == null) {
|
||||
Logging.instance.log(
|
||||
"Tried to $runtimeType.updateRanges where (from: $_fromTicker || to: $_toTicker)",
|
||||
level: LogLevel.Info,
|
||||
);
|
||||
return;
|
||||
}
|
||||
final response = await exchange?.getRange(
|
||||
_fromTicker,
|
||||
_toTicker,
|
||||
exchangeType == ExchangeRateType.fixed,
|
||||
);
|
||||
|
||||
if (response?.value == null) {
|
||||
Logging.instance.log(
|
||||
"Tried to $runtimeType.updateRanges where response: $response",
|
||||
level: LogLevel.Info,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
final range = response!.value!;
|
||||
|
||||
minAmount = range.min;
|
||||
maxAmount = range.max;
|
||||
|
||||
debugPrint("updated range for $_fromTicker-$_toTicker: $range");
|
||||
|
||||
if (shouldNotifyListeners) {
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> updateEstimate({
|
||||
required bool shouldNotifyListeners,
|
||||
required bool reversed,
|
||||
}) async {
|
||||
final amount = reversed ? toAmount : fromAmount;
|
||||
if (fromTicker == null ||
|
||||
toTicker == null ||
|
||||
amount == null ||
|
||||
amount <= Decimal.zero) {
|
||||
Logging.instance.log(
|
||||
"Tried to $runtimeType.updateEstimate where (from: $fromTicker || to: $toTicker || amount: $amount)",
|
||||
level: LogLevel.Info,
|
||||
);
|
||||
return;
|
||||
}
|
||||
final response = await exchange?.getEstimate(
|
||||
fromTicker!,
|
||||
toTicker!,
|
||||
amount,
|
||||
exchangeType == ExchangeRateType.fixed,
|
||||
reversed,
|
||||
);
|
||||
|
||||
if (response?.value == null) {
|
||||
Logging.instance.log(
|
||||
"Tried to $runtimeType.updateEstimate where response: $response",
|
||||
level: LogLevel.Info,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
estimate = response!.value!;
|
||||
|
||||
if (reversed) {
|
||||
fromAmount = estimate!.estimatedAmount;
|
||||
} else {
|
||||
toAmount = estimate!.estimatedAmount;
|
||||
}
|
||||
|
||||
rate = (toAmount! / fromAmount!).toDecimal(scaleOnInfinitePrecision: 12);
|
||||
|
||||
debugPrint("updated estimate for $fromTicker-$toTicker: $estimate");
|
||||
|
||||
if (shouldNotifyListeners) {
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
void setOnError({
|
||||
required void Function(String)? onError,
|
||||
bool shouldNotifyListeners = false,
|
||||
}) {
|
||||
_onError = onError;
|
||||
if (shouldNotifyListeners) {
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> swap({FixedRateMarket? market}) async {
|
||||
final Decimal? newToAmount = fromAmount;
|
||||
final Decimal? newFromAmount = toAmount;
|
||||
|
||||
fromAmount = newFromAmount;
|
||||
toAmount = newToAmount;
|
||||
|
||||
minAmount = null;
|
||||
maxAmount = null;
|
||||
|
||||
switch (exchangeType) {
|
||||
case ExchangeRateType.estimated:
|
||||
final Currency? newTo = from;
|
||||
final Currency? newFrom = to;
|
||||
|
||||
_to = newTo;
|
||||
_from = newFrom;
|
||||
|
||||
await updateRanges(shouldNotifyListeners: false);
|
||||
|
||||
await updateEstimate(
|
||||
shouldNotifyListeners: false,
|
||||
reversed: reversed,
|
||||
);
|
||||
break;
|
||||
case ExchangeRateType.fixed:
|
||||
await updateMarket(market, false);
|
||||
break;
|
||||
}
|
||||
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
|
@ -1,179 +1,179 @@
|
|||
import 'package:decimal/decimal.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:stackwallet/models/exchange/change_now/cn_exchange_estimate.dart';
|
||||
import 'package:stackwallet/models/exchange/response_objects/fixed_rate_market.dart';
|
||||
import 'package:stackwallet/services/exchange/change_now/change_now_api.dart';
|
||||
import 'package:stackwallet/utilities/logger.dart';
|
||||
|
||||
class FixedRateExchangeFormState extends ChangeNotifier {
|
||||
Decimal? _fromAmount;
|
||||
Decimal? _toAmount;
|
||||
|
||||
FixedRateMarket? _market;
|
||||
FixedRateMarket? get market => _market;
|
||||
|
||||
CNExchangeEstimate? _estimate;
|
||||
CNExchangeEstimate? get estimate => _estimate;
|
||||
|
||||
Decimal? get rate {
|
||||
if (_estimate == null) {
|
||||
return null;
|
||||
} else {
|
||||
return (_estimate!.toAmount / _estimate!.fromAmount)
|
||||
.toDecimal(scaleOnInfinitePrecision: 12);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> swap(FixedRateMarket reverseFixedRateMarket) async {
|
||||
final Decimal? tmp = _fromAmount;
|
||||
_fromAmount = _toAmount;
|
||||
_toAmount = tmp;
|
||||
|
||||
await updateMarket(reverseFixedRateMarket, false);
|
||||
await updateRateEstimate(CNEstimateType.direct);
|
||||
_toAmount = _estimate?.toAmount ?? Decimal.zero;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
String get fromAmountString =>
|
||||
_fromAmount == null ? "" : _fromAmount!.toStringAsFixed(8);
|
||||
String get toAmountString =>
|
||||
_toAmount == null ? "" : _toAmount!.toStringAsFixed(8);
|
||||
|
||||
Future<void> updateMarket(
|
||||
FixedRateMarket? market,
|
||||
bool shouldNotifyListeners,
|
||||
) async {
|
||||
_market = market;
|
||||
|
||||
if (_market == null) {
|
||||
_fromAmount = null;
|
||||
_toAmount = null;
|
||||
} else {
|
||||
if (_fromAmount != null) {
|
||||
if (_fromAmount! <= Decimal.zero) {
|
||||
_toAmount = Decimal.zero;
|
||||
} else {
|
||||
await updateRateEstimate(CNEstimateType.direct);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldNotifyListeners) {
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
String get rateDisplayString {
|
||||
if (_market == null || _estimate == null) {
|
||||
return "N/A";
|
||||
} else {
|
||||
return "1 ${_estimate!.fromCurrency.toUpperCase()} ~${rate!.toStringAsFixed(8)} ${_estimate!.toCurrency.toUpperCase()}";
|
||||
}
|
||||
}
|
||||
|
||||
bool get canExchange {
|
||||
return _market != null &&
|
||||
_fromAmount != null &&
|
||||
_toAmount != null &&
|
||||
sendAmountWarning.isEmpty;
|
||||
}
|
||||
|
||||
String get sendAmountWarning {
|
||||
if (_market != null && _fromAmount != null) {
|
||||
if (_fromAmount! < _market!.min) {
|
||||
return "Minimum amount ${_market!.min.toString()} ${_market!.from.toUpperCase()}";
|
||||
} else if (_fromAmount! > _market!.max) {
|
||||
return "Maximum amount ${_market!.max.toString()} ${_market!.from.toUpperCase()}";
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
Future<void> setToAmountAndCalculateFromAmount(
|
||||
Decimal newToAmount,
|
||||
bool shouldNotifyListeners,
|
||||
) async {
|
||||
_toAmount = newToAmount;
|
||||
|
||||
if (shouldNotifyListeners) {
|
||||
await updateRateEstimate(CNEstimateType.reverse);
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> setFromAmountAndCalculateToAmount(
|
||||
Decimal newFromAmount,
|
||||
bool shouldNotifyListeners,
|
||||
) async {
|
||||
_fromAmount = newFromAmount;
|
||||
|
||||
if (shouldNotifyListeners) {
|
||||
await updateRateEstimate(CNEstimateType.direct);
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
void Function(String)? _onError;
|
||||
|
||||
void setOnError({
|
||||
required void Function(String)? onError,
|
||||
bool shouldNotifyListeners = false,
|
||||
}) {
|
||||
_onError = onError;
|
||||
if (shouldNotifyListeners) {
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> updateRateEstimate(CNEstimateType direction) async {
|
||||
if (market != null) {
|
||||
Decimal? amount;
|
||||
// set amount based on trade estimate direction
|
||||
switch (direction) {
|
||||
case CNEstimateType.direct:
|
||||
if (_fromAmount != null
|
||||
// &&
|
||||
// market!.min >= _fromAmount! &&
|
||||
// _fromAmount! <= market!.max
|
||||
) {
|
||||
amount = _fromAmount!;
|
||||
}
|
||||
break;
|
||||
case CNEstimateType.reverse:
|
||||
if (_toAmount != null
|
||||
// &&
|
||||
// market!.min >= _toAmount! &&
|
||||
// _toAmount! <= market!.max
|
||||
) {
|
||||
amount = _toAmount!;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (amount != null && market != null && amount > Decimal.zero) {
|
||||
final response =
|
||||
await ChangeNowAPI.instance.getEstimatedExchangeAmountV2(
|
||||
fromTicker: market!.from,
|
||||
toTicker: market!.to,
|
||||
fromOrTo: direction,
|
||||
flow: CNFlowType.fixedRate,
|
||||
amount: amount,
|
||||
);
|
||||
|
||||
if (response.value != null) {
|
||||
// update estimate if response succeeded
|
||||
_estimate = response.value;
|
||||
|
||||
_toAmount = _estimate?.toAmount;
|
||||
_fromAmount = _estimate?.fromAmount;
|
||||
notifyListeners();
|
||||
} else if (response.exception != null) {
|
||||
Logging.instance.log("updateRateEstimate(): ${response.exception}",
|
||||
level: LogLevel.Warning);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// import 'package:decimal/decimal.dart';
|
||||
// import 'package:flutter/cupertino.dart';
|
||||
// import 'package:stackwallet/models/exchange/change_now/cn_exchange_estimate.dart';
|
||||
// import 'package:stackwallet/models/exchange/response_objects/fixed_rate_market.dart';
|
||||
// import 'package:stackwallet/services/exchange/change_now/change_now_api.dart';
|
||||
// import 'package:stackwallet/utilities/logger.dart';
|
||||
//
|
||||
// class FixedRateExchangeFormState extends ChangeNotifier {
|
||||
// Decimal? _fromAmount;
|
||||
// Decimal? _toAmount;
|
||||
//
|
||||
// FixedRateMarket? _market;
|
||||
// FixedRateMarket? get market => _market;
|
||||
//
|
||||
// CNExchangeEstimate? _estimate;
|
||||
// CNExchangeEstimate? get estimate => _estimate;
|
||||
//
|
||||
// Decimal? get rate {
|
||||
// if (_estimate == null) {
|
||||
// return null;
|
||||
// } else {
|
||||
// return (_estimate!.toAmount / _estimate!.fromAmount)
|
||||
// .toDecimal(scaleOnInfinitePrecision: 12);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// Future<void> swap(FixedRateMarket reverseFixedRateMarket) async {
|
||||
// final Decimal? tmp = _fromAmount;
|
||||
// _fromAmount = _toAmount;
|
||||
// _toAmount = tmp;
|
||||
//
|
||||
// await updateMarket(reverseFixedRateMarket, false);
|
||||
// await updateRateEstimate(CNEstimateType.direct);
|
||||
// _toAmount = _estimate?.toAmount ?? Decimal.zero;
|
||||
// notifyListeners();
|
||||
// }
|
||||
//
|
||||
// String get fromAmountString =>
|
||||
// _fromAmount == null ? "" : _fromAmount!.toStringAsFixed(8);
|
||||
// String get toAmountString =>
|
||||
// _toAmount == null ? "" : _toAmount!.toStringAsFixed(8);
|
||||
//
|
||||
// Future<void> updateMarket(
|
||||
// FixedRateMarket? market,
|
||||
// bool shouldNotifyListeners,
|
||||
// ) async {
|
||||
// _market = market;
|
||||
//
|
||||
// if (_market == null) {
|
||||
// _fromAmount = null;
|
||||
// _toAmount = null;
|
||||
// } else {
|
||||
// if (_fromAmount != null) {
|
||||
// if (_fromAmount! <= Decimal.zero) {
|
||||
// _toAmount = Decimal.zero;
|
||||
// } else {
|
||||
// await updateRateEstimate(CNEstimateType.direct);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (shouldNotifyListeners) {
|
||||
// notifyListeners();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// String get rateDisplayString {
|
||||
// if (_market == null || _estimate == null) {
|
||||
// return "N/A";
|
||||
// } else {
|
||||
// return "1 ${_estimate!.fromCurrency.toUpperCase()} ~${rate!.toStringAsFixed(8)} ${_estimate!.toCurrency.toUpperCase()}";
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// bool get canExchange {
|
||||
// return _market != null &&
|
||||
// _fromAmount != null &&
|
||||
// _toAmount != null &&
|
||||
// sendAmountWarning.isEmpty;
|
||||
// }
|
||||
//
|
||||
// String get sendAmountWarning {
|
||||
// if (_market != null && _fromAmount != null) {
|
||||
// if (_fromAmount! < _market!.min) {
|
||||
// return "Minimum amount ${_market!.min.toString()} ${_market!.from.toUpperCase()}";
|
||||
// } else if (_fromAmount! > _market!.max) {
|
||||
// return "Maximum amount ${_market!.max.toString()} ${_market!.from.toUpperCase()}";
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return "";
|
||||
// }
|
||||
//
|
||||
// Future<void> setToAmountAndCalculateFromAmount(
|
||||
// Decimal newToAmount,
|
||||
// bool shouldNotifyListeners,
|
||||
// ) async {
|
||||
// _toAmount = newToAmount;
|
||||
//
|
||||
// if (shouldNotifyListeners) {
|
||||
// await updateRateEstimate(CNEstimateType.reverse);
|
||||
// notifyListeners();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// Future<void> setFromAmountAndCalculateToAmount(
|
||||
// Decimal newFromAmount,
|
||||
// bool shouldNotifyListeners,
|
||||
// ) async {
|
||||
// _fromAmount = newFromAmount;
|
||||
//
|
||||
// if (shouldNotifyListeners) {
|
||||
// await updateRateEstimate(CNEstimateType.direct);
|
||||
// notifyListeners();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// void Function(String)? _onError;
|
||||
//
|
||||
// void setOnError({
|
||||
// required void Function(String)? onError,
|
||||
// bool shouldNotifyListeners = false,
|
||||
// }) {
|
||||
// _onError = onError;
|
||||
// if (shouldNotifyListeners) {
|
||||
// notifyListeners();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// Future<void> updateRateEstimate(CNEstimateType direction) async {
|
||||
// if (market != null) {
|
||||
// Decimal? amount;
|
||||
// // set amount based on trade estimate direction
|
||||
// switch (direction) {
|
||||
// case CNEstimateType.direct:
|
||||
// if (_fromAmount != null
|
||||
// // &&
|
||||
// // market!.min >= _fromAmount! &&
|
||||
// // _fromAmount! <= market!.max
|
||||
// ) {
|
||||
// amount = _fromAmount!;
|
||||
// }
|
||||
// break;
|
||||
// case CNEstimateType.reverse:
|
||||
// if (_toAmount != null
|
||||
// // &&
|
||||
// // market!.min >= _toAmount! &&
|
||||
// // _toAmount! <= market!.max
|
||||
// ) {
|
||||
// amount = _toAmount!;
|
||||
// }
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// if (amount != null && market != null && amount > Decimal.zero) {
|
||||
// final response =
|
||||
// await ChangeNowAPI.instance.getEstimatedExchangeAmountV2(
|
||||
// fromTicker: market!.from,
|
||||
// toTicker: market!.to,
|
||||
// fromOrTo: direction,
|
||||
// flow: CNFlowType.fixedRate,
|
||||
// amount: amount,
|
||||
// );
|
||||
//
|
||||
// if (response.value != null) {
|
||||
// // update estimate if response succeeded
|
||||
// _estimate = response.value;
|
||||
//
|
||||
// _toAmount = _estimate?.toAmount;
|
||||
// _fromAmount = _estimate?.fromAmount;
|
||||
// notifyListeners();
|
||||
// } else if (response.exception != null) {
|
||||
// Logging.instance.log("updateRateEstimate(): ${response.exception}",
|
||||
// level: LogLevel.Warning);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
|
|
@ -6,6 +6,7 @@ import 'package:flutter/services.dart';
|
|||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:stackwallet/models/exchange/exchange_form_state.dart';
|
||||
import 'package:stackwallet/models/exchange/incomplete_exchange.dart';
|
||||
import 'package:stackwallet/models/exchange/response_objects/currency.dart';
|
||||
import 'package:stackwallet/models/exchange/response_objects/fixed_rate_market.dart';
|
||||
|
@ -21,9 +22,7 @@ import 'package:stackwallet/pages/exchange_view/sub_widgets/rate_type_toggle.dar
|
|||
import 'package:stackwallet/providers/exchange/available_currencies_state_provider.dart';
|
||||
import 'package:stackwallet/providers/exchange/available_floating_rate_pairs_state_provider.dart';
|
||||
import 'package:stackwallet/providers/exchange/change_now_provider.dart';
|
||||
import 'package:stackwallet/providers/exchange/estimate_rate_exchange_form_provider.dart';
|
||||
import 'package:stackwallet/providers/exchange/exchange_send_from_wallet_id_provider.dart';
|
||||
import 'package:stackwallet/providers/exchange/fixed_rate_exchange_form_provider.dart';
|
||||
import 'package:stackwallet/providers/exchange/fixed_rate_market_pairs_provider.dart';
|
||||
import 'package:stackwallet/providers/providers.dart';
|
||||
import 'package:stackwallet/utilities/assets.dart';
|
||||
|
@ -62,42 +61,27 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
|
|||
final FocusNode _receiveFocusNode = FocusNode();
|
||||
|
||||
bool _swapLock = false;
|
||||
bool _reversed = false;
|
||||
|
||||
void sendFieldOnChanged(String value) async {
|
||||
final newFromAmount = Decimal.tryParse(value);
|
||||
final isEstimated =
|
||||
ref.read(prefsChangeNotifierProvider).exchangeRateType ==
|
||||
ExchangeRateType.estimated;
|
||||
if (newFromAmount != null) {
|
||||
if (isEstimated) {
|
||||
await ref
|
||||
.read(estimatedRateExchangeFormProvider)
|
||||
.setFromAmountAndCalculateToAmount(newFromAmount, false);
|
||||
} else {
|
||||
await ref
|
||||
.read(fixedRateExchangeFormProvider)
|
||||
.setFromAmountAndCalculateToAmount(newFromAmount, false);
|
||||
}
|
||||
} else {
|
||||
if (isEstimated) {
|
||||
await ref
|
||||
.read(estimatedRateExchangeFormProvider)
|
||||
.setFromAmountAndCalculateToAmount(Decimal.zero, false);
|
||||
} else {
|
||||
await ref
|
||||
.read(fixedRateExchangeFormProvider)
|
||||
.setFromAmountAndCalculateToAmount(Decimal.zero, false);
|
||||
}
|
||||
_receiveController.text = isEstimated ? "-" : "";
|
||||
|
||||
ref.read(exchangeFormStateProvider).fromAmount =
|
||||
newFromAmount ?? Decimal.zero;
|
||||
|
||||
if (newFromAmount == null) {
|
||||
_receiveController.text =
|
||||
ref.read(prefsChangeNotifierProvider).exchangeRateType ==
|
||||
ExchangeRateType.estimated
|
||||
? "-"
|
||||
: "";
|
||||
}
|
||||
}
|
||||
|
||||
void selectSendCurrency() async {
|
||||
if (ref.read(prefsChangeNotifierProvider).exchangeRateType ==
|
||||
ExchangeRateType.estimated) {
|
||||
final fromTicker =
|
||||
ref.read(estimatedRateExchangeFormProvider).from?.ticker ?? "-";
|
||||
final fromTicker = ref.read(exchangeFormStateProvider).fromTicker ?? "-";
|
||||
// ref.read(estimatedRateExchangeFormProvider).from?.ticker ?? "-";
|
||||
|
||||
if (walletInitiated &&
|
||||
fromTicker.toLowerCase() == coin!.ticker.toLowerCase()) {
|
||||
|
@ -108,16 +92,13 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
|
|||
await _showFloatingRateSelectionSheet(
|
||||
currencies:
|
||||
ref.read(availableChangeNowCurrenciesStateProvider.state).state,
|
||||
excludedTicker:
|
||||
ref.read(estimatedRateExchangeFormProvider).to?.ticker ?? "-",
|
||||
excludedTicker: ref.read(exchangeFormStateProvider).toTicker ?? "-",
|
||||
fromTicker: fromTicker,
|
||||
onSelected: (from) => ref
|
||||
.read(estimatedRateExchangeFormProvider)
|
||||
.updateFrom(from, true));
|
||||
onSelected: (from) =>
|
||||
ref.read(exchangeFormStateProvider).updateFrom(from, true));
|
||||
} else {
|
||||
final toTicker = ref.read(fixedRateExchangeFormProvider).market?.to ?? "";
|
||||
final fromTicker =
|
||||
ref.read(fixedRateExchangeFormProvider).market?.from ?? "";
|
||||
final toTicker = ref.read(exchangeFormStateProvider).toTicker ?? "";
|
||||
final fromTicker = ref.read(exchangeFormStateProvider).fromTicker ?? "";
|
||||
|
||||
if (walletInitiated &&
|
||||
fromTicker.toLowerCase() == coin!.ticker.toLowerCase()) {
|
||||
|
@ -138,7 +119,7 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
|
|||
);
|
||||
|
||||
await ref
|
||||
.read(fixedRateExchangeFormProvider)
|
||||
.read(exchangeFormStateProvider)
|
||||
.updateMarket(market, true);
|
||||
} catch (e) {
|
||||
unawaited(showDialog<dynamic>(
|
||||
|
@ -158,8 +139,7 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
|
|||
void selectReceiveCurrency() async {
|
||||
if (ref.read(prefsChangeNotifierProvider).exchangeRateType ==
|
||||
ExchangeRateType.estimated) {
|
||||
final toTicker =
|
||||
ref.read(estimatedRateExchangeFormProvider).to?.ticker ?? "";
|
||||
final toTicker = ref.read(exchangeFormStateProvider).toTicker ?? "";
|
||||
|
||||
if (walletInitiated &&
|
||||
toTicker.toLowerCase() == coin!.ticker.toLowerCase()) {
|
||||
|
@ -170,16 +150,13 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
|
|||
await _showFloatingRateSelectionSheet(
|
||||
currencies:
|
||||
ref.read(availableChangeNowCurrenciesStateProvider.state).state,
|
||||
excludedTicker:
|
||||
ref.read(estimatedRateExchangeFormProvider).from?.ticker ?? "",
|
||||
fromTicker:
|
||||
ref.read(estimatedRateExchangeFormProvider).from?.ticker ?? "",
|
||||
excludedTicker: ref.read(exchangeFormStateProvider).fromTicker ?? "",
|
||||
fromTicker: ref.read(exchangeFormStateProvider).fromTicker ?? "",
|
||||
onSelected: (to) =>
|
||||
ref.read(estimatedRateExchangeFormProvider).updateTo(to, true));
|
||||
ref.read(exchangeFormStateProvider).updateTo(to, true));
|
||||
} else {
|
||||
final fromTicker =
|
||||
ref.read(fixedRateExchangeFormProvider).market?.from ?? "";
|
||||
final toTicker = ref.read(fixedRateExchangeFormProvider).market?.to ?? "";
|
||||
final fromTicker = ref.read(exchangeFormStateProvider).fromTicker ?? "";
|
||||
final toTicker = ref.read(exchangeFormStateProvider).toTicker ?? "";
|
||||
|
||||
if (walletInitiated &&
|
||||
toTicker.toLowerCase() == coin!.ticker.toLowerCase()) {
|
||||
|
@ -200,7 +177,7 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
|
|||
);
|
||||
|
||||
await ref
|
||||
.read(fixedRateExchangeFormProvider)
|
||||
.read(exchangeFormStateProvider)
|
||||
.updateMarket(market, true);
|
||||
} catch (e) {
|
||||
unawaited(showDialog<dynamic>(
|
||||
|
@ -222,28 +199,11 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
|
|||
final isEstimated =
|
||||
ref.read(prefsChangeNotifierProvider).exchangeRateType ==
|
||||
ExchangeRateType.estimated;
|
||||
if (newToAmount != null) {
|
||||
if (isEstimated) {
|
||||
// await ref
|
||||
// .read(estimatedRateExchangeFormProvider)
|
||||
// .setToAmountAndCalculateFromAmount(
|
||||
// newToAmount, false);
|
||||
} else {
|
||||
await ref
|
||||
.read(fixedRateExchangeFormProvider)
|
||||
.setToAmountAndCalculateFromAmount(newToAmount, false);
|
||||
}
|
||||
} else {
|
||||
if (isEstimated) {
|
||||
// await ref
|
||||
// .read(estimatedRateExchangeFormProvider)
|
||||
// .setToAmountAndCalculateFromAmount(
|
||||
// Decimal.zero, false);
|
||||
} else {
|
||||
await ref
|
||||
.read(fixedRateExchangeFormProvider)
|
||||
.setToAmountAndCalculateFromAmount(Decimal.zero, false);
|
||||
}
|
||||
if (!isEstimated) {
|
||||
ref.read(exchangeFormStateProvider).toAmount =
|
||||
newToAmount ?? Decimal.zero;
|
||||
}
|
||||
if (newToAmount == null) {
|
||||
_sendController.text = "";
|
||||
}
|
||||
}
|
||||
|
@ -276,10 +236,10 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
|
|||
if (ref.watch(prefsChangeNotifierProvider
|
||||
.select((pref) => pref.exchangeRateType)) ==
|
||||
ExchangeRateType.estimated) {
|
||||
await ref.read(estimatedRateExchangeFormProvider).swap();
|
||||
await ref.read(exchangeFormStateProvider).swap();
|
||||
} else {
|
||||
final from = ref.read(fixedRateExchangeFormProvider).market?.from;
|
||||
final to = ref.read(fixedRateExchangeFormProvider).market?.to;
|
||||
final from = ref.read(exchangeFormStateProvider).fromTicker;
|
||||
final to = ref.read(exchangeFormStateProvider).toTicker;
|
||||
|
||||
if (to != null && from != null) {
|
||||
final markets = ref
|
||||
|
@ -288,7 +248,7 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
|
|||
.where((e) => e.from == to && e.to == from);
|
||||
|
||||
if (markets.isNotEmpty) {
|
||||
await ref.read(fixedRateExchangeFormProvider).swap(markets.first);
|
||||
await ref.read(exchangeFormStateProvider).swap(market: markets.first);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -351,7 +311,7 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
|
|||
}
|
||||
}
|
||||
|
||||
String? _fetchIconUrlFromTickerForFixedRateFlow(String? ticker) {
|
||||
String? _fetchIconUrlFromTicker(String? ticker) {
|
||||
if (ticker == null) return null;
|
||||
|
||||
final possibleCurrencies = ref
|
||||
|
@ -417,15 +377,35 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
|
|||
void onRateTypeChanged(ExchangeRateType rateType) async {
|
||||
_receiveFocusNode.unfocus();
|
||||
_sendFocusNode.unfocus();
|
||||
|
||||
unawaited(
|
||||
showDialog<void>(
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
builder: (_) => WillPopScope(
|
||||
onWillPop: () async => false,
|
||||
child: Container(
|
||||
color: Theme.of(context)
|
||||
.extension<StackColors>()!
|
||||
.overlay
|
||||
.withOpacity(0.6),
|
||||
child: const CustomLoadingOverlay(
|
||||
message: "Updating exchange rate",
|
||||
eventBus: null,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
final fromTicker = ref.read(exchangeFormStateProvider).fromTicker ?? "-";
|
||||
final toTicker = ref.read(exchangeFormStateProvider).toTicker ?? "-";
|
||||
|
||||
ref.read(exchangeFormStateProvider).exchangeType = rateType;
|
||||
ref.read(exchangeFormStateProvider).reversed = false;
|
||||
switch (rateType) {
|
||||
case ExchangeRateType.estimated:
|
||||
final market = ref.read(fixedRateExchangeFormProvider).market;
|
||||
final fromTicker = market?.from ?? "";
|
||||
final toTicker = market?.to ?? "";
|
||||
if (!(fromTicker.isEmpty ||
|
||||
toTicker.isEmpty ||
|
||||
toTicker == "-" ||
|
||||
fromTicker == "-")) {
|
||||
if (!(toTicker == "-" || fromTicker == "-")) {
|
||||
final available = ref
|
||||
.read(availableFloatingRatePairsStateProvider.state)
|
||||
.state
|
||||
|
@ -442,28 +422,29 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
|
|||
availableCurrencies.firstWhere((e) => e.ticker == toTicker);
|
||||
|
||||
final newFromAmount = Decimal.tryParse(_sendController.text);
|
||||
if (newFromAmount != null) {
|
||||
await ref
|
||||
.read(estimatedRateExchangeFormProvider)
|
||||
.setFromAmountAndCalculateToAmount(newFromAmount, false);
|
||||
} else {
|
||||
await ref
|
||||
.read(estimatedRateExchangeFormProvider)
|
||||
.setFromAmountAndCalculateToAmount(Decimal.zero, false);
|
||||
|
||||
ref.read(exchangeFormStateProvider).fromAmount =
|
||||
newFromAmount ?? Decimal.zero;
|
||||
if (newFromAmount == null) {
|
||||
_receiveController.text = "";
|
||||
}
|
||||
|
||||
await ref
|
||||
.read(estimatedRateExchangeFormProvider)
|
||||
.updateTo(to, false);
|
||||
await ref
|
||||
.read(estimatedRateExchangeFormProvider)
|
||||
.updateFrom(from, true);
|
||||
await ref.read(exchangeFormStateProvider).updateTo(to, false);
|
||||
await ref.read(exchangeFormStateProvider).updateFrom(from, true);
|
||||
|
||||
_receiveController.text =
|
||||
ref.read(exchangeFormStateProvider).toAmountString.isEmpty
|
||||
? "-"
|
||||
: ref.read(exchangeFormStateProvider).toAmountString;
|
||||
if (mounted) {
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mounted) {
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
unawaited(showFloatingFlushBar(
|
||||
type: FlushBarType.warning,
|
||||
message:
|
||||
|
@ -472,14 +453,7 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
|
|||
));
|
||||
break;
|
||||
case ExchangeRateType.fixed:
|
||||
final fromTicker =
|
||||
ref.read(estimatedRateExchangeFormProvider).from?.ticker ?? "";
|
||||
final toTicker =
|
||||
ref.read(estimatedRateExchangeFormProvider).to?.ticker ?? "";
|
||||
if (!(fromTicker.isEmpty ||
|
||||
toTicker.isEmpty ||
|
||||
toTicker == "-" ||
|
||||
fromTicker == "-")) {
|
||||
if (!(toTicker == "-" || fromTicker == "-")) {
|
||||
FixedRateMarket? market;
|
||||
try {
|
||||
market = ref
|
||||
|
@ -491,29 +465,28 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
|
|||
}
|
||||
|
||||
final newFromAmount = Decimal.tryParse(_sendController.text);
|
||||
if (newFromAmount != null) {
|
||||
await ref
|
||||
.read(fixedRateExchangeFormProvider)
|
||||
.setFromAmountAndCalculateToAmount(newFromAmount, false);
|
||||
} else {
|
||||
await ref
|
||||
.read(fixedRateExchangeFormProvider)
|
||||
.setFromAmountAndCalculateToAmount(Decimal.zero, false);
|
||||
ref.read(exchangeFormStateProvider).fromAmount =
|
||||
newFromAmount ?? Decimal.zero;
|
||||
|
||||
if (newFromAmount == null) {
|
||||
_receiveController.text = "";
|
||||
}
|
||||
|
||||
await ref.read(exchangeFormStateProvider).updateMarket(market, false);
|
||||
await ref
|
||||
.read(fixedRateExchangeFormProvider)
|
||||
.updateMarket(market, false);
|
||||
await ref
|
||||
.read(fixedRateExchangeFormProvider)
|
||||
.read(exchangeFormStateProvider)
|
||||
.setFromAmountAndCalculateToAmount(
|
||||
Decimal.tryParse(_sendController.text) ?? Decimal.zero,
|
||||
true,
|
||||
);
|
||||
if (mounted) {
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (mounted) {
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
unawaited(showFloatingFlushBar(
|
||||
type: FlushBarType.warning,
|
||||
message:
|
||||
|
@ -527,10 +500,8 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
|
|||
void onExchangePressed() async {
|
||||
if (ref.read(prefsChangeNotifierProvider).exchangeRateType ==
|
||||
ExchangeRateType.estimated) {
|
||||
final fromTicker =
|
||||
ref.read(estimatedRateExchangeFormProvider).from?.ticker ?? "";
|
||||
final toTicker =
|
||||
ref.read(estimatedRateExchangeFormProvider).to?.ticker ?? "";
|
||||
final fromTicker = ref.read(exchangeFormStateProvider).fromTicker ?? "";
|
||||
final toTicker = ref.read(exchangeFormStateProvider).toTicker ?? "";
|
||||
|
||||
bool isAvailable = false;
|
||||
final availableFloatingPairs =
|
||||
|
@ -555,8 +526,7 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
|
|||
return;
|
||||
}
|
||||
|
||||
final sendAmount = Decimal.parse(
|
||||
ref.read(estimatedRateExchangeFormProvider).fromAmountString);
|
||||
final sendAmount = ref.read(exchangeFormStateProvider).fromAmount!;
|
||||
|
||||
final rateType = ref.read(prefsChangeNotifierProvider).exchangeRateType;
|
||||
|
||||
|
@ -610,12 +580,10 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
final fromTicker =
|
||||
ref.read(fixedRateExchangeFormProvider).market?.from ?? "";
|
||||
final toTicker = ref.read(fixedRateExchangeFormProvider).market?.to ?? "";
|
||||
final fromTicker = ref.read(exchangeFormStateProvider).fromTicker ?? "";
|
||||
final toTicker = ref.read(exchangeFormStateProvider).toTicker ?? "";
|
||||
|
||||
final sendAmount = Decimal.parse(
|
||||
ref.read(fixedRateExchangeFormProvider).fromAmountString);
|
||||
final sendAmount = ref.read(exchangeFormStateProvider).fromAmount!;
|
||||
|
||||
final rateType = ref.read(prefsChangeNotifierProvider).exchangeRateType;
|
||||
|
||||
|
@ -683,7 +651,7 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
|
|||
}
|
||||
|
||||
String rate =
|
||||
"1 ${fromTicker.toUpperCase()} ~${ref.read(fixedRateExchangeFormProvider).rate!.toStringAsFixed(8)} ${toTicker.toUpperCase()}";
|
||||
"1 ${fromTicker.toUpperCase()} ~${ref.read(exchangeFormStateProvider).rate!.toStringAsFixed(8)} ${toTicker.toUpperCase()}";
|
||||
|
||||
final model = IncompleteExchangeModel(
|
||||
sendTicker: fromTicker,
|
||||
|
@ -721,21 +689,10 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
|
|||
|
||||
String? ticker;
|
||||
|
||||
if (ref.read(prefsChangeNotifierProvider).exchangeRateType ==
|
||||
ExchangeRateType.estimated) {
|
||||
if (isSend) {
|
||||
ticker = ref.watch(estimatedRateExchangeFormProvider
|
||||
.select((value) => value.from?.ticker));
|
||||
} else {
|
||||
ticker = ref.watch(estimatedRateExchangeFormProvider
|
||||
.select((value) => value.to?.ticker));
|
||||
}
|
||||
if (isSend) {
|
||||
ticker = ref.read(exchangeFormStateProvider).fromTicker;
|
||||
} else {
|
||||
if (isSend) {
|
||||
ticker = ref.read(fixedRateExchangeFormProvider).market?.from;
|
||||
} else {
|
||||
ticker = ref.read(fixedRateExchangeFormProvider).market?.to;
|
||||
}
|
||||
ticker = ref.read(exchangeFormStateProvider).toTicker;
|
||||
}
|
||||
|
||||
if (ticker == null) {
|
||||
|
@ -756,46 +713,29 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
|
|||
|
||||
if (walletInitiated) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
||||
ref.read(estimatedRateExchangeFormProvider).clearAmounts(true);
|
||||
ref.read(exchangeFormStateProvider).clearAmounts(true);
|
||||
// ref.read(fixedRateExchangeFormProvider);
|
||||
});
|
||||
} else {
|
||||
final isEstimated =
|
||||
ref.read(prefsChangeNotifierProvider).exchangeRateType ==
|
||||
ExchangeRateType.estimated;
|
||||
_sendController.text = isEstimated
|
||||
? ref.read(estimatedRateExchangeFormProvider).fromAmountString
|
||||
: ref.read(fixedRateExchangeFormProvider).fromAmountString;
|
||||
_sendController.text =
|
||||
ref.read(exchangeFormStateProvider).fromAmountString;
|
||||
_receiveController.text = isEstimated
|
||||
? "-" //ref.read(estimatedRateExchangeFormProvider).toAmountString
|
||||
: ref.read(fixedRateExchangeFormProvider).toAmountString;
|
||||
: ref.read(exchangeFormStateProvider).toAmountString;
|
||||
}
|
||||
|
||||
_sendFocusNode.addListener(() async {
|
||||
if (!_sendFocusNode.hasFocus) {
|
||||
final newFromAmount = Decimal.tryParse(_sendController.text);
|
||||
if (newFromAmount != null) {
|
||||
if (ref.read(prefsChangeNotifierProvider).exchangeRateType ==
|
||||
ExchangeRateType.estimated) {
|
||||
await ref
|
||||
.read(estimatedRateExchangeFormProvider)
|
||||
.setFromAmountAndCalculateToAmount(newFromAmount, true);
|
||||
} else {
|
||||
await ref
|
||||
.read(fixedRateExchangeFormProvider)
|
||||
.setFromAmountAndCalculateToAmount(newFromAmount, true);
|
||||
}
|
||||
} else {
|
||||
if (ref.read(prefsChangeNotifierProvider).exchangeRateType ==
|
||||
ExchangeRateType.estimated) {
|
||||
await ref
|
||||
.read(estimatedRateExchangeFormProvider)
|
||||
.setFromAmountAndCalculateToAmount(Decimal.zero, true);
|
||||
} else {
|
||||
await ref
|
||||
.read(fixedRateExchangeFormProvider)
|
||||
.setFromAmountAndCalculateToAmount(Decimal.zero, true);
|
||||
}
|
||||
await ref
|
||||
.read(exchangeFormStateProvider)
|
||||
.setFromAmountAndCalculateToAmount(
|
||||
newFromAmount ?? Decimal.zero, true);
|
||||
|
||||
if (newFromAmount == null) {
|
||||
_receiveController.text =
|
||||
ref.read(prefsChangeNotifierProvider).exchangeRateType ==
|
||||
ExchangeRateType.estimated
|
||||
|
@ -807,28 +747,14 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
|
|||
_receiveFocusNode.addListener(() async {
|
||||
if (!_receiveFocusNode.hasFocus) {
|
||||
final newToAmount = Decimal.tryParse(_receiveController.text);
|
||||
if (newToAmount != null) {
|
||||
if (ref.read(prefsChangeNotifierProvider).exchangeRateType ==
|
||||
ExchangeRateType.estimated) {
|
||||
// await ref
|
||||
// .read(estimatedRateExchangeFormProvider)
|
||||
// .setToAmountAndCalculateFromAmount(newToAmount, true);
|
||||
} else {
|
||||
await ref
|
||||
.read(fixedRateExchangeFormProvider)
|
||||
.setToAmountAndCalculateFromAmount(newToAmount, true);
|
||||
}
|
||||
} else {
|
||||
if (ref.read(prefsChangeNotifierProvider).exchangeRateType ==
|
||||
ExchangeRateType.estimated) {
|
||||
// await ref
|
||||
// .read(estimatedRateExchangeFormProvider)
|
||||
// .setToAmountAndCalculateFromAmount(Decimal.zero, true);
|
||||
} else {
|
||||
await ref
|
||||
.read(fixedRateExchangeFormProvider)
|
||||
.setToAmountAndCalculateFromAmount(Decimal.zero, true);
|
||||
}
|
||||
if (ref.read(prefsChangeNotifierProvider).exchangeRateType !=
|
||||
ExchangeRateType.estimated) {
|
||||
await ref
|
||||
.read(exchangeFormStateProvider)
|
||||
.setToAmountAndCalculateFromAmount(
|
||||
newToAmount ?? Decimal.zero, true);
|
||||
}
|
||||
if (newToAmount == null) {
|
||||
_sendController.text = "";
|
||||
}
|
||||
}
|
||||
|
@ -853,39 +779,29 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
|
|||
ExchangeRateType.estimated;
|
||||
|
||||
ref.listen(
|
||||
isEstimated
|
||||
? estimatedRateExchangeFormProvider
|
||||
.select((value) => value.toAmountString)
|
||||
: fixedRateExchangeFormProvider.select(
|
||||
(value) => value.toAmountString), (previous, String next) {
|
||||
exchangeFormStateProvider.select((value) => value.toAmountString),
|
||||
(previous, String next) {
|
||||
if (!_receiveFocusNode.hasFocus) {
|
||||
_receiveController.text = isEstimated && next.isEmpty ? "-" : next;
|
||||
debugPrint("RECEIVE AMOUNT LISTENER ACTIVATED");
|
||||
if (_swapLock) {
|
||||
_sendController.text = isEstimated
|
||||
? ref.read(estimatedRateExchangeFormProvider).fromAmountString
|
||||
: ref.read(fixedRateExchangeFormProvider).fromAmountString;
|
||||
_sendController.text =
|
||||
ref.read(exchangeFormStateProvider).fromAmountString;
|
||||
}
|
||||
}
|
||||
});
|
||||
ref.listen(
|
||||
isEstimated
|
||||
? estimatedRateExchangeFormProvider
|
||||
.select((value) => value.fromAmountString)
|
||||
: fixedRateExchangeFormProvider.select(
|
||||
(value) => value.fromAmountString), (previous, String next) {
|
||||
exchangeFormStateProvider.select((value) => value.fromAmountString),
|
||||
(previous, String next) {
|
||||
if (!_sendFocusNode.hasFocus) {
|
||||
_sendController.text = next;
|
||||
debugPrint("SEND AMOUNT LISTENER ACTIVATED");
|
||||
if (_swapLock) {
|
||||
_receiveController.text = isEstimated
|
||||
? ref
|
||||
.read(estimatedRateExchangeFormProvider)
|
||||
.toAmountString
|
||||
.isEmpty
|
||||
? ref.read(exchangeFormStateProvider).toAmountString.isEmpty
|
||||
? "-"
|
||||
: ref.read(estimatedRateExchangeFormProvider).toAmountString
|
||||
: ref.read(fixedRateExchangeFormProvider).toAmountString;
|
||||
: ref.read(exchangeFormStateProvider).toAmountString
|
||||
: ref.read(exchangeFormStateProvider).toAmountString;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -956,20 +872,10 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
|
|||
),
|
||||
child: Builder(
|
||||
builder: (context) {
|
||||
String? image;
|
||||
if (ref.watch(prefsChangeNotifierProvider.select(
|
||||
(value) => value.exchangeRateType)) ==
|
||||
ExchangeRateType.estimated) {
|
||||
image = ref
|
||||
.watch(estimatedRateExchangeFormProvider
|
||||
.select((value) => value.from))
|
||||
?.image;
|
||||
} else {
|
||||
image = _fetchIconUrlFromTickerForFixedRateFlow(
|
||||
ref.watch(
|
||||
fixedRateExchangeFormProvider.select(
|
||||
(value) => value.market?.from)));
|
||||
}
|
||||
final image = _fetchIconUrlFromTicker(ref.watch(
|
||||
exchangeFormStateProvider
|
||||
.select((value) => value.fromTicker)));
|
||||
|
||||
if (image != null && image.isNotEmpty) {
|
||||
return Center(
|
||||
child: SvgPicture.network(
|
||||
|
@ -1020,17 +926,9 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
|
|||
width: 6,
|
||||
),
|
||||
Text(
|
||||
ref.watch(prefsChangeNotifierProvider.select(
|
||||
(value) => value.exchangeRateType)) ==
|
||||
ExchangeRateType.estimated
|
||||
? ref.watch(estimatedRateExchangeFormProvider
|
||||
.select((value) =>
|
||||
value.from?.ticker.toUpperCase())) ??
|
||||
"-"
|
||||
: ref.watch(fixedRateExchangeFormProvider.select(
|
||||
(value) =>
|
||||
value.market?.from.toUpperCase())) ??
|
||||
"-",
|
||||
ref.watch(exchangeFormStateProvider.select((value) =>
|
||||
value.fromTicker?.toUpperCase())) ??
|
||||
"-",
|
||||
style: STextStyles.smallMed14(context).copyWith(
|
||||
color: Theme.of(context)
|
||||
.extension<StackColors>()!
|
||||
|
@ -1105,14 +1003,13 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
|
|||
),
|
||||
Positioned.fill(
|
||||
child: Align(
|
||||
alignment: Alignment.topRight,
|
||||
alignment: ref.watch(exchangeFormStateProvider
|
||||
.select((value) => value.reversed))
|
||||
? Alignment.bottomRight
|
||||
: Alignment.topRight,
|
||||
child: Text(
|
||||
ref.read(prefsChangeNotifierProvider).exchangeRateType ==
|
||||
ExchangeRateType.estimated
|
||||
? ref.watch(estimatedRateExchangeFormProvider
|
||||
.select((value) => value.minimumSendWarning))
|
||||
: ref.watch(fixedRateExchangeFormProvider
|
||||
.select((value) => value.sendAmountWarning)),
|
||||
ref.watch(exchangeFormStateProvider
|
||||
.select((value) => value.warning)),
|
||||
style: STextStyles.errorSmall(context),
|
||||
),
|
||||
),
|
||||
|
@ -1179,19 +1076,10 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
|
|||
),
|
||||
child: Builder(
|
||||
builder: (context) {
|
||||
String? image;
|
||||
if (ref.watch(prefsChangeNotifierProvider.select(
|
||||
(value) => value.exchangeRateType)) ==
|
||||
ExchangeRateType.estimated) {
|
||||
image = ref
|
||||
.watch(estimatedRateExchangeFormProvider
|
||||
.select((value) => value.to))
|
||||
?.image;
|
||||
} else {
|
||||
image = _fetchIconUrlFromTickerForFixedRateFlow(
|
||||
ref.watch(fixedRateExchangeFormProvider
|
||||
.select((value) => value.market?.to)));
|
||||
}
|
||||
final image = _fetchIconUrlFromTicker(ref.watch(
|
||||
exchangeFormStateProvider
|
||||
.select((value) => value.toTicker)));
|
||||
|
||||
if (image != null && image.isNotEmpty) {
|
||||
return Center(
|
||||
child: SvgPicture.network(
|
||||
|
@ -1240,17 +1128,9 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
|
|||
width: 6,
|
||||
),
|
||||
Text(
|
||||
ref.watch(prefsChangeNotifierProvider.select(
|
||||
(value) => value.exchangeRateType)) ==
|
||||
ExchangeRateType.estimated
|
||||
? ref.watch(estimatedRateExchangeFormProvider
|
||||
.select((value) =>
|
||||
value.to?.ticker.toUpperCase())) ??
|
||||
"-"
|
||||
: ref.watch(fixedRateExchangeFormProvider.select(
|
||||
(value) =>
|
||||
value.market?.to.toUpperCase())) ??
|
||||
"-",
|
||||
ref.watch(exchangeFormStateProvider.select(
|
||||
(value) => value.toTicker?.toUpperCase())) ??
|
||||
"-",
|
||||
style: STextStyles.smallMed14(context).copyWith(
|
||||
color: Theme.of(context)
|
||||
.extension<StackColors>()!
|
||||
|
@ -1293,24 +1173,17 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
|
|||
fixedRate: ref.watch(prefsChangeNotifierProvider
|
||||
.select((value) => value.exchangeRateType)) ==
|
||||
ExchangeRateType.fixed,
|
||||
reversed: _reversed,
|
||||
reversed: ref.watch(
|
||||
exchangeFormStateProvider.select((value) => value.reversed)),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
PrimaryButton(
|
||||
enabled: ((ref.read(prefsChangeNotifierProvider).exchangeRateType ==
|
||||
ExchangeRateType.estimated)
|
||||
? ref.watch(estimatedRateExchangeFormProvider
|
||||
enabled: ref.watch(
|
||||
exchangeFormStateProvider.select((value) => value.canExchange)),
|
||||
onPressed: ref.watch(exchangeFormStateProvider
|
||||
.select((value) => value.canExchange))
|
||||
: ref.watch(fixedRateExchangeFormProvider
|
||||
.select((value) => value.canExchange))),
|
||||
onPressed: ((ref.read(prefsChangeNotifierProvider).exchangeRateType ==
|
||||
ExchangeRateType.estimated)
|
||||
? ref.watch(estimatedRateExchangeFormProvider
|
||||
.select((value) => value.canExchange))
|
||||
: ref.watch(fixedRateExchangeFormProvider
|
||||
.select((value) => value.canExchange)))
|
||||
? onExchangePressed
|
||||
: null,
|
||||
label: "Exchange",
|
||||
|
|
|
@ -2,22 +2,14 @@ import 'dart:async';
|
|||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:stackwallet/pages/exchange_view/exchange_form.dart';
|
||||
import 'package:stackwallet/pages/exchange_view/sub_widgets/exchange_rate_sheet.dart';
|
||||
import 'package:stackwallet/pages/exchange_view/trade_details_view.dart';
|
||||
import 'package:stackwallet/providers/exchange/changenow_initial_load_status.dart';
|
||||
import 'package:stackwallet/providers/exchange/estimate_rate_exchange_form_provider.dart';
|
||||
import 'package:stackwallet/providers/exchange/fixed_rate_exchange_form_provider.dart';
|
||||
import 'package:stackwallet/providers/exchange/trade_sent_from_stack_lookup_provider.dart';
|
||||
import 'package:stackwallet/providers/global/trades_service_provider.dart';
|
||||
import 'package:stackwallet/providers/providers.dart';
|
||||
import 'package:stackwallet/utilities/assets.dart';
|
||||
import 'package:stackwallet/utilities/constants.dart';
|
||||
import 'package:stackwallet/utilities/text_styles.dart';
|
||||
import 'package:stackwallet/utilities/theme/stack_colors.dart';
|
||||
import 'package:stackwallet/widgets/stack_dialog.dart';
|
||||
import 'package:stackwallet/widgets/trade_card.dart';
|
||||
import 'package:tuple/tuple.dart';
|
||||
|
||||
|
@ -191,137 +183,3 @@ class _ExchangeViewState extends ConsumerState<ExchangeView> {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
class RateInfo extends ConsumerWidget {
|
||||
const RateInfo({
|
||||
Key? key,
|
||||
required this.onChanged,
|
||||
}) : super(key: key);
|
||||
|
||||
final void Function(ExchangeRateType) onChanged;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final type = ref.watch(
|
||||
prefsChangeNotifierProvider.select((pref) => pref.exchangeRateType));
|
||||
final isEstimated = type == ExchangeRateType.estimated;
|
||||
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).extension<StackColors>()!.popupBG,
|
||||
borderRadius: BorderRadius.circular(
|
||||
Constants.size.circularBorderRadius,
|
||||
),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
TextButton(
|
||||
onPressed: kFixedRateEnabled
|
||||
? () async {
|
||||
if (isEstimated) {
|
||||
if (ref
|
||||
.read(
|
||||
changeNowFixedInitialLoadStatusStateProvider
|
||||
.state)
|
||||
.state ==
|
||||
ChangeNowLoadStatus.loading) {
|
||||
bool userPoppedDialog = false;
|
||||
await showDialog<void>(
|
||||
context: context,
|
||||
builder: (context) => Consumer(
|
||||
builder: (context, ref, __) {
|
||||
return StackOkDialog(
|
||||
title: "Loading rate data...",
|
||||
message:
|
||||
"Performing initial fetch of ChangeNOW fixed rate market data",
|
||||
onOkPressed: (value) {
|
||||
userPoppedDialog = value == "OK";
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
if (ref
|
||||
.read(
|
||||
changeNowFixedInitialLoadStatusStateProvider
|
||||
.state)
|
||||
.state ==
|
||||
ChangeNowLoadStatus.loading) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unawaited(showModalBottomSheet<dynamic>(
|
||||
backgroundColor: Colors.transparent,
|
||||
context: context,
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.vertical(
|
||||
top: Radius.circular(20),
|
||||
),
|
||||
),
|
||||
builder: (_) => const ExchangeRateSheet(),
|
||||
).then((value) {
|
||||
if (value is ExchangeRateType && value != type) {
|
||||
onChanged(value);
|
||||
}
|
||||
}));
|
||||
}
|
||||
: null,
|
||||
style: Theme.of(context).textButtonTheme.style?.copyWith(
|
||||
minimumSize: MaterialStateProperty.all(
|
||||
const Size(0, 0),
|
||||
),
|
||||
padding: MaterialStateProperty.all<EdgeInsetsGeometry>(
|
||||
const EdgeInsets.all(2),
|
||||
),
|
||||
backgroundColor: MaterialStateProperty.all<Color>(
|
||||
Colors.transparent,
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
isEstimated ? "Estimated rate" : "Fixed rate",
|
||||
style: STextStyles.itemSubtitle(context),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 6,
|
||||
),
|
||||
if (kFixedRateEnabled)
|
||||
SvgPicture.asset(
|
||||
Assets.svg.chevronDown,
|
||||
width: 5,
|
||||
height: 2.5,
|
||||
color: Theme.of(context)
|
||||
.extension<StackColors>()!
|
||||
.infoItemLabel,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
FittedBox(
|
||||
fit: BoxFit.scaleDown,
|
||||
child: ConstrainedBox(
|
||||
constraints: const BoxConstraints(
|
||||
minWidth: 1,
|
||||
),
|
||||
child: Text(
|
||||
isEstimated
|
||||
? ref.watch(estimatedRateExchangeFormProvider
|
||||
.select((value) => value.rateDisplayString))
|
||||
: ref.watch(fixedRateExchangeFormProvider
|
||||
.select((value) => value.rateDisplayString)),
|
||||
style: STextStyles.itemSubtitle12(context),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,12 +2,11 @@ import 'dart:async';
|
|||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:stackwallet/models/exchange/exchange_form_state.dart';
|
||||
import 'package:stackwallet/pages/exchange_view/exchange_view.dart';
|
||||
import 'package:stackwallet/providers/exchange/available_currencies_state_provider.dart';
|
||||
import 'package:stackwallet/providers/exchange/available_floating_rate_pairs_state_provider.dart';
|
||||
import 'package:stackwallet/providers/exchange/change_now_provider.dart';
|
||||
import 'package:stackwallet/providers/exchange/estimate_rate_exchange_form_provider.dart';
|
||||
import 'package:stackwallet/providers/exchange/fixed_rate_exchange_form_provider.dart';
|
||||
import 'package:stackwallet/providers/exchange/fixed_rate_market_pairs_provider.dart';
|
||||
import 'package:stackwallet/providers/providers.dart';
|
||||
import 'package:stackwallet/services/exchange/change_now/change_now_api.dart';
|
||||
|
@ -54,15 +53,15 @@ class _HomeViewButtonBarState extends ConsumerState<HomeViewButtonBar> {
|
|||
response2.value!;
|
||||
|
||||
if (response.value!.length > 1) {
|
||||
if (ref.read(estimatedRateExchangeFormProvider).from == null) {
|
||||
if (ref.read(exchangeFormStateProvider).from == null) {
|
||||
if (response.value!.where((e) => e.ticker == "btc").isNotEmpty) {
|
||||
await ref.read(estimatedRateExchangeFormProvider).updateFrom(
|
||||
await ref.read(exchangeFormStateProvider).updateFrom(
|
||||
response.value!.firstWhere((e) => e.ticker == "btc"), true);
|
||||
}
|
||||
}
|
||||
if (ref.read(estimatedRateExchangeFormProvider).to == null) {
|
||||
if (ref.read(exchangeFormStateProvider).to == null) {
|
||||
if (response.value!.where((e) => e.ticker == "doge").isNotEmpty) {
|
||||
await ref.read(estimatedRateExchangeFormProvider).updateTo(
|
||||
await ref.read(exchangeFormStateProvider).updateTo(
|
||||
response.value!.firstWhere((e) => e.ticker == "doge"), true);
|
||||
}
|
||||
}
|
||||
|
@ -97,13 +96,13 @@ class _HomeViewButtonBarState extends ConsumerState<HomeViewButtonBar> {
|
|||
ref.read(fixedRateMarketPairsStateProvider.state).state =
|
||||
response3.value!;
|
||||
|
||||
if (ref.read(fixedRateExchangeFormProvider).market == null) {
|
||||
if (ref.read(exchangeFormStateProvider).market == null) {
|
||||
final matchingMarkets =
|
||||
response3.value!.where((e) => e.to == "doge" && e.from == "btc");
|
||||
|
||||
if (matchingMarkets.isNotEmpty) {
|
||||
await ref
|
||||
.read(fixedRateExchangeFormProvider)
|
||||
.read(exchangeFormStateProvider)
|
||||
.updateMarket(matchingMarkets.first, true);
|
||||
}
|
||||
}
|
||||
|
@ -126,7 +125,7 @@ class _HomeViewButtonBarState extends ConsumerState<HomeViewButtonBar> {
|
|||
|
||||
@override
|
||||
void initState() {
|
||||
ref.read(estimatedRateExchangeFormProvider).setOnError(
|
||||
ref.read(exchangeFormStateProvider).setOnError(
|
||||
onError: (String message) => showDialog<dynamic>(
|
||||
context: context,
|
||||
barrierDismissible: true,
|
||||
|
|
|
@ -5,6 +5,7 @@ import 'package:event_bus/event_bus.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:stackwallet/models/exchange/exchange_form_state.dart';
|
||||
import 'package:stackwallet/notifications/show_flush_bar.dart';
|
||||
import 'package:stackwallet/pages/exchange_view/sub_widgets/exchange_rate_sheet.dart';
|
||||
import 'package:stackwallet/pages/exchange_view/wallet_initiated_exchange_view.dart';
|
||||
|
@ -19,7 +20,6 @@ import 'package:stackwallet/pages/wallet_view/sub_widgets/wallet_navigation_bar.
|
|||
import 'package:stackwallet/pages/wallet_view/sub_widgets/wallet_summary.dart';
|
||||
import 'package:stackwallet/pages/wallet_view/transaction_views/all_transactions_view.dart';
|
||||
import 'package:stackwallet/providers/exchange/available_currencies_state_provider.dart';
|
||||
import 'package:stackwallet/providers/exchange/estimate_rate_exchange_form_provider.dart';
|
||||
import 'package:stackwallet/providers/global/auto_swb_service_provider.dart';
|
||||
import 'package:stackwallet/providers/providers.dart';
|
||||
import 'package:stackwallet/providers/ui/transaction_filter_provider.dart';
|
||||
|
@ -250,6 +250,8 @@ class _WalletViewState extends ConsumerState<WalletView> {
|
|||
final walletId = ref.read(managerProvider).walletId;
|
||||
ref.read(prefsChangeNotifierProvider).exchangeRateType =
|
||||
ExchangeRateType.estimated;
|
||||
ref.read(exchangeFormStateProvider).exchangeType =
|
||||
ExchangeRateType.estimated;
|
||||
|
||||
final currencies = ref
|
||||
.read(availableChangeNowCurrenciesStateProvider.state)
|
||||
|
@ -258,28 +260,31 @@ class _WalletViewState extends ConsumerState<WalletView> {
|
|||
element.ticker.toLowerCase() == coin.ticker.toLowerCase());
|
||||
|
||||
if (currencies.isNotEmpty) {
|
||||
unawaited(ref
|
||||
.read(estimatedRateExchangeFormProvider)
|
||||
.updateFrom(currencies.first, false));
|
||||
unawaited(ref.read(estimatedRateExchangeFormProvider).updateTo(
|
||||
ref
|
||||
.read(availableChangeNowCurrenciesStateProvider.state)
|
||||
.state
|
||||
.firstWhere(
|
||||
(element) =>
|
||||
element.ticker.toLowerCase() != coin.ticker.toLowerCase(),
|
||||
),
|
||||
false));
|
||||
ref.read(exchangeFormStateProvider).setCurrencies(
|
||||
currencies.first,
|
||||
ref
|
||||
.read(availableChangeNowCurrenciesStateProvider.state)
|
||||
.state
|
||||
.firstWhere(
|
||||
(element) =>
|
||||
element.ticker.toLowerCase() !=
|
||||
coin.ticker.toLowerCase(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
unawaited(Navigator.of(context).pushNamed(
|
||||
WalletInitiatedExchangeView.routeName,
|
||||
arguments: Tuple3(
|
||||
walletId,
|
||||
coin,
|
||||
_loadCNData,
|
||||
),
|
||||
));
|
||||
if (mounted) {
|
||||
unawaited(
|
||||
Navigator.of(context).pushNamed(
|
||||
WalletInitiatedExchangeView.routeName,
|
||||
arguments: Tuple3(
|
||||
walletId,
|
||||
coin,
|
||||
_loadCNData,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:stackwallet/models/exchange/estimated_rate_exchange_form_state.dart';
|
||||
|
||||
final estimatedRateExchangeFormProvider =
|
||||
ChangeNotifierProvider((ref) => EstimatedRateExchangeFormState());
|
||||
// import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
// import 'package:stackwallet/models/exchange/estimated_rate_exchange_form_state.dart';
|
||||
//
|
||||
// final estimatedRateExchangeFormProvider =
|
||||
// ChangeNotifierProvider((ref) => EstimatedRateExchangeFormState());
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:stackwallet/models/exchange/fixed_rate_exchange_form_state.dart';
|
||||
|
||||
final fixedRateExchangeFormProvider =
|
||||
ChangeNotifierProvider<FixedRateExchangeFormState>(
|
||||
(ref) => FixedRateExchangeFormState());
|
||||
// import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
// import 'package:stackwallet/models/exchange/fixed_rate_exchange_form_state.dart';
|
||||
//
|
||||
// final fixedRateExchangeFormProvider =
|
||||
// ChangeNotifierProvider<FixedRateExchangeFormState>(
|
||||
// (ref) => FixedRateExchangeFormState());
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:stackwallet/models/exchange/exchange_form_state.dart';
|
||||
import 'package:stackwallet/providers/exchange/available_currencies_state_provider.dart';
|
||||
import 'package:stackwallet/providers/exchange/available_floating_rate_pairs_state_provider.dart';
|
||||
import 'package:stackwallet/providers/exchange/changenow_initial_load_status.dart';
|
||||
import 'package:stackwallet/providers/exchange/estimate_rate_exchange_form_provider.dart';
|
||||
import 'package:stackwallet/providers/exchange/fixed_rate_exchange_form_provider.dart';
|
||||
import 'package:stackwallet/providers/exchange/fixed_rate_market_pairs_provider.dart';
|
||||
import 'package:stackwallet/services/exchange/change_now/change_now_api.dart';
|
||||
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||
|
@ -38,7 +37,7 @@ class ChangeNowLoadingService {
|
|||
ref.read(fixedRateMarketPairsStateProvider.state).state =
|
||||
response3.value!;
|
||||
|
||||
if (ref.read(fixedRateExchangeFormProvider).market == null) {
|
||||
if (ref.read(exchangeFormStateProvider).market == null) {
|
||||
String fromTicker = "btc";
|
||||
String toTicker = "xmr";
|
||||
|
||||
|
@ -50,7 +49,7 @@ class ChangeNowLoadingService {
|
|||
.where((e) => e.to == toTicker && e.from == fromTicker);
|
||||
if (matchingMarkets.isNotEmpty) {
|
||||
await ref
|
||||
.read(fixedRateExchangeFormProvider)
|
||||
.read(exchangeFormStateProvider)
|
||||
.updateMarket(matchingMarkets.first, true);
|
||||
}
|
||||
}
|
||||
|
@ -99,18 +98,18 @@ class ChangeNowLoadingService {
|
|||
}
|
||||
|
||||
if (response.value!.length > 1) {
|
||||
if (ref.read(estimatedRateExchangeFormProvider).from == null) {
|
||||
if (ref.read(exchangeFormStateProvider).from == null) {
|
||||
if (response.value!
|
||||
.where((e) => e.ticker == fromTicker)
|
||||
.isNotEmpty) {
|
||||
await ref.read(estimatedRateExchangeFormProvider).updateFrom(
|
||||
await ref.read(exchangeFormStateProvider).updateFrom(
|
||||
response.value!.firstWhere((e) => e.ticker == fromTicker),
|
||||
false);
|
||||
}
|
||||
}
|
||||
if (ref.read(estimatedRateExchangeFormProvider).to == null) {
|
||||
if (ref.read(exchangeFormStateProvider).to == null) {
|
||||
if (response.value!.where((e) => e.ticker == toTicker).isNotEmpty) {
|
||||
await ref.read(estimatedRateExchangeFormProvider).updateTo(
|
||||
await ref.read(exchangeFormStateProvider).updateTo(
|
||||
response.value!.firstWhere((e) => e.ticker == toTicker),
|
||||
false);
|
||||
}
|
||||
|
|
|
@ -1,219 +1,219 @@
|
|||
import 'package:decimal/decimal.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mockito/annotations.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:stackwallet/models/exchange/estimated_rate_exchange_form_state.dart';
|
||||
import 'package:stackwallet/models/exchange/response_objects/currency.dart';
|
||||
import 'package:stackwallet/models/exchange/response_objects/estimate.dart';
|
||||
import 'package:stackwallet/services/exchange/change_now/change_now_api.dart';
|
||||
import 'package:stackwallet/services/exchange/exchange_response.dart';
|
||||
|
||||
import 'estimated_rate_exchange_form_state_test.mocks.dart';
|
||||
|
||||
@GenerateMocks([ChangeNowAPI])
|
||||
void main() {
|
||||
final currencyA = Currency(
|
||||
ticker: "btc",
|
||||
name: "Bitcoin",
|
||||
image: "image.url",
|
||||
hasExternalId: false,
|
||||
isFiat: false,
|
||||
featured: false,
|
||||
isStable: true,
|
||||
supportsFixedRate: true,
|
||||
network: '',
|
||||
);
|
||||
final currencyB = Currency(
|
||||
ticker: "xmr",
|
||||
name: "Monero",
|
||||
image: "image.url",
|
||||
hasExternalId: false,
|
||||
isFiat: false,
|
||||
featured: false,
|
||||
isStable: true,
|
||||
supportsFixedRate: true,
|
||||
network: '',
|
||||
);
|
||||
final currencyC = Currency(
|
||||
ticker: "firo",
|
||||
name: "Firo",
|
||||
image: "image.url",
|
||||
hasExternalId: false,
|
||||
isFiat: false,
|
||||
featured: false,
|
||||
isStable: true,
|
||||
supportsFixedRate: true,
|
||||
network: '',
|
||||
);
|
||||
|
||||
test("EstimatedRateExchangeFormState constructor", () async {
|
||||
final state = EstimatedRateExchangeFormState();
|
||||
|
||||
expect(state.from, null);
|
||||
expect(state.to, null);
|
||||
expect(state.canExchange, false);
|
||||
expect(state.rate, null);
|
||||
expect(state.rateDisplayString, "N/A");
|
||||
expect(state.fromAmountString, "");
|
||||
expect(state.toAmountString, "");
|
||||
expect(state.minimumSendWarning, "");
|
||||
});
|
||||
|
||||
test("init EstimatedRateExchangeFormState", () async {
|
||||
final state = EstimatedRateExchangeFormState();
|
||||
|
||||
await state.init(currencyA, currencyB);
|
||||
|
||||
expect(state.from, currencyA);
|
||||
expect(state.to, currencyB);
|
||||
expect(state.canExchange, false);
|
||||
expect(state.rate, null);
|
||||
expect(state.rateDisplayString, "N/A");
|
||||
expect(state.fromAmountString, "");
|
||||
expect(state.toAmountString, "");
|
||||
expect(state.minimumSendWarning, "");
|
||||
});
|
||||
|
||||
test("updateTo on fresh state", () async {
|
||||
final state = EstimatedRateExchangeFormState();
|
||||
|
||||
await state.updateTo(currencyA, false);
|
||||
|
||||
expect(state.from, null);
|
||||
expect(state.to, currencyA);
|
||||
expect(state.canExchange, false);
|
||||
expect(state.rate, null);
|
||||
expect(state.rateDisplayString, "N/A");
|
||||
expect(state.fromAmountString, "");
|
||||
expect(state.toAmountString, "");
|
||||
expect(state.minimumSendWarning, "");
|
||||
});
|
||||
|
||||
test(
|
||||
"updateTo after updateFrom where amounts are null and getMinimalExchangeAmount succeeds",
|
||||
() async {
|
||||
final cn = MockChangeNowAPI();
|
||||
|
||||
final state = EstimatedRateExchangeFormState();
|
||||
state.cnTesting = cn;
|
||||
|
||||
when(cn.getMinimalExchangeAmount(fromTicker: "btc", toTicker: "xmr"))
|
||||
.thenAnswer((_) async => ExchangeResponse(value: Decimal.fromInt(42)));
|
||||
|
||||
await state.updateFrom(currencyA, true);
|
||||
await state.updateTo(currencyB, true);
|
||||
|
||||
expect(state.from, currencyA);
|
||||
expect(state.to, currencyB);
|
||||
expect(state.canExchange, false);
|
||||
expect(state.rate, null);
|
||||
expect(state.rateDisplayString, "N/A");
|
||||
expect(state.fromAmountString, "");
|
||||
expect(state.toAmountString, "");
|
||||
expect(state.minimumSendWarning, "");
|
||||
|
||||
verify(cn.getMinimalExchangeAmount(fromTicker: "btc", toTicker: "xmr"))
|
||||
.called(1);
|
||||
});
|
||||
|
||||
test(
|
||||
"updateTo after updateFrom where amounts are null and getMinimalExchangeAmount fails",
|
||||
() async {
|
||||
final cn = MockChangeNowAPI();
|
||||
|
||||
final state = EstimatedRateExchangeFormState();
|
||||
state.cnTesting = cn;
|
||||
|
||||
when(cn.getMinimalExchangeAmount(fromTicker: "btc", toTicker: "xmr"))
|
||||
.thenAnswer((_) async => ExchangeResponse());
|
||||
|
||||
await state.updateFrom(currencyA, true);
|
||||
await state.updateTo(currencyB, true);
|
||||
|
||||
expect(state.from, currencyA);
|
||||
expect(state.to, currencyB);
|
||||
expect(state.canExchange, false);
|
||||
expect(state.rate, null);
|
||||
expect(state.rateDisplayString, "N/A");
|
||||
expect(state.fromAmountString, "");
|
||||
expect(state.toAmountString, "");
|
||||
expect(state.minimumSendWarning, "");
|
||||
|
||||
verify(cn.getMinimalExchangeAmount(fromTicker: "btc", toTicker: "xmr"))
|
||||
.called(1);
|
||||
});
|
||||
|
||||
test(
|
||||
"updateTo after updateFrom and setFromAmountAndCalculateToAmount where fromAmount is less than the minimum required exchange amount",
|
||||
() async {
|
||||
final cn = MockChangeNowAPI();
|
||||
|
||||
final state = EstimatedRateExchangeFormState();
|
||||
state.cnTesting = cn;
|
||||
|
||||
when(cn.getMinimalExchangeAmount(fromTicker: "btc", toTicker: "xmr"))
|
||||
.thenAnswer((_) async => ExchangeResponse(value: Decimal.fromInt(42)));
|
||||
|
||||
await state.updateFrom(currencyA, true);
|
||||
await state.setFromAmountAndCalculateToAmount(Decimal.parse("10.10"), true);
|
||||
await state.updateTo(currencyB, true);
|
||||
|
||||
expect(state.from, currencyA);
|
||||
expect(state.to, currencyB);
|
||||
expect(state.canExchange, false);
|
||||
expect(state.rate, null);
|
||||
expect(state.rateDisplayString, "N/A");
|
||||
expect(state.fromAmountString, "10.10000000");
|
||||
expect(state.toAmountString, "");
|
||||
expect(state.minimumSendWarning, "Minimum amount 42 BTC");
|
||||
|
||||
verify(cn.getMinimalExchangeAmount(fromTicker: "btc", toTicker: "xmr"))
|
||||
.called(1);
|
||||
});
|
||||
|
||||
test(
|
||||
"updateTo after updateFrom and setFromAmountAndCalculateToAmount where fromAmount is greater than the minimum required exchange amount",
|
||||
() async {
|
||||
final cn = MockChangeNowAPI();
|
||||
|
||||
final state = EstimatedRateExchangeFormState();
|
||||
state.cnTesting = cn;
|
||||
|
||||
when(cn.getMinimalExchangeAmount(fromTicker: "btc", toTicker: "xmr"))
|
||||
.thenAnswer((_) async => ExchangeResponse(value: Decimal.fromInt(42)));
|
||||
when(cn.getEstimatedExchangeAmount(
|
||||
fromTicker: "btc",
|
||||
toTicker: "xmr",
|
||||
fromAmount: Decimal.parse("110.10")))
|
||||
.thenAnswer((_) async => ExchangeResponse(
|
||||
value: Estimate(
|
||||
reversed: false,
|
||||
fixedRate: false,
|
||||
rateId: 'some rate id',
|
||||
warningMessage: '',
|
||||
estimatedAmount: Decimal.parse("302.002348"),
|
||||
)));
|
||||
|
||||
await state.updateFrom(currencyA, true);
|
||||
await state.setFromAmountAndCalculateToAmount(
|
||||
Decimal.parse("110.10"), true);
|
||||
await state.updateTo(currencyB, true);
|
||||
|
||||
expect(state.from, currencyA);
|
||||
expect(state.to, currencyB);
|
||||
expect(state.canExchange, true);
|
||||
expect(state.rate, Decimal.parse("2.742982270663"));
|
||||
expect(state.rateDisplayString, "1 BTC ~2.74298227 XMR");
|
||||
expect(state.fromAmountString, "110.10000000");
|
||||
expect(state.toAmountString, "302.00234800");
|
||||
expect(state.minimumSendWarning, "");
|
||||
|
||||
verify(cn.getMinimalExchangeAmount(fromTicker: "btc", toTicker: "xmr"))
|
||||
.called(1);
|
||||
verify(cn.getEstimatedExchangeAmount(
|
||||
fromTicker: "btc",
|
||||
toTicker: "xmr",
|
||||
fromAmount: Decimal.parse("110.10")))
|
||||
.called(1);
|
||||
});
|
||||
}
|
||||
// import 'package:decimal/decimal.dart';
|
||||
// import 'package:flutter_test/flutter_test.dart';
|
||||
// import 'package:mockito/annotations.dart';
|
||||
// import 'package:mockito/mockito.dart';
|
||||
// import 'package:stackwallet/models/exchange/estimated_rate_exchange_form_state.dart';
|
||||
// import 'package:stackwallet/models/exchange/response_objects/currency.dart';
|
||||
// import 'package:stackwallet/models/exchange/response_objects/estimate.dart';
|
||||
// import 'package:stackwallet/services/exchange/change_now/change_now_api.dart';
|
||||
// import 'package:stackwallet/services/exchange/exchange_response.dart';
|
||||
//
|
||||
// import 'estimated_rate_exchange_form_state_test.mocks.dart';
|
||||
//
|
||||
// @GenerateMocks([ChangeNowAPI])
|
||||
// void main() {
|
||||
// final currencyA = Currency(
|
||||
// ticker: "btc",
|
||||
// name: "Bitcoin",
|
||||
// image: "image.url",
|
||||
// hasExternalId: false,
|
||||
// isFiat: false,
|
||||
// featured: false,
|
||||
// isStable: true,
|
||||
// supportsFixedRate: true,
|
||||
// network: '',
|
||||
// );
|
||||
// final currencyB = Currency(
|
||||
// ticker: "xmr",
|
||||
// name: "Monero",
|
||||
// image: "image.url",
|
||||
// hasExternalId: false,
|
||||
// isFiat: false,
|
||||
// featured: false,
|
||||
// isStable: true,
|
||||
// supportsFixedRate: true,
|
||||
// network: '',
|
||||
// );
|
||||
// final currencyC = Currency(
|
||||
// ticker: "firo",
|
||||
// name: "Firo",
|
||||
// image: "image.url",
|
||||
// hasExternalId: false,
|
||||
// isFiat: false,
|
||||
// featured: false,
|
||||
// isStable: true,
|
||||
// supportsFixedRate: true,
|
||||
// network: '',
|
||||
// );
|
||||
//
|
||||
// test("EstimatedRateExchangeFormState constructor", () async {
|
||||
// final state = EstimatedRateExchangeFormState();
|
||||
//
|
||||
// expect(state.from, null);
|
||||
// expect(state.to, null);
|
||||
// expect(state.canExchange, false);
|
||||
// expect(state.rate, null);
|
||||
// expect(state.rateDisplayString, "N/A");
|
||||
// expect(state.fromAmountString, "");
|
||||
// expect(state.toAmountString, "");
|
||||
// expect(state.minimumSendWarning, "");
|
||||
// });
|
||||
//
|
||||
// test("init EstimatedRateExchangeFormState", () async {
|
||||
// final state = EstimatedRateExchangeFormState();
|
||||
//
|
||||
// await state.init(currencyA, currencyB);
|
||||
//
|
||||
// expect(state.from, currencyA);
|
||||
// expect(state.to, currencyB);
|
||||
// expect(state.canExchange, false);
|
||||
// expect(state.rate, null);
|
||||
// expect(state.rateDisplayString, "N/A");
|
||||
// expect(state.fromAmountString, "");
|
||||
// expect(state.toAmountString, "");
|
||||
// expect(state.minimumSendWarning, "");
|
||||
// });
|
||||
//
|
||||
// test("updateTo on fresh state", () async {
|
||||
// final state = EstimatedRateExchangeFormState();
|
||||
//
|
||||
// await state.updateTo(currencyA, false);
|
||||
//
|
||||
// expect(state.from, null);
|
||||
// expect(state.to, currencyA);
|
||||
// expect(state.canExchange, false);
|
||||
// expect(state.rate, null);
|
||||
// expect(state.rateDisplayString, "N/A");
|
||||
// expect(state.fromAmountString, "");
|
||||
// expect(state.toAmountString, "");
|
||||
// expect(state.minimumSendWarning, "");
|
||||
// });
|
||||
//
|
||||
// test(
|
||||
// "updateTo after updateFrom where amounts are null and getMinimalExchangeAmount succeeds",
|
||||
// () async {
|
||||
// final cn = MockChangeNowAPI();
|
||||
//
|
||||
// final state = EstimatedRateExchangeFormState();
|
||||
// state.cnTesting = cn;
|
||||
//
|
||||
// when(cn.getMinimalExchangeAmount(fromTicker: "btc", toTicker: "xmr"))
|
||||
// .thenAnswer((_) async => ExchangeResponse(value: Decimal.fromInt(42)));
|
||||
//
|
||||
// await state.updateFrom(currencyA, true);
|
||||
// await state.updateTo(currencyB, true);
|
||||
//
|
||||
// expect(state.from, currencyA);
|
||||
// expect(state.to, currencyB);
|
||||
// expect(state.canExchange, false);
|
||||
// expect(state.rate, null);
|
||||
// expect(state.rateDisplayString, "N/A");
|
||||
// expect(state.fromAmountString, "");
|
||||
// expect(state.toAmountString, "");
|
||||
// expect(state.minimumSendWarning, "");
|
||||
//
|
||||
// verify(cn.getMinimalExchangeAmount(fromTicker: "btc", toTicker: "xmr"))
|
||||
// .called(1);
|
||||
// });
|
||||
//
|
||||
// test(
|
||||
// "updateTo after updateFrom where amounts are null and getMinimalExchangeAmount fails",
|
||||
// () async {
|
||||
// final cn = MockChangeNowAPI();
|
||||
//
|
||||
// final state = EstimatedRateExchangeFormState();
|
||||
// state.cnTesting = cn;
|
||||
//
|
||||
// when(cn.getMinimalExchangeAmount(fromTicker: "btc", toTicker: "xmr"))
|
||||
// .thenAnswer((_) async => ExchangeResponse());
|
||||
//
|
||||
// await state.updateFrom(currencyA, true);
|
||||
// await state.updateTo(currencyB, true);
|
||||
//
|
||||
// expect(state.from, currencyA);
|
||||
// expect(state.to, currencyB);
|
||||
// expect(state.canExchange, false);
|
||||
// expect(state.rate, null);
|
||||
// expect(state.rateDisplayString, "N/A");
|
||||
// expect(state.fromAmountString, "");
|
||||
// expect(state.toAmountString, "");
|
||||
// expect(state.minimumSendWarning, "");
|
||||
//
|
||||
// verify(cn.getMinimalExchangeAmount(fromTicker: "btc", toTicker: "xmr"))
|
||||
// .called(1);
|
||||
// });
|
||||
//
|
||||
// test(
|
||||
// "updateTo after updateFrom and setFromAmountAndCalculateToAmount where fromAmount is less than the minimum required exchange amount",
|
||||
// () async {
|
||||
// final cn = MockChangeNowAPI();
|
||||
//
|
||||
// final state = EstimatedRateExchangeFormState();
|
||||
// state.cnTesting = cn;
|
||||
//
|
||||
// when(cn.getMinimalExchangeAmount(fromTicker: "btc", toTicker: "xmr"))
|
||||
// .thenAnswer((_) async => ExchangeResponse(value: Decimal.fromInt(42)));
|
||||
//
|
||||
// await state.updateFrom(currencyA, true);
|
||||
// await state.setFromAmountAndCalculateToAmount(Decimal.parse("10.10"), true);
|
||||
// await state.updateTo(currencyB, true);
|
||||
//
|
||||
// expect(state.from, currencyA);
|
||||
// expect(state.to, currencyB);
|
||||
// expect(state.canExchange, false);
|
||||
// expect(state.rate, null);
|
||||
// expect(state.rateDisplayString, "N/A");
|
||||
// expect(state.fromAmountString, "10.10000000");
|
||||
// expect(state.toAmountString, "");
|
||||
// expect(state.minimumSendWarning, "Minimum amount 42 BTC");
|
||||
//
|
||||
// verify(cn.getMinimalExchangeAmount(fromTicker: "btc", toTicker: "xmr"))
|
||||
// .called(1);
|
||||
// });
|
||||
//
|
||||
// test(
|
||||
// "updateTo after updateFrom and setFromAmountAndCalculateToAmount where fromAmount is greater than the minimum required exchange amount",
|
||||
// () async {
|
||||
// final cn = MockChangeNowAPI();
|
||||
//
|
||||
// final state = EstimatedRateExchangeFormState();
|
||||
// state.cnTesting = cn;
|
||||
//
|
||||
// when(cn.getMinimalExchangeAmount(fromTicker: "btc", toTicker: "xmr"))
|
||||
// .thenAnswer((_) async => ExchangeResponse(value: Decimal.fromInt(42)));
|
||||
// when(cn.getEstimatedExchangeAmount(
|
||||
// fromTicker: "btc",
|
||||
// toTicker: "xmr",
|
||||
// fromAmount: Decimal.parse("110.10")))
|
||||
// .thenAnswer((_) async => ExchangeResponse(
|
||||
// value: Estimate(
|
||||
// reversed: false,
|
||||
// fixedRate: false,
|
||||
// rateId: 'some rate id',
|
||||
// warningMessage: '',
|
||||
// estimatedAmount: Decimal.parse("302.002348"),
|
||||
// )));
|
||||
//
|
||||
// await state.updateFrom(currencyA, true);
|
||||
// await state.setFromAmountAndCalculateToAmount(
|
||||
// Decimal.parse("110.10"), true);
|
||||
// await state.updateTo(currencyB, true);
|
||||
//
|
||||
// expect(state.from, currencyA);
|
||||
// expect(state.to, currencyB);
|
||||
// expect(state.canExchange, true);
|
||||
// expect(state.rate, Decimal.parse("2.742982270663"));
|
||||
// expect(state.rateDisplayString, "1 BTC ~2.74298227 XMR");
|
||||
// expect(state.fromAmountString, "110.10000000");
|
||||
// expect(state.toAmountString, "302.00234800");
|
||||
// expect(state.minimumSendWarning, "");
|
||||
//
|
||||
// verify(cn.getMinimalExchangeAmount(fromTicker: "btc", toTicker: "xmr"))
|
||||
// .called(1);
|
||||
// verify(cn.getEstimatedExchangeAmount(
|
||||
// fromTicker: "btc",
|
||||
// toTicker: "xmr",
|
||||
// fromAmount: Decimal.parse("110.10")))
|
||||
// .called(1);
|
||||
// });
|
||||
// }
|
||||
|
|
Loading…
Reference in a new issue