added simpleswap data loading, cleaned up providers, modified exchange process

This commit is contained in:
julian 2022-10-04 11:06:14 -06:00
parent 9189754363
commit 2c8ba8405f
25 changed files with 646 additions and 456 deletions

View file

@ -18,7 +18,6 @@ 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';
@ -41,7 +40,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_exchange.dart';
import 'package:stackwallet/services/exchange/change_now/change_now_loading_service.dart';
import 'package:stackwallet/services/exchange/exchange_data_loading_service.dart';
import 'package:stackwallet/services/locale_service.dart';
import 'package:stackwallet/services/node_service.dart';
import 'package:stackwallet/services/notifications_api.dart';
@ -229,7 +228,7 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme>
// run without awaiting
if (Constants.enableExchange) {
unawaited(ChangeNowLoadingService().loadAll(ref));
unawaited(ExchangeDataLoadingService().loadAll(ref));
}
if (_prefs.isAutoBackupEnabled) {
@ -249,102 +248,6 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme>
}
}
// Future<void> _loadChangeNowStandardCurrencies() async {
// if (ref
// .read(availableChangeNowCurrenciesStateProvider.state)
// .state
// .isNotEmpty &&
// ref
// .read(availableFloatingRatePairsStateProvider.state)
// .state
// .isNotEmpty) {
// return;
// }
// final response = await ChangeNowAPI.instance.getAvailableCurrencies();
// final response2 =
// await ChangeNowAPI.instance.getAvailableFloatingRatePairs();
// if (response.value != null) {
// ref.read(availableChangeNowCurrenciesStateProvider.state).state =
// response.value!;
// if (response2.value != null) {
// ref.read(availableFloatingRatePairsStateProvider.state).state =
// response2.value!;
//
// if (response.value!.length > 1) {
// if (ref.read(exchangeFormStateProvider).from == null) {
// if (response.value!.where((e) => e.ticker == "btc").isNotEmpty) {
// await ref.read(exchangeFormStateProvider).updateFrom(
// response.value!.firstWhere((e) => e.ticker == "btc"), false);
// }
// }
// if (ref.read(exchangeFormStateProvider).to == null) {
// if (response.value!.where((e) => e.ticker == "doge").isNotEmpty) {
// await ref.read(exchangeFormStateProvider).updateTo(
// response.value!.firstWhere((e) => e.ticker == "doge"), false);
// }
// }
// }
// } else {
// Logging.instance.log(
// "Failed to load changeNOW available floating rate pairs: ${response2.exception?.errorMessage}",
// level: LogLevel.Error);
// ref.read(changeNowEstimatedInitialLoadStatusStateProvider.state).state =
// ChangeNowLoadStatus.failed;
// return;
// }
// } else {
// Logging.instance.log(
// "Failed to load changeNOW currencies: ${response.exception?.errorMessage}",
// level: LogLevel.Error);
// await Future<void>.delayed(const Duration(seconds: 1));
// ref.read(changeNowEstimatedInitialLoadStatusStateProvider.state).state =
// ChangeNowLoadStatus.failed;
// return;
// }
//
// ref.read(changeNowEstimatedInitialLoadStatusStateProvider.state).state =
// ChangeNowLoadStatus.success;
// }
// Future<void> _loadFixedRateMarkets() async {
// Logging.instance.log("Starting initial fixed rate market data loading...",
// level: LogLevel.Info);
// if (ref.read(fixedRateMarketPairsStateProvider.state).state.isNotEmpty) {
// return;
// }
//
// final response3 =
// await ChangeNowAPI.instance.getAvailableFixedRateMarkets();
// if (response3.value != null) {
// ref.read(fixedRateMarketPairsStateProvider.state).state =
// response3.value!;
//
// if (ref.read(exchangeFormStateProvider).market == null) {
// final matchingMarkets =
// response3.value!.where((e) => e.to == "doge" && e.from == "btc");
// if (matchingMarkets.isNotEmpty) {
// await ref
// .read(exchangeFormStateProvider)
// .updateMarket(matchingMarkets.first, true);
// }
// }
//
// Logging.instance.log("Initial fixed rate market data loading complete.",
// level: LogLevel.Info);
// } else {
// Logging.instance.log(
// "Failed to load changeNOW fixed rate markets: ${response3.exception?.errorMessage}",
// level: LogLevel.Error);
//
// ref.read(changeNowFixedInitialLoadStatusStateProvider.state).state =
// ChangeNowLoadStatus.failed;
// return;
// }
//
// ref.read(changeNowFixedInitialLoadStatusStateProvider.state).state =
// ChangeNowLoadStatus.success;
// }
@override
void initState() {
ref.read(exchangeFormStateProvider).exchange = ChangeNowExchange();

View file

@ -0,0 +1,24 @@
import 'package:stackwallet/models/exchange/response_objects/currency.dart';
import 'package:stackwallet/models/exchange/response_objects/fixed_rate_market.dart';
import 'package:stackwallet/models/exchange/response_objects/pair.dart';
class CNAvailableCurrencies {
final List<Currency> currencies = [];
final List<Pair> pairs = [];
final List<FixedRateMarket> markets = [];
void updateCurrencies(List<Currency> newCurrencies) {
currencies.clear();
currencies.addAll(newCurrencies);
}
void updateFloatingPairs(List<Pair> newPairs) {
pairs.clear();
pairs.addAll(newPairs);
}
void updateMarkets(List<FixedRateMarket> newMarkets) {
markets.clear();
markets.addAll(newMarkets);
}
}

View file

@ -1,7 +1,6 @@
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';
@ -9,9 +8,6 @@ import 'package:stackwallet/pages/exchange_view/sub_widgets/exchange_rate_sheet.
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;

View file

@ -0,0 +1,30 @@
import 'package:stackwallet/models/exchange/response_objects/currency.dart';
import 'package:stackwallet/models/exchange/response_objects/pair.dart';
class SPAvailableCurrencies {
final List<Currency> floatingRateCurrencies = [];
final List<Currency> fixedRateCurrencies = [];
final List<Pair> floatingRatePairs = [];
final List<Pair> fixedRatePairs = [];
void updateFloatingCurrencies(List<Currency> newCurrencies) {
floatingRateCurrencies.clear();
floatingRateCurrencies.addAll(newCurrencies);
}
void updateFixedCurrencies(List<Currency> newCurrencies) {
fixedRateCurrencies.clear();
fixedRateCurrencies.addAll(newCurrencies);
}
void updateFloatingPairs(List<Pair> newPairs) {
floatingRatePairs.clear();
floatingRatePairs.addAll(newPairs);
}
void updateFixedPairs(List<Pair> newPairs) {
fixedRatePairs.clear();
fixedRatePairs.addAll(newPairs);
}
}

View file

@ -6,7 +6,6 @@ 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';
@ -19,11 +18,10 @@ import 'package:stackwallet/pages/exchange_view/exchange_step_views/step_2_view.
import 'package:stackwallet/pages/exchange_view/sub_widgets/exchange_provider_options.dart';
import 'package:stackwallet/pages/exchange_view/sub_widgets/exchange_rate_sheet.dart';
import 'package:stackwallet/pages/exchange_view/sub_widgets/rate_type_toggle.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/exchange_send_from_wallet_id_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_exchange.dart';
import 'package:stackwallet/services/exchange/simpleswap/simpleswap_exchange.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/enums/flush_bar_type.dart';
@ -88,9 +86,23 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
return;
}
List<Currency> currencies;
switch (ref.read(currentExchangeNameStateProvider.state).state) {
case ChangeNowExchange.exchangeName:
currencies =
ref.read(availableChangeNowCurrenciesProvider).currencies;
break;
case SimpleSwapExchange.exchangeName:
currencies = ref
.read(availableSimpleswapCurrenciesProvider)
.floatingRateCurrencies;
break;
default:
currencies = [];
}
await _showFloatingRateSelectionSheet(
currencies:
ref.read(availableChangeNowCurrenciesStateProvider.state).state,
currencies: currencies,
excludedTicker: ref.read(exchangeFormStateProvider).toTicker ?? "-",
fromTicker: fromTicker,
onSelected: (from) =>
@ -105,33 +117,51 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
return;
}
await _showFixedRateSelectionSheet(
excludedTicker: toTicker,
fromTicker: fromTicker,
onSelected: (selectedFromTicker) async {
try {
final market = ref
.read(fixedRateMarketPairsStateProvider.state)
.state
.firstWhere(
(e) => e.to == toTicker && e.from == selectedFromTicker,
);
switch (ref.read(currentExchangeNameStateProvider.state).state) {
case ChangeNowExchange.exchangeName:
await _showFixedRateSelectionSheet(
excludedTicker: toTicker,
fromTicker: fromTicker,
onSelected: (selectedFromTicker) async {
try {
final market = ref
.read(availableChangeNowCurrenciesProvider)
.markets
.firstWhere(
(e) => e.to == toTicker && e.from == selectedFromTicker,
);
await ref
.read(exchangeFormStateProvider)
.updateMarket(market, true);
} catch (e) {
unawaited(showDialog<dynamic>(
context: context,
builder: (_) => const StackDialog(
title: "Fixed rate market error",
message: "Could not find the specified fixed rate trade pair",
),
));
return;
}
},
);
await ref
.read(exchangeFormStateProvider)
.updateMarket(market, true);
} catch (e) {
unawaited(showDialog<dynamic>(
context: context,
builder: (_) => const StackDialog(
title: "Fixed rate market error",
message:
"Could not find the specified fixed rate trade pair",
),
));
return;
}
},
);
break;
case SimpleSwapExchange.exchangeName:
await _showFloatingRateSelectionSheet(
currencies: ref
.read(availableSimpleswapCurrenciesProvider)
.fixedRateCurrencies,
excludedTicker:
ref.read(exchangeFormStateProvider).toTicker ?? "-",
fromTicker: fromTicker,
onSelected: (from) =>
ref.read(exchangeFormStateProvider).updateFrom(from, true));
break;
default:
// TODO show error?
}
}
}
@ -146,9 +176,23 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
return;
}
List<Currency> currencies;
switch (ref.read(currentExchangeNameStateProvider.state).state) {
case ChangeNowExchange.exchangeName:
currencies =
ref.read(availableChangeNowCurrenciesProvider).currencies;
break;
case SimpleSwapExchange.exchangeName:
currencies = ref
.read(availableSimpleswapCurrenciesProvider)
.floatingRateCurrencies;
break;
default:
currencies = [];
}
await _showFloatingRateSelectionSheet(
currencies:
ref.read(availableChangeNowCurrenciesStateProvider.state).state,
currencies: currencies,
excludedTicker: ref.read(exchangeFormStateProvider).fromTicker ?? "",
fromTicker: ref.read(exchangeFormStateProvider).fromTicker ?? "",
onSelected: (to) =>
@ -163,33 +207,51 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
return;
}
await _showFixedRateSelectionSheet(
excludedTicker: fromTicker,
fromTicker: fromTicker,
onSelected: (selectedToTicker) async {
try {
final market = ref
.read(fixedRateMarketPairsStateProvider.state)
.state
.firstWhere(
(e) => e.to == selectedToTicker && e.from == fromTicker,
);
switch (ref.read(currentExchangeNameStateProvider.state).state) {
case ChangeNowExchange.exchangeName:
await _showFixedRateSelectionSheet(
excludedTicker: fromTicker,
fromTicker: fromTicker,
onSelected: (selectedToTicker) async {
try {
final market = ref
.read(availableChangeNowCurrenciesProvider)
.markets
.firstWhere(
(e) => e.to == selectedToTicker && e.from == fromTicker,
);
await ref
.read(exchangeFormStateProvider)
.updateMarket(market, true);
} catch (e) {
unawaited(showDialog<dynamic>(
context: context,
builder: (_) => const StackDialog(
title: "Fixed rate market error",
message: "Could not find the specified fixed rate trade pair",
),
));
return;
}
},
);
await ref
.read(exchangeFormStateProvider)
.updateMarket(market, true);
} catch (e) {
unawaited(showDialog<dynamic>(
context: context,
builder: (_) => const StackDialog(
title: "Fixed rate market error",
message:
"Could not find the specified fixed rate trade pair",
),
));
return;
}
},
);
break;
case SimpleSwapExchange.exchangeName:
await _showFloatingRateSelectionSheet(
currencies: ref
.read(availableSimpleswapCurrenciesProvider)
.fixedRateCurrencies,
excludedTicker:
ref.read(exchangeFormStateProvider).fromTicker ?? "",
fromTicker: ref.read(exchangeFormStateProvider).fromTicker ?? "",
onSelected: (to) =>
ref.read(exchangeFormStateProvider).updateTo(to, true));
break;
default:
// TODO show error?
}
}
}
@ -237,18 +299,29 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
ExchangeRateType.estimated) {
await ref.read(exchangeFormStateProvider).swap();
} else {
final from = ref.read(exchangeFormStateProvider).fromTicker;
final to = ref.read(exchangeFormStateProvider).toTicker;
switch (ref.read(currentExchangeNameStateProvider.state).state) {
case ChangeNowExchange.exchangeName:
final from = ref.read(exchangeFormStateProvider).fromTicker;
final to = ref.read(exchangeFormStateProvider).toTicker;
if (to != null && from != null) {
final markets = ref
.read(fixedRateMarketPairsStateProvider.state)
.state
.where((e) => e.from == to && e.to == from);
if (to != null && from != null) {
final markets = ref
.read(availableChangeNowCurrenciesProvider)
.markets
.where((e) => e.from == to && e.to == from);
if (markets.isNotEmpty) {
await ref.read(exchangeFormStateProvider).swap(market: markets.first);
}
if (markets.isNotEmpty) {
await ref
.read(exchangeFormStateProvider)
.swap(market: markets.first);
}
}
break;
case SimpleSwapExchange.exchangeName:
await ref.read(exchangeFormStateProvider).swap();
break;
default:
//
}
}
if (mounted) {
@ -266,25 +339,35 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
_sendFocusNode.unfocus();
_receiveFocusNode.unfocus();
List<Pair> availablePairs = [];
List<Pair> allPairs;
switch (ref.read(currentExchangeNameStateProvider.state).state) {
case ChangeNowExchange.exchangeName:
allPairs = ref.read(availableChangeNowCurrenciesProvider).pairs;
break;
case SimpleSwapExchange.exchangeName:
allPairs = ref.read(exchangeFormStateProvider).exchangeType ==
ExchangeRateType.fixed
? ref.read(availableSimpleswapCurrenciesProvider).fixedRatePairs
: ref.read(availableSimpleswapCurrenciesProvider).floatingRatePairs;
break;
default:
allPairs = [];
}
List<Pair> availablePairs;
if (fromTicker.isEmpty ||
fromTicker == "-" ||
excludedTicker.isEmpty ||
excludedTicker == "-") {
availablePairs =
ref.read(availableFloatingRatePairsStateProvider.state).state;
availablePairs = allPairs;
} else if (excludedTicker == fromTicker) {
availablePairs = ref
.read(availableFloatingRatePairsStateProvider.state)
.state
availablePairs = allPairs
.where((e) => e.from == excludedTicker)
.toList(growable: false);
} else {
availablePairs = ref
.read(availableFloatingRatePairsStateProvider.state)
.state
.where((e) => e.to == excludedTicker)
.toList(growable: false);
availablePairs =
allPairs.where((e) => e.to == excludedTicker).toList(growable: false);
}
final List<Currency> tickers = currencies.where((e) {
@ -313,10 +396,30 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
String? _fetchIconUrlFromTicker(String? ticker) {
if (ticker == null) return null;
final possibleCurrencies = ref
.read(availableChangeNowCurrenciesStateProvider.state)
.state
.where((e) => e.ticker.toUpperCase() == ticker.toUpperCase());
Iterable<Currency> possibleCurrencies;
switch (ref.read(currentExchangeNameStateProvider.state).state) {
case ChangeNowExchange.exchangeName:
possibleCurrencies = ref
.read(availableChangeNowCurrenciesProvider)
.currencies
.where((e) => e.ticker.toUpperCase() == ticker.toUpperCase());
break;
case SimpleSwapExchange.exchangeName:
possibleCurrencies = [
...ref
.read(availableSimpleswapCurrenciesProvider)
.fixedRateCurrencies
.where((e) => e.ticker.toUpperCase() == ticker.toUpperCase()),
...ref
.read(availableSimpleswapCurrenciesProvider)
.floatingRateCurrencies
.where((e) => e.ticker.toUpperCase() == ticker.toUpperCase()),
];
break;
default:
possibleCurrencies = [];
}
for (final currency in possibleCurrencies) {
if (currency.image.isNotEmpty) {
@ -342,17 +445,17 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
fromTicker == "" ||
fromTicker == "-") {
marketsThatPairWithExcludedTicker =
ref.read(fixedRateMarketPairsStateProvider.state).state;
ref.read(availableChangeNowCurrenciesProvider).markets;
} else if (excludedTicker == fromTicker) {
marketsThatPairWithExcludedTicker = ref
.read(fixedRateMarketPairsStateProvider.state)
.state
.read(availableChangeNowCurrenciesProvider)
.markets
.where((e) => e.from == excludedTicker && e.to != excludedTicker)
.toList(growable: false);
} else {
marketsThatPairWithExcludedTicker = ref
.read(fixedRateMarketPairsStateProvider.state)
.state
.read(availableChangeNowCurrenciesProvider)
.markets
.where((e) => e.to == excludedTicker && e.from != excludedTicker)
.toList(growable: false);
}
@ -361,8 +464,7 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
MaterialPageRoute<dynamic>(
builder: (_) => FixedRateMarketPairCoinSelectionView(
markets: marketsThatPairWithExcludedTicker,
currencies:
ref.read(availableChangeNowCurrenciesStateProvider.state).state,
currencies: ref.read(availableChangeNowCurrenciesProvider).currencies,
isFrom: excludedTicker != fromTicker,
),
),
@ -405,15 +507,46 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
switch (rateType) {
case ExchangeRateType.estimated:
if (!(toTicker == "-" || fromTicker == "-")) {
final available = ref
.read(availableFloatingRatePairsStateProvider.state)
.state
.where((e) => e.to == toTicker && e.from == fromTicker);
late final Iterable<Pair> available;
switch (ref.read(currentExchangeNameStateProvider.state).state) {
case ChangeNowExchange.exchangeName:
available = ref
.read(availableChangeNowCurrenciesProvider)
.pairs
.where((e) => e.to == toTicker && e.from == fromTicker);
break;
case SimpleSwapExchange.exchangeName:
available = ref
.read(availableSimpleswapCurrenciesProvider)
.floatingRatePairs
.where((e) => e.to == toTicker && e.from == fromTicker);
break;
default:
available = [];
}
if (available.isNotEmpty) {
final availableCurrencies = ref
.read(availableChangeNowCurrenciesStateProvider.state)
.state
.where((e) => e.ticker == fromTicker || e.ticker == toTicker);
late final Iterable<Currency> availableCurrencies;
switch (ref.read(currentExchangeNameStateProvider.state).state) {
case ChangeNowExchange.exchangeName:
availableCurrencies = ref
.read(availableChangeNowCurrenciesProvider)
.currencies
.where(
(e) => e.ticker == fromTicker || e.ticker == toTicker);
break;
case SimpleSwapExchange.exchangeName:
availableCurrencies = ref
.read(availableSimpleswapCurrenciesProvider)
.floatingRateCurrencies
.where(
(e) => e.ticker == fromTicker || e.ticker == toTicker);
break;
default:
availableCurrencies = [];
}
if (availableCurrencies.length > 1) {
final from =
availableCurrencies.firstWhere((e) => e.ticker == fromTicker);
@ -444,209 +577,245 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
if (mounted) {
Navigator.of(context).pop();
}
unawaited(showFloatingFlushBar(
type: FlushBarType.warning,
message:
"Estimated rate trade pair \"$fromTicker-$toTicker\" unavailable. Reverting to last estimated rate pair.",
context: context,
));
unawaited(
showFloatingFlushBar(
type: FlushBarType.warning,
message:
"Estimated rate trade pair \"$fromTicker-$toTicker\" unavailable. Reverting to last estimated rate pair.",
context: context,
),
);
break;
case ExchangeRateType.fixed:
if (!(toTicker == "-" || fromTicker == "-")) {
FixedRateMarket? market;
try {
market = ref
.read(fixedRateMarketPairsStateProvider.state)
.state
.firstWhere((e) => e.from == fromTicker && e.to == toTicker);
} catch (_) {
market = null;
}
switch (ref.read(currentExchangeNameStateProvider.state).state) {
case ChangeNowExchange.exchangeName:
FixedRateMarket? market;
try {
market = ref
.read(availableChangeNowCurrenciesProvider)
.markets
.firstWhere(
(e) => e.from == fromTicker && e.to == toTicker);
} catch (_) {
market = null;
}
final newFromAmount = Decimal.tryParse(_sendController.text);
ref.read(exchangeFormStateProvider).fromAmount =
newFromAmount ?? Decimal.zero;
final newFromAmount = Decimal.tryParse(_sendController.text);
ref.read(exchangeFormStateProvider).fromAmount =
newFromAmount ?? Decimal.zero;
if (newFromAmount == null) {
_receiveController.text = "";
}
if (newFromAmount == null) {
_receiveController.text = "";
}
await ref.read(exchangeFormStateProvider).updateMarket(market, false);
await ref
.read(exchangeFormStateProvider)
.setFromAmountAndCalculateToAmount(
Decimal.tryParse(_sendController.text) ?? Decimal.zero,
true,
);
if (mounted) {
Navigator.of(context).pop();
await ref
.read(exchangeFormStateProvider)
.updateMarket(market, false);
await ref
.read(exchangeFormStateProvider)
.setFromAmountAndCalculateToAmount(
Decimal.tryParse(_sendController.text) ?? Decimal.zero,
true,
);
if (mounted) {
Navigator.of(context).pop();
}
return;
case SimpleSwapExchange.exchangeName:
final available = ref
.read(availableSimpleswapCurrenciesProvider)
.floatingRatePairs
.where((e) => e.to == toTicker && e.from == fromTicker);
if (available.isNotEmpty) {
final availableCurrencies = ref
.read(availableSimpleswapCurrenciesProvider)
.fixedRateCurrencies
.where(
(e) => e.ticker == fromTicker || e.ticker == toTicker);
if (availableCurrencies.length > 1) {
final from = availableCurrencies
.firstWhere((e) => e.ticker == fromTicker);
final to = availableCurrencies
.firstWhere((e) => e.ticker == toTicker);
final newFromAmount = Decimal.tryParse(_sendController.text);
ref.read(exchangeFormStateProvider).fromAmount =
newFromAmount ?? Decimal.zero;
if (newFromAmount == null) {
_receiveController.text = "";
}
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;
}
}
break;
default:
//
}
return;
}
if (mounted) {
Navigator.of(context).pop();
}
unawaited(showFloatingFlushBar(
type: FlushBarType.warning,
message:
"Fixed rate trade pair \"$fromTicker-$toTicker\" unavailable. Reverting to last fixed rate pair.",
context: context,
));
unawaited(
showFloatingFlushBar(
type: FlushBarType.warning,
message:
"Fixed rate trade pair \"$fromTicker-$toTicker\" unavailable. Reverting to last fixed rate pair.",
context: context,
),
);
break;
}
}
void onExchangePressed() async {
if (ref.read(prefsChangeNotifierProvider).exchangeRateType ==
ExchangeRateType.estimated) {
final fromTicker = ref.read(exchangeFormStateProvider).fromTicker ?? "";
final toTicker = ref.read(exchangeFormStateProvider).toTicker ?? "";
final rateType = ref.read(prefsChangeNotifierProvider).exchangeRateType;
final fromTicker = ref.read(exchangeFormStateProvider).fromTicker ?? "";
final toTicker = ref.read(exchangeFormStateProvider).toTicker ?? "";
final sendAmount = ref.read(exchangeFormStateProvider).fromAmount!;
final estimate = ref.read(exchangeFormStateProvider).estimate!;
bool isAvailable = false;
final availableFloatingPairs =
ref.read(availableFloatingRatePairsStateProvider.state).state;
for (final pair in availableFloatingPairs) {
if (pair.from == fromTicker && pair.to == toTicker) {
isAvailable = true;
break;
String rate;
switch (rateType) {
case ExchangeRateType.estimated:
bool isAvailable = false;
late final Iterable<Pair> availableFloatingPairs;
switch (ref.read(currentExchangeNameStateProvider.state).state) {
case ChangeNowExchange.exchangeName:
availableFloatingPairs = ref
.read(availableChangeNowCurrenciesProvider)
.pairs
.where((e) => e.to == toTicker && e.from == fromTicker);
break;
case SimpleSwapExchange.exchangeName:
availableFloatingPairs = ref
.read(availableSimpleswapCurrenciesProvider)
.floatingRatePairs
.where((e) => e.to == toTicker && e.from == fromTicker);
break;
default:
availableFloatingPairs = [];
}
}
if (!isAvailable) {
unawaited(showDialog<dynamic>(
context: context,
barrierDismissible: true,
builder: (_) => StackDialog(
title: "Selected trade pair unavailable",
message:
"The $fromTicker - $toTicker market is currently disabled for estimated/floating rate trades",
),
));
return;
}
for (final pair in availableFloatingPairs) {
if (pair.from == fromTicker && pair.to == toTicker) {
isAvailable = true;
break;
}
}
final sendAmount = ref.read(exchangeFormStateProvider).fromAmount!;
if (!isAvailable) {
unawaited(showDialog<dynamic>(
context: context,
barrierDismissible: true,
builder: (_) => StackDialog(
title: "Selected trade pair unavailable",
message:
"The $fromTicker - $toTicker market is currently disabled for estimated/floating rate trades",
),
));
return;
}
rate =
"1 ${fromTicker.toUpperCase()} ~${(estimate.estimatedAmount / sendAmount).toDecimal(scaleOnInfinitePrecision: 8).toStringAsFixed(8)} ${toTicker.toUpperCase()}";
break;
case ExchangeRateType.fixed:
bool? shouldCancel;
final rateType = ref.read(prefsChangeNotifierProvider).exchangeRateType;
if (estimate.warningMessage != null &&
estimate.warningMessage!.isNotEmpty) {
shouldCancel = await showDialog<bool?>(
context: context,
barrierDismissible: true,
builder: (_) => StackDialog(
title: "Failed to update trade estimate",
message:
"${estimate.warningMessage!}\n\nDo you want to attempt trade anyways?",
leftButton: TextButton(
style: Theme.of(context)
.extension<StackColors>()!
.getSecondaryEnabledButtonColor(context),
child: Text(
"Cancel",
style: STextStyles.itemSubtitle12(context),
),
onPressed: () {
// notify return to cancel
Navigator.of(context).pop(true);
},
),
rightButton: TextButton(
style: Theme.of(context)
.extension<StackColors>()!
.getPrimaryEnabledButtonColor(context),
child: Text(
"Attempt",
style: STextStyles.button(context),
),
onPressed: () {
// continue and try to attempt trade
Navigator.of(context).pop(false);
},
),
),
);
}
final estimate = ref.read(exchangeFormStateProvider).estimate!;
if (shouldCancel is bool && shouldCancel) {
return;
}
rate =
"1 ${fromTicker.toUpperCase()} ~${ref.read(exchangeFormStateProvider).rate!.toStringAsFixed(8)} ${toTicker.toUpperCase()}";
break;
}
String rate =
"1 ${fromTicker.toUpperCase()} ~${(estimate.estimatedAmount / sendAmount).toDecimal(scaleOnInfinitePrecision: 8).toStringAsFixed(8)} ${toTicker.toUpperCase()}";
final model = IncompleteExchangeModel(
sendTicker: fromTicker.toUpperCase(),
receiveTicker: toTicker.toUpperCase(),
rateInfo: rate,
sendAmount: estimate.reversed ? estimate.estimatedAmount : sendAmount,
receiveAmount: estimate.reversed
? ref.read(exchangeFormStateProvider).toAmount!
: estimate.estimatedAmount,
rateType: rateType,
rateId: estimate.rateId,
reversed: estimate.reversed,
);
final model = IncompleteExchangeModel(
sendTicker: fromTicker.toUpperCase(),
receiveTicker: toTicker.toUpperCase(),
rateInfo: rate,
sendAmount: sendAmount,
receiveAmount: estimate.estimatedAmount,
rateType: rateType,
rateId: estimate.rateId,
reversed: estimate.reversed,
);
if (mounted) {
if (walletInitiated) {
ref.read(exchangeSendFromWalletIdStateProvider.state).state =
Tuple2(walletId!, coin!);
unawaited(Navigator.of(context).pushNamed(
if (mounted) {
if (walletInitiated) {
ref.read(exchangeSendFromWalletIdStateProvider.state).state =
Tuple2(walletId!, coin!);
unawaited(
Navigator.of(context).pushNamed(
Step2View.routeName,
arguments: model,
));
} else {
ref.read(exchangeSendFromWalletIdStateProvider.state).state = null;
unawaited(Navigator.of(context).pushNamed(
Step1View.routeName,
arguments: model,
));
}
}
} else {
final fromTicker = ref.read(exchangeFormStateProvider).fromTicker ?? "";
final toTicker = ref.read(exchangeFormStateProvider).toTicker ?? "";
final sendAmount = ref.read(exchangeFormStateProvider).fromAmount!;
final rateType = ref.read(prefsChangeNotifierProvider).exchangeRateType;
final estimate = ref.read(exchangeFormStateProvider).estimate!;
bool? shouldCancel;
if (estimate.warningMessage != null &&
estimate.warningMessage!.isNotEmpty) {
shouldCancel = await showDialog<bool?>(
context: context,
barrierDismissible: true,
builder: (_) => StackDialog(
title: "Failed to update trade estimate",
message:
"${estimate.warningMessage!}\n\nDo you want to attempt trade anyways?",
leftButton: TextButton(
style: Theme.of(context)
.extension<StackColors>()!
.getSecondaryEnabledButtonColor(context),
child: Text(
"Cancel",
style: STextStyles.itemSubtitle12(context),
),
onPressed: () {
// notify return to cancel
Navigator.of(context).pop(true);
},
),
rightButton: TextButton(
style: Theme.of(context)
.extension<StackColors>()!
.getPrimaryEnabledButtonColor(context),
child: Text(
"Attempt",
style: STextStyles.button(context),
),
onPressed: () {
// continue and try to attempt trade
Navigator.of(context).pop(false);
},
),
),
);
}
if (shouldCancel is bool && shouldCancel) {
return;
}
String rate =
"1 ${fromTicker.toUpperCase()} ~${ref.read(exchangeFormStateProvider).rate!.toStringAsFixed(8)} ${toTicker.toUpperCase()}";
final model = IncompleteExchangeModel(
sendTicker: fromTicker,
receiveTicker: toTicker,
rateInfo: rate,
sendAmount: estimate.reversed ? estimate.estimatedAmount : sendAmount,
receiveAmount: estimate.reversed
? ref.read(exchangeFormStateProvider).toAmount!
: estimate.estimatedAmount,
rateType: rateType,
rateId: estimate.rateId,
reversed: estimate.reversed,
);
if (mounted) {
if (walletInitiated) {
ref.read(exchangeSendFromWalletIdStateProvider.state).state =
Tuple2(walletId!, coin!);
unawaited(Navigator.of(context).pushNamed(
Step2View.routeName,
arguments: model,
));
} else {
ref.read(exchangeSendFromWalletIdStateProvider.state).state = null;
unawaited(Navigator.of(context).pushNamed(
} else {
ref.read(exchangeSendFromWalletIdStateProvider.state).state = null;
unawaited(
Navigator.of(context).pushNamed(
Step1View.routeName,
arguments: model,
));
}
),
);
}
}
}

View file

@ -7,7 +7,7 @@ import 'package:stackwallet/models/exchange/response_objects/trade.dart';
import 'package:stackwallet/pages/exchange_view/exchange_step_views/step_4_view.dart';
import 'package:stackwallet/pages/exchange_view/sub_widgets/exchange_rate_sheet.dart';
import 'package:stackwallet/pages/exchange_view/sub_widgets/step_row.dart';
import 'package:stackwallet/providers/exchange/change_now_provider.dart';
import 'package:stackwallet/providers/exchange/exchange_provider.dart';
import 'package:stackwallet/providers/global/trades_service_provider.dart';
import 'package:stackwallet/services/exchange/exchange_response.dart';
import 'package:stackwallet/services/notifications_api.dart';
@ -245,7 +245,7 @@ class _Step3ViewState extends ConsumerState<Step3View> {
final ExchangeResponse<Trade> response =
await ref
.read(changeNowProvider)
.read(exchangeProvider)
.createTrade(
from: model.sendTicker,
to: model.receiveTicker,

View file

@ -12,8 +12,6 @@ import 'package:stackwallet/pages/exchange_view/send_from_view.dart';
import 'package:stackwallet/pages/exchange_view/sub_widgets/step_row.dart';
import 'package:stackwallet/pages/home_view/home_view.dart';
import 'package:stackwallet/pages/send_view/sub_widgets/building_transaction_dialog.dart';
import 'package:stackwallet/providers/exchange/change_now_provider.dart';
import 'package:stackwallet/providers/exchange/exchange_send_from_wallet_id_provider.dart';
import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/route_generator.dart';
import 'package:stackwallet/utilities/assets.dart';
@ -68,7 +66,7 @@ class _Step4ViewState extends ConsumerState<Step4View> {
Future<void> _updateStatus() async {
final statusResponse =
await ref.read(changeNowProvider).updateTrade(model.trade!);
await ref.read(exchangeProvider).updateTrade(model.trade!);
String status = "Waiting";
if (statusResponse.value != null) {
status = statusResponse.value!.status;

View file

@ -2,32 +2,14 @@ import 'package:decimal/decimal.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/services/exchange/change_now/change_now_exchange.dart';
import 'package:stackwallet/services/exchange/exchange.dart';
import 'package:stackwallet/services/exchange/simpleswap/simpleswap_exchange.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/logger.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/widgets/rounded_white_container.dart';
final currentExchangeNameStateProvider =
StateProvider<String>((ref) => ChangeNowExchange.exchangeName);
final exchangeProvider = Provider<Exchange>((ref) {
switch (ref.watch(currentExchangeNameStateProvider.state).state) {
case ChangeNowExchange.exchangeName:
return ChangeNowExchange();
case SimpleSwapExchange.exchangeName:
return SimpleSwapExchange();
default:
const errorMessage =
"Attempted to access exchangeProvider with invalid exchange name!";
Logging.instance.log(errorMessage, level: LogLevel.Fatal);
throw Exception(errorMessage);
}
});
class ExchangeProviderOptions extends ConsumerWidget {
const ExchangeProviderOptions({
Key? key,

View file

@ -13,10 +13,9 @@ import 'package:stackwallet/pages/exchange_view/edit_trade_note_view.dart';
import 'package:stackwallet/pages/exchange_view/send_from_view.dart';
import 'package:stackwallet/pages/wallet_view/transaction_views/edit_note_view.dart';
import 'package:stackwallet/pages/wallet_view/transaction_views/transaction_details_view.dart';
import 'package:stackwallet/providers/exchange/change_now_provider.dart';
import 'package:stackwallet/providers/exchange/trade_note_service_provider.dart';
import 'package:stackwallet/providers/global/trades_service_provider.dart';
import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/services/exchange/exchange.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/clipboard_interface.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
@ -85,7 +84,8 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
.firstWhere((e) => e.tradeId == tradeId);
if (mounted) {
final response = await ref.read(changeNowProvider).updateTrade(trade);
final exchange = Exchange.fromName(trade.exchangeName);
final response = await exchange.updateTrade(trade);
if (mounted && response.value != null) {
await ref

View file

@ -13,7 +13,7 @@ import 'package:stackwallet/pages/wallets_view/wallets_view.dart';
import 'package:stackwallet/providers/global/notifications_provider.dart';
import 'package:stackwallet/providers/ui/home_view_index_provider.dart';
import 'package:stackwallet/providers/ui/unread_notifications_provider.dart';
import 'package:stackwallet/services/exchange/change_now/change_now_loading_service.dart';
import 'package:stackwallet/services/exchange/exchange_data_loading_service.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/text_styles.dart';
@ -41,7 +41,7 @@ class _HomeViewState extends ConsumerState<HomeView> {
bool _exitEnabled = false;
final _cnLoadingService = ChangeNowLoadingService();
final _cnLoadingService = ExchangeDataLoadingService();
Future<bool> _onWillPop() async {
// go to home view when tapping back on the main exchange view

View file

@ -1,8 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:stackwallet/models/exchange/exchange_form_state.dart';
import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/services/exchange/change_now/change_now_loading_service.dart';
import 'package:stackwallet/services/exchange/exchange_data_loading_service.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/widgets/stack_dialog.dart';
@ -119,7 +118,7 @@ class _HomeViewButtonBarState extends ConsumerState<HomeViewButtonBar> {
// // },
// ),
// );
await ChangeNowLoadingService().loadAll(ref);
await ExchangeDataLoadingService().loadAll(ref);
// if (!okPressed && mounted) {
// Navigator.of(context).pop();
// }

View file

@ -5,7 +5,6 @@ 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 +18,6 @@ import 'package:stackwallet/pages/wallet_view/sub_widgets/transactions_list.dart
import 'package:stackwallet/pages/wallet_view/sub_widgets/wallet_navigation_bar.dart';
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/global/auto_swb_service_provider.dart';
import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/providers/ui/transaction_filter_provider.dart';
@ -31,7 +29,8 @@ import 'package:stackwallet/services/coins/manager.dart';
import 'package:stackwallet/services/event_bus/events/global/node_connection_status_changed_event.dart';
import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_changed_event.dart';
import 'package:stackwallet/services/event_bus/global_event_bus.dart';
import 'package:stackwallet/services/exchange/change_now/change_now_loading_service.dart';
import 'package:stackwallet/services/exchange/change_now/change_now_exchange.dart';
import 'package:stackwallet/services/exchange/exchange_data_loading_service.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/enums/backup_frequency_type.dart';
@ -79,7 +78,7 @@ class _WalletViewState extends ConsumerState<WalletView> {
late StreamSubscription<dynamic> _syncStatusSubscription;
late StreamSubscription<dynamic> _nodeStatusSubscription;
final _cnLoadingService = ChangeNowLoadingService();
final _cnLoadingService = ExchangeDataLoadingService();
@override
void initState() {
@ -247,15 +246,19 @@ class _WalletViewState extends ConsumerState<WalletView> {
),
);
} else {
ref.read(currentExchangeNameStateProvider.state).state =
ChangeNowExchange.exchangeName;
final walletId = ref.read(managerProvider).walletId;
ref.read(prefsChangeNotifierProvider).exchangeRateType =
ExchangeRateType.estimated;
ref.read(exchangeFormStateProvider).exchange = ref.read(exchangeProvider);
ref.read(exchangeFormStateProvider).exchangeType =
ExchangeRateType.estimated;
final currencies = ref
.read(availableChangeNowCurrenciesStateProvider.state)
.state
.read(availableChangeNowCurrenciesProvider)
.currencies
.where((element) =>
element.ticker.toLowerCase() == coin.ticker.toLowerCase());
@ -263,8 +266,8 @@ class _WalletViewState extends ConsumerState<WalletView> {
ref.read(exchangeFormStateProvider).setCurrencies(
currencies.first,
ref
.read(availableChangeNowCurrenciesStateProvider.state)
.state
.read(availableChangeNowCurrenciesProvider)
.currencies
.firstWhere(
(element) =>
element.ticker.toLowerCase() !=

View file

@ -0,0 +1,6 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:stackwallet/models/exchange/change_now/cn_available_currencies.dart';
final availableChangeNowCurrenciesProvider = Provider<CNAvailableCurrencies>(
(ref) => CNAvailableCurrencies(),
);

View file

@ -1,5 +0,0 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:stackwallet/models/exchange/response_objects/currency.dart';
final availableChangeNowCurrenciesStateProvider =
StateProvider<List<Currency>>((ref) => <Currency>[]);

View file

@ -1,5 +0,0 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:stackwallet/models/exchange/response_objects/pair.dart';
final availableFloatingRatePairsStateProvider =
StateProvider<List<Pair>>((ref) => <Pair>[]);

View file

@ -0,0 +1,6 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:stackwallet/models/exchange/simpleswap/sp_available_currencies.dart';
final availableSimpleswapCurrenciesProvider = Provider<SPAvailableCurrencies>(
(ref) => SPAvailableCurrencies(),
);

View file

@ -1,5 +1,6 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:stackwallet/services/exchange/change_now/change_now_exchange.dart';
import 'package:stackwallet/services/exchange/exchange.dart';
final changeNowProvider = Provider<Exchange>((ref) => ChangeNowExchange());
final currentExchangeNameStateProvider = StateProvider<String>(
(ref) => ChangeNowExchange.exchangeName,
);

View file

@ -1,5 +0,0 @@
// import 'package:flutter_riverpod/flutter_riverpod.dart';
// import 'package:stackwallet/models/exchange/estimated_rate_exchange_form_state.dart';
//
// final estimatedRateExchangeFormProvider =
// ChangeNotifierProvider((ref) => EstimatedRateExchangeFormState());

View file

@ -0,0 +1,6 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:stackwallet/models/exchange/exchange_form_state.dart';
final exchangeFormStateProvider = ChangeNotifierProvider<ExchangeFormState>(
(ref) => ExchangeFormState(),
);

View file

@ -0,0 +1,9 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:stackwallet/providers/exchange/current_exchange_name_state_provider.dart';
import 'package:stackwallet/services/exchange/exchange.dart';
final exchangeProvider = Provider<Exchange>(
(ref) => Exchange.fromName(
ref.watch(currentExchangeNameStateProvider.state).state,
),
);

View file

@ -1,6 +0,0 @@
// import 'package:flutter_riverpod/flutter_riverpod.dart';
// import 'package:stackwallet/models/exchange/fixed_rate_exchange_form_state.dart';
//
// final fixedRateExchangeFormProvider =
// ChangeNotifierProvider<FixedRateExchangeFormState>(
// (ref) => FixedRateExchangeFormState());

View file

@ -1,5 +0,0 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:stackwallet/models/exchange/response_objects/fixed_rate_market.dart';
final fixedRateMarketPairsStateProvider =
StateProvider<List<FixedRateMarket>>((ref) => []);

View file

@ -1,3 +1,13 @@
export './exchange/available_changenow_currencies_provider.dart';
export './exchange/available_simpleswap_currencies_provider.dart';
export './exchange/changenow_initial_load_status.dart';
export './exchange/current_exchange_name_state_provider.dart';
export './exchange/exchange_flow_is_active_state_provider.dart';
export './exchange/exchange_form_state_provider.dart';
export './exchange/exchange_provider.dart';
export './exchange/exchange_send_from_wallet_id_provider.dart';
export './exchange/trade_note_service_provider.dart';
export './exchange/trade_sent_from_stack_lookup_provider.dart';
export './global/favorites_provider.dart';
export './global/locale_provider.dart';
export './global/node_service_provider.dart';

View file

@ -4,9 +4,22 @@ import 'package:stackwallet/models/exchange/response_objects/estimate.dart';
import 'package:stackwallet/models/exchange/response_objects/pair.dart';
import 'package:stackwallet/models/exchange/response_objects/range.dart';
import 'package:stackwallet/models/exchange/response_objects/trade.dart';
import 'package:stackwallet/services/exchange/change_now/change_now_exchange.dart';
import 'package:stackwallet/services/exchange/exchange_response.dart';
import 'package:stackwallet/services/exchange/simpleswap/simpleswap_exchange.dart';
abstract class Exchange {
static Exchange fromName(String name) {
switch (name) {
case ChangeNowExchange.exchangeName:
return ChangeNowExchange();
case SimpleSwapExchange.exchangeName:
return SimpleSwapExchange();
default:
throw ArgumentError("Unknown exchange name");
}
}
String get name;
Future<ExchangeResponse<List<Currency>>> getAllCurrencies(bool fixedRate);

View file

@ -1,19 +1,18 @@
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/fixed_rate_market_pairs_provider.dart';
import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/services/exchange/change_now/change_now_api.dart';
import 'package:stackwallet/services/exchange/simpleswap/simpleswap_exchange.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/logger.dart';
class ChangeNowLoadingService {
class ExchangeDataLoadingService {
Future<void> loadAll(WidgetRef ref, {Coin? coin}) async {
try {
await Future.wait([
_loadFixedRateMarkets(ref, coin: coin),
_loadChangeNowStandardCurrencies(ref, coin: coin),
loadSimpleswapFixedRateCurrencies(ref),
loadSimpleswapFloatingRateCurrencies(ref),
]);
} catch (e, s) {
Logging.instance.log("ChangeNowLoadingService.loadAll failed: $e\n$s",
@ -34,8 +33,9 @@ class ChangeNowLoadingService {
final response3 =
await ChangeNowAPI.instance.getAvailableFixedRateMarkets();
if (response3.value != null) {
ref.read(fixedRateMarketPairsStateProvider.state).state =
response3.value!;
ref
.read(availableChangeNowCurrenciesProvider)
.updateMarkets(response3.value!);
if (ref.read(exchangeFormStateProvider).market == null) {
String fromTicker = "btc";
@ -86,11 +86,14 @@ class ChangeNowLoadingService {
final response2 =
await ChangeNowAPI.instance.getAvailableFloatingRatePairs();
if (response.value != null) {
ref.read(availableChangeNowCurrenciesStateProvider.state).state =
response.value!;
ref
.read(availableChangeNowCurrenciesProvider)
.updateCurrencies(response.value!);
if (response2.value != null) {
ref.read(availableFloatingRatePairsStateProvider.state).state =
response2.value!;
ref
.read(availableChangeNowCurrenciesProvider)
.updateFloatingPairs(response2.value!);
String fromTicker = "btc";
String toTicker = "xmr";
@ -138,4 +141,62 @@ class ChangeNowLoadingService {
ref.read(changeNowEstimatedInitialLoadStatusStateProvider.state).state =
ChangeNowLoadStatus.success;
}
Future<void> loadSimpleswapFloatingRateCurrencies(WidgetRef ref) async {
final exchange = SimpleSwapExchange();
final responseCurrencies = await exchange.getAllCurrencies(false);
if (responseCurrencies.value != null) {
ref
.read(availableSimpleswapCurrenciesProvider)
.updateFloatingCurrencies(responseCurrencies.value!);
final responsePairs = await exchange.getAllPairs(false);
if (responsePairs.value != null) {
ref
.read(availableSimpleswapCurrenciesProvider)
.updateFloatingPairs(responsePairs.value!);
} else {
Logging.instance.log(
"loadSimpleswapFloatingRateCurrencies: $responsePairs",
level: LogLevel.Warning,
);
}
} else {
Logging.instance.log(
"loadSimpleswapFloatingRateCurrencies: $responseCurrencies",
level: LogLevel.Warning,
);
}
}
Future<void> loadSimpleswapFixedRateCurrencies(WidgetRef ref) async {
final exchange = SimpleSwapExchange();
final responseCurrencies = await exchange.getAllCurrencies(true);
if (responseCurrencies.value != null) {
ref
.read(availableSimpleswapCurrenciesProvider)
.updateFixedCurrencies(responseCurrencies.value!);
final responsePairs = await exchange.getAllPairs(true);
if (responsePairs.value != null) {
ref
.read(availableSimpleswapCurrenciesProvider)
.updateFixedPairs(responsePairs.value!);
} else {
Logging.instance.log(
"loadSimpleswapFixedRateCurrencies: $responsePairs",
level: LogLevel.Warning,
);
}
} else {
Logging.instance.log(
"loadSimpleswapFixedRateCurrencies: $responseCurrencies",
level: LogLevel.Warning,
);
}
}
}