generic rate estimate

This commit is contained in:
julian 2022-10-03 10:30:50 -06:00
parent c182557b30
commit 670c32aeaf
15 changed files with 335 additions and 201 deletions

View file

@ -1,7 +1,7 @@
import 'package:decimal/decimal.dart'; import 'package:decimal/decimal.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:stackwallet/models/exchange/change_now/cn_exchange_estimate.dart'; import 'package:stackwallet/models/exchange/change_now/cn_exchange_estimate.dart';
import 'package:stackwallet/models/exchange/change_now/fixed_rate_market.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/services/exchange/change_now/change_now_api.dart';
import 'package:stackwallet/utilities/logger.dart'; import 'package:stackwallet/utilities/logger.dart';

View file

@ -0,0 +1,46 @@
import 'package:decimal/decimal.dart';
import 'package:stackwallet/utilities/logger.dart';
class Estimate {
final Decimal estimatedAmount;
final bool fixedRate;
final bool reversed;
final String? warningMessage;
final String? rateId;
Estimate({
required this.estimatedAmount,
required this.fixedRate,
required this.reversed,
this.warningMessage,
this.rateId,
});
factory Estimate.fromMap(Map<String, dynamic> map) {
try {
return Estimate(
estimatedAmount: Decimal.parse(map["estimatedAmount"] as String),
fixedRate: map["fixedRate"] as bool,
reversed: map["reversed"] as bool,
warningMessage: map["warningMessage"] as String?,
rateId: map["rateId"] as String?,
);
} catch (e, s) {
Logging.instance.log("Estimate.fromMap(): $e\n$s", level: LogLevel.Error);
rethrow;
}
}
Map<String, dynamic> toMap() {
return {
"estimatedAmount": estimatedAmount.toString(),
"fixedRate": fixedRate,
"reversed": reversed,
"warningMessage": warningMessage,
"rateId": rateId,
};
}
@override
String toString() => "Estimate: ${toMap()}";
}

View file

@ -1,4 +1,5 @@
import 'package:decimal/decimal.dart'; import 'package:decimal/decimal.dart';
import 'package:stackwallet/utilities/logger.dart';
class FixedRateMarket { class FixedRateMarket {
/// Currency ticker /// Currency ticker
@ -20,7 +21,7 @@ class FixedRateMarket {
/// Network fee for transferring funds between wallets, it should /// Network fee for transferring funds between wallets, it should
/// be deducted from the result. /// be deducted from the result.
final Decimal minerFee; final Decimal? minerFee;
FixedRateMarket({ FixedRateMarket({
required this.from, required this.from,
@ -31,7 +32,7 @@ class FixedRateMarket {
required this.minerFee, required this.minerFee,
}); });
factory FixedRateMarket.fromJson(Map<String, dynamic> json) { factory FixedRateMarket.fromMap(Map<String, dynamic> json) {
try { try {
return FixedRateMarket( return FixedRateMarket(
from: json["from"] as String, from: json["from"] as String,
@ -39,15 +40,19 @@ class FixedRateMarket {
min: Decimal.parse(json["min"].toString()), min: Decimal.parse(json["min"].toString()),
max: Decimal.parse(json["max"].toString()), max: Decimal.parse(json["max"].toString()),
rate: Decimal.parse(json["rate"].toString()), rate: Decimal.parse(json["rate"].toString()),
minerFee: Decimal.parse(json["minerFee"].toString()), minerFee: Decimal.tryParse(json["minerFee"].toString()),
);
} catch (e, s) {
Logging.instance.log(
"FixedRateMarket.fromMap(): $e\n$s",
level: LogLevel.Error,
); );
} catch (e) {
rethrow; rethrow;
} }
} }
Map<String, dynamic> toJson() { Map<String, dynamic> toMap() {
final map = { return {
"from": from, "from": from,
"to": to, "to": to,
"min": min, "min": min,
@ -55,8 +60,6 @@ class FixedRateMarket {
"rate": rate, "rate": rate,
"minerFee": minerFee, "minerFee": minerFee,
}; };
return map;
} }
FixedRateMarket copyWith({ FixedRateMarket copyWith({
@ -78,7 +81,5 @@ class FixedRateMarket {
} }
@override @override
String toString() { String toString() => "FixedRateMarket: ${toMap()}";
return "FixedRateMarket: ${toJson()}";
}
} }

View file

@ -1,8 +1,8 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/models/exchange/change_now/fixed_rate_market.dart';
import 'package:stackwallet/models/exchange/response_objects/currency.dart'; import 'package:stackwallet/models/exchange/response_objects/currency.dart';
import 'package:stackwallet/models/exchange/response_objects/fixed_rate_market.dart';
import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart';

View file

@ -6,9 +6,9 @@ import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:flutter_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/models/exchange/change_now/fixed_rate_market.dart';
import 'package:stackwallet/models/exchange/incomplete_exchange.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/currency.dart';
import 'package:stackwallet/models/exchange/response_objects/fixed_rate_market.dart';
import 'package:stackwallet/models/exchange/response_objects/pair.dart'; import 'package:stackwallet/models/exchange/response_objects/pair.dart';
import 'package:stackwallet/notifications/show_flush_bar.dart'; import 'package:stackwallet/notifications/show_flush_bar.dart';
import 'package:stackwallet/pages/exchange_view/exchange_coin_selection/fixed_rate_pair_coin_selection_view.dart'; import 'package:stackwallet/pages/exchange_view/exchange_coin_selection/fixed_rate_pair_coin_selection_view.dart';
@ -1276,15 +1276,17 @@ class _ExchangeViewState extends ConsumerState<ExchangeView> {
} }
String rate = String rate =
"1 ${fromTicker.toUpperCase()} ~${(response.value! / sendAmount).toDecimal(scaleOnInfinitePrecision: 8).toStringAsFixed(8)} ${toTicker.toUpperCase()}"; "1 ${fromTicker.toUpperCase()} ~${(response.value!.estimatedAmount / sendAmount).toDecimal(scaleOnInfinitePrecision: 8).toStringAsFixed(8)} ${toTicker.toUpperCase()}";
final model = IncompleteExchangeModel( final model = IncompleteExchangeModel(
sendTicker: fromTicker.toUpperCase(), sendTicker: fromTicker.toUpperCase(),
receiveTicker: toTicker.toUpperCase(), receiveTicker: toTicker.toUpperCase(),
rateInfo: rate, rateInfo: rate,
sendAmount: sendAmount, sendAmount: sendAmount,
receiveAmount: response.value!, receiveAmount:
response.value!.estimatedAmount,
rateType: rateType, rateType: rateType,
rateId: response.value!.rateId,
); );
if (mounted) { if (mounted) {
@ -1341,51 +1343,50 @@ class _ExchangeViewState extends ConsumerState<ExchangeView> {
), ),
)); ));
return; return;
} else if (response.value!.warningMessage !=
null &&
response
.value!.warningMessage!.isNotEmpty) {
shouldCancel = await showDialog<bool?>(
context: context,
barrierDismissible: true,
builder: (_) => StackDialog(
title:
"Failed to update trade estimate",
message:
"${response.value!.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);
},
),
),
);
} }
// else if (response.value!.warningMessage !=
// null &&
// response
// .value!.warningMessage!.isNotEmpty) {
// shouldCancel = await showDialog<bool?>(
// context: context,
// barrierDismissible: true,
// builder: (_) => StackDialog(
// title:
// "Failed to update trade estimate",
// message:
// "${response.value!.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) { if (shouldCancel is bool && shouldCancel) {
return; return;
@ -1399,8 +1400,10 @@ class _ExchangeViewState extends ConsumerState<ExchangeView> {
receiveTicker: toTicker, receiveTicker: toTicker,
rateInfo: rate, rateInfo: rate,
sendAmount: sendAmount, sendAmount: sendAmount,
receiveAmount: response.value!, receiveAmount:
response.value!.estimatedAmount,
rateType: rateType, rateType: rateType,
rateId: response.value!.rateId,
); );
if (mounted) { if (mounted) {

View file

@ -5,9 +5,9 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/models/exchange/change_now/fixed_rate_market.dart';
import 'package:stackwallet/models/exchange/incomplete_exchange.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/currency.dart';
import 'package:stackwallet/models/exchange/response_objects/fixed_rate_market.dart';
import 'package:stackwallet/models/exchange/response_objects/pair.dart'; import 'package:stackwallet/models/exchange/response_objects/pair.dart';
import 'package:stackwallet/notifications/show_flush_bar.dart'; import 'package:stackwallet/notifications/show_flush_bar.dart';
import 'package:stackwallet/pages/exchange_view/exchange_coin_selection/fixed_rate_pair_coin_selection_view.dart'; import 'package:stackwallet/pages/exchange_view/exchange_coin_selection/fixed_rate_pair_coin_selection_view.dart';
@ -1431,15 +1431,17 @@ class _WalletInitiatedExchangeViewState
} }
String rate = String rate =
"1 ${fromTicker.toUpperCase()} ~${(response.value! / sendAmount).toDecimal(scaleOnInfinitePrecision: 8).toStringAsFixed(8)} ${toTicker.toUpperCase()}"; "1 ${fromTicker.toUpperCase()} ~${(response.value!.estimatedAmount / sendAmount).toDecimal(scaleOnInfinitePrecision: 8).toStringAsFixed(8)} ${toTicker.toUpperCase()}";
final model = IncompleteExchangeModel( final model = IncompleteExchangeModel(
sendTicker: fromTicker.toUpperCase(), sendTicker: fromTicker.toUpperCase(),
receiveTicker: toTicker.toUpperCase(), receiveTicker: toTicker.toUpperCase(),
rateInfo: rate, rateInfo: rate,
sendAmount: sendAmount, sendAmount: sendAmount,
receiveAmount: response.value!, receiveAmount:
response.value!.estimatedAmount,
rateType: rateType, rateType: rateType,
rateId: response.value!.rateId,
); );
if (mounted) { if (mounted) {
@ -1497,52 +1499,51 @@ class _WalletInitiatedExchangeViewState
), ),
)); ));
return; return;
} else if (response.value!.warningMessage !=
null &&
response.value!.warningMessage!
.isNotEmpty) {
shouldCancel = await showDialog<bool?>(
context: context,
barrierDismissible: true,
builder: (_) => StackDialog(
title:
"Failed to update trade estimate",
message:
"${response.value!.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);
},
),
),
);
} }
// else if (response.value!.warningMessage !=
// null &&
// response.value!.warningMessage!
// .isNotEmpty) {
// shouldCancel = await showDialog<bool?>(
// context: context,
// barrierDismissible: true,
// builder: (_) => StackDialog(
// title:
// "Failed to update trade estimate",
// message:
// "${response.value!.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) { if (shouldCancel is bool && shouldCancel) {
return; return;
@ -1556,8 +1557,10 @@ class _WalletInitiatedExchangeViewState
receiveTicker: toTicker, receiveTicker: toTicker,
rateInfo: rate, rateInfo: rate,
sendAmount: sendAmount, sendAmount: sendAmount,
receiveAmount: response.value!, receiveAmount:
response.value!.estimatedAmount,
rateType: rateType, rateType: rateType,
rateId: response.value!.rateId,
); );
if (mounted) { if (mounted) {

View file

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

View file

@ -8,8 +8,9 @@ import 'package:stackwallet/models/exchange/change_now/cn_exchange_estimate.dart
import 'package:stackwallet/models/exchange/change_now/estimated_exchange_amount.dart'; import 'package:stackwallet/models/exchange/change_now/estimated_exchange_amount.dart';
import 'package:stackwallet/models/exchange/change_now/exchange_transaction.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/change_now/exchange_transaction_status.dart';
import 'package:stackwallet/models/exchange/change_now/fixed_rate_market.dart';
import 'package:stackwallet/models/exchange/response_objects/currency.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/models/exchange/response_objects/pair.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/range.dart';
import 'package:stackwallet/services/exchange/exchange_response.dart'; import 'package:stackwallet/services/exchange/exchange_response.dart';
@ -309,7 +310,7 @@ class ChangeNowAPI {
/// Get estimated amount of [toTicker] cryptocurrency to receive /// Get estimated amount of [toTicker] cryptocurrency to receive
/// for [fromAmount] of [fromTicker] /// for [fromAmount] of [fromTicker]
Future<ExchangeResponse<EstimatedExchangeAmount>> getEstimatedExchangeAmount({ Future<ExchangeResponse<Estimate>> getEstimatedExchangeAmount({
required String fromTicker, required String fromTicker,
required String toTicker, required String toTicker,
required Decimal fromAmount, required Decimal fromAmount,
@ -329,7 +330,15 @@ class ChangeNowAPI {
try { try {
final value = EstimatedExchangeAmount.fromJson( final value = EstimatedExchangeAmount.fromJson(
Map<String, dynamic>.from(json as Map)); Map<String, dynamic>.from(json as Map));
return ExchangeResponse(value: value); return ExchangeResponse(
value: Estimate(
estimatedAmount: value.estimatedAmount,
fixedRate: false,
reversed: false,
rateId: value.rateId,
warningMessage: value.warningMessage,
),
);
} catch (_) { } catch (_) {
return ExchangeResponse( return ExchangeResponse(
exception: ExchangeException( exception: ExchangeException(
@ -352,8 +361,7 @@ class ChangeNowAPI {
/// Get estimated amount of [toTicker] cryptocurrency to receive /// Get estimated amount of [toTicker] cryptocurrency to receive
/// for [fromAmount] of [fromTicker] /// for [fromAmount] of [fromTicker]
Future<ExchangeResponse<EstimatedExchangeAmount>> Future<ExchangeResponse<Estimate>> getEstimatedExchangeAmountFixedRate({
getEstimatedExchangeAmountFixedRate({
required String fromTicker, required String fromTicker,
required String toTicker, required String toTicker,
required Decimal fromAmount, required Decimal fromAmount,
@ -382,7 +390,15 @@ class ChangeNowAPI {
try { try {
final value = EstimatedExchangeAmount.fromJson( final value = EstimatedExchangeAmount.fromJson(
Map<String, dynamic>.from(json as Map)); Map<String, dynamic>.from(json as Map));
return ExchangeResponse(value: value); return ExchangeResponse(
value: Estimate(
estimatedAmount: value.estimatedAmount,
fixedRate: true,
reversed: reversed,
rateId: value.rateId,
warningMessage: value.warningMessage,
),
);
} catch (_) { } catch (_) {
return ExchangeResponse( return ExchangeResponse(
exception: ExchangeException( exception: ExchangeException(
@ -574,7 +590,7 @@ class ChangeNowAPI {
for (final json in jsonArray) { for (final json in jsonArray) {
try { try {
markets.add( markets.add(
FixedRateMarket.fromJson(Map<String, dynamic>.from(json as Map))); FixedRateMarket.fromMap(Map<String, dynamic>.from(json as Map)));
} catch (_) { } catch (_) {
return ExchangeResponse( return ExchangeResponse(
exception: ExchangeException("Failed to serialize $json", exception: ExchangeException("Failed to serialize $json",

View file

@ -1,7 +1,7 @@
import 'package:decimal/decimal.dart'; import 'package:decimal/decimal.dart';
import 'package:stackwallet/models/exchange/change_now/estimated_exchange_amount.dart';
import 'package:stackwallet/models/exchange/change_now/exchange_transaction.dart'; import 'package:stackwallet/models/exchange/change_now/exchange_transaction.dart';
import 'package:stackwallet/models/exchange/response_objects/currency.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/pair.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/range.dart';
import 'package:stackwallet/models/exchange/response_objects/trade.dart'; import 'package:stackwallet/models/exchange/response_objects/trade.dart';
@ -87,14 +87,14 @@ class ChangeNowExchange extends Exchange {
} }
@override @override
Future<ExchangeResponse<Decimal>> getEstimate( Future<ExchangeResponse<Estimate>> getEstimate(
String from, String from,
String to, String to,
Decimal amount, Decimal amount,
bool fixedRate, bool fixedRate,
bool reversed, bool reversed,
) async { ) async {
late final ExchangeResponse<EstimatedExchangeAmount> response; late final ExchangeResponse<Estimate> response;
if (fixedRate) { if (fixedRate) {
response = response =
await ChangeNowAPI.instance.getEstimatedExchangeAmountFixedRate( await ChangeNowAPI.instance.getEstimatedExchangeAmountFixedRate(
@ -110,10 +110,7 @@ class ChangeNowExchange extends Exchange {
fromAmount: amount, fromAmount: amount,
); );
} }
if (response.exception != null) { return response;
return ExchangeResponse(exception: response.exception);
}
return ExchangeResponse(value: response.value?.estimatedAmount);
} }
@override @override

View file

@ -1,5 +1,6 @@
import 'package:decimal/decimal.dart'; import 'package:decimal/decimal.dart';
import 'package:stackwallet/models/exchange/response_objects/currency.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/pair.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/range.dart';
import 'package:stackwallet/models/exchange/response_objects/trade.dart'; import 'package:stackwallet/models/exchange/response_objects/trade.dart';
@ -28,7 +29,7 @@ abstract class Exchange {
bool fixedRate, bool fixedRate,
); );
Future<ExchangeResponse<Decimal>> getEstimate( Future<ExchangeResponse<Estimate>> getEstimate(
String from, String from,
String to, String to,
Decimal amount, Decimal amount,

View file

@ -4,6 +4,7 @@ import 'package:decimal/decimal.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
import 'package:stackwallet/external_api_keys.dart'; import 'package:stackwallet/external_api_keys.dart';
import 'package:stackwallet/models/exchange/response_objects/fixed_rate_market.dart';
import 'package:stackwallet/models/exchange/response_objects/pair.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/range.dart';
import 'package:stackwallet/models/exchange/response_objects/trade.dart'; import 'package:stackwallet/models/exchange/response_objects/trade.dart';
@ -37,7 +38,6 @@ class SimpleSwapAPI {
); );
final parsed = jsonDecode(response.body); final parsed = jsonDecode(response.body);
print("PARSED: $parsed");
return parsed; return parsed;
} catch (e, s) { } catch (e, s) {
@ -99,9 +99,6 @@ class SimpleSwapAPI {
try { try {
final jsonObject = await _makePostRequest(uri, body); final jsonObject = await _makePostRequest(uri, body);
print("================================");
print(jsonObject);
print("================================");
final json = Map<String, dynamic>.from(jsonObject as Map); final json = Map<String, dynamic>.from(jsonObject as Map);
final trade = Trade( final trade = Trade(
@ -427,4 +424,76 @@ class SimpleSwapAPI {
); );
} }
} }
Future<ExchangeResponse<List<FixedRateMarket>>> getFixedRateMarketInfo({
String? apiKey,
}) async {
final uri = _buildUri(
"/get_market_info",
null,
// {
// "api_key": apiKey ?? kSimpleSwapApiKey,
// "fixed": isFixedRate.toString(),
// "currency_from": currencyFrom,
// "currency_to": currencyTo,
// },
);
try {
final jsonArray = await _makeGetRequest(uri);
try {
final result = await compute(
_parseFixedRateMarketsJson,
jsonArray as List,
);
return result;
} catch (e, s) {
Logging.instance.log("getAvailableFixedRateMarkets exception: $e\n$s",
level: LogLevel.Error);
return ExchangeResponse(
exception: ExchangeException(
"Error: $jsonArray",
ExchangeExceptionType.serializeResponseError,
),
);
}
} catch (e, s) {
Logging.instance.log("getAvailableFixedRateMarkets exception: $e\n$s",
level: LogLevel.Error);
return ExchangeResponse(
exception: ExchangeException(
e.toString(),
ExchangeExceptionType.generic,
),
);
}
}
ExchangeResponse<List<FixedRateMarket>> _parseFixedRateMarketsJson(
List<dynamic> jsonArray) {
try {
final List<FixedRateMarket> markets = [];
for (final json in jsonArray) {
try {
final map = Map<String, dynamic>.from(json as Map);
markets.add(FixedRateMarket(
from: map["currency_from"] as String,
to: map["currency_to"] as String,
min: Decimal.parse(map["min"] as String),
max: Decimal.parse(map["max"] as String),
rate: Decimal.parse(map["rate"] as String),
minerFee: null,
));
} catch (_) {
return ExchangeResponse(
exception: ExchangeException("Failed to serialize $json",
ExchangeExceptionType.serializeResponseError));
}
}
return ExchangeResponse(value: markets);
} catch (_) {
rethrow;
}
}
} }

View file

@ -1,5 +1,6 @@
import 'package:decimal/decimal.dart'; import 'package:decimal/decimal.dart';
import 'package:stackwallet/models/exchange/response_objects/currency.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/pair.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/range.dart';
import 'package:stackwallet/models/exchange/response_objects/trade.dart'; import 'package:stackwallet/models/exchange/response_objects/trade.dart';
@ -76,7 +77,7 @@ class SimpleSwapExchange extends Exchange {
} }
@override @override
Future<ExchangeResponse<Decimal>> getEstimate( Future<ExchangeResponse<Estimate>> getEstimate(
String from, String from,
String to, String to,
Decimal amount, Decimal amount,
@ -89,10 +90,18 @@ class SimpleSwapExchange extends Exchange {
currencyTo: to, currencyTo: to,
amount: amount.toString(), amount: amount.toString(),
); );
if (response.exception != null) {
return ExchangeResponse(
exception: response.exception,
);
}
return ExchangeResponse( return ExchangeResponse(
value: Decimal.tryParse(response.value ?? ""), value: Estimate(
exception: response.exception, estimatedAmount: Decimal.parse(response.value!),
fixedRate: fixedRate,
reversed: reversed,
),
); );
} }

View file

@ -2,9 +2,9 @@ import 'package:decimal/decimal.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart'; import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart'; import 'package:mockito/mockito.dart';
import 'package:stackwallet/models/exchange/change_now/estimated_exchange_amount.dart';
import 'package:stackwallet/models/exchange/estimated_rate_exchange_form_state.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/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/change_now/change_now_api.dart';
import 'package:stackwallet/services/exchange/exchange_response.dart'; import 'package:stackwallet/services/exchange/exchange_response.dart';
@ -186,8 +186,9 @@ void main() {
toTicker: "xmr", toTicker: "xmr",
fromAmount: Decimal.parse("110.10"))) fromAmount: Decimal.parse("110.10")))
.thenAnswer((_) async => ExchangeResponse( .thenAnswer((_) async => ExchangeResponse(
value: EstimatedExchangeAmount( value: Estimate(
transactionSpeedForecast: '10-60', reversed: false,
fixedRate: false,
rateId: 'some rate id', rateId: 'some rate id',
warningMessage: '', warningMessage: '',
estimatedAmount: Decimal.parse("302.002348"), estimatedAmount: Decimal.parse("302.002348"),

View file

@ -9,16 +9,16 @@ import 'package:http/http.dart' as _i4;
import 'package:mockito/mockito.dart' as _i1; import 'package:mockito/mockito.dart' as _i1;
import 'package:stackwallet/models/exchange/change_now/cn_exchange_estimate.dart' import 'package:stackwallet/models/exchange/change_now/cn_exchange_estimate.dart'
as _i10; as _i10;
import 'package:stackwallet/models/exchange/change_now/estimated_exchange_amount.dart'
as _i9;
import 'package:stackwallet/models/exchange/change_now/exchange_transaction.dart' import 'package:stackwallet/models/exchange/change_now/exchange_transaction.dart'
as _i12; as _i12;
import 'package:stackwallet/models/exchange/change_now/exchange_transaction_status.dart' import 'package:stackwallet/models/exchange/change_now/exchange_transaction_status.dart'
as _i13; as _i13;
import 'package:stackwallet/models/exchange/change_now/fixed_rate_market.dart'
as _i11;
import 'package:stackwallet/models/exchange/response_objects/currency.dart' import 'package:stackwallet/models/exchange/response_objects/currency.dart'
as _i6; as _i6;
import 'package:stackwallet/models/exchange/response_objects/estimate.dart'
as _i9;
import 'package:stackwallet/models/exchange/response_objects/fixed_rate_market.dart'
as _i11;
import 'package:stackwallet/models/exchange/response_objects/pair.dart' as _i14; import 'package:stackwallet/models/exchange/response_objects/pair.dart' as _i14;
import 'package:stackwallet/models/exchange/response_objects/range.dart' as _i8; import 'package:stackwallet/models/exchange/response_objects/range.dart' as _i8;
import 'package:stackwallet/services/exchange/change_now/change_now_api.dart' import 'package:stackwallet/services/exchange/change_now/change_now_api.dart'
@ -97,26 +97,23 @@ class MockChangeNowAPI extends _i1.Mock implements _i3.ChangeNowAPI {
_FakeExchangeResponse_0<_i8.Range>())) _FakeExchangeResponse_0<_i8.Range>()))
as _i5.Future<_i2.ExchangeResponse<_i8.Range>>); as _i5.Future<_i2.ExchangeResponse<_i8.Range>>);
@override @override
_i5.Future<_i2.ExchangeResponse<_i9.EstimatedExchangeAmount>> _i5.Future<_i2.ExchangeResponse<_i9.Estimate>> getEstimatedExchangeAmount(
getEstimatedExchangeAmount( {String? fromTicker,
{String? fromTicker, String? toTicker,
String? toTicker, _i7.Decimal? fromAmount,
_i7.Decimal? fromAmount, String? apiKey}) =>
String? apiKey}) => (super.noSuchMethod(
(super.noSuchMethod( Invocation.method(#getEstimatedExchangeAmount, [], {
Invocation.method(#getEstimatedExchangeAmount, [], { #fromTicker: fromTicker,
#fromTicker: fromTicker, #toTicker: toTicker,
#toTicker: toTicker, #fromAmount: fromAmount,
#fromAmount: fromAmount, #apiKey: apiKey
#apiKey: apiKey }),
}), returnValue: Future<_i2.ExchangeResponse<_i9.Estimate>>.value(
returnValue: Future< _FakeExchangeResponse_0<_i9.Estimate>()))
_i2.ExchangeResponse< as _i5.Future<_i2.ExchangeResponse<_i9.Estimate>>);
_i9.EstimatedExchangeAmount>>.value(
_FakeExchangeResponse_0<_i9.EstimatedExchangeAmount>()))
as _i5.Future<_i2.ExchangeResponse<_i9.EstimatedExchangeAmount>>);
@override @override
_i5.Future<_i2.ExchangeResponse<_i9.EstimatedExchangeAmount>> _i5.Future<_i2.ExchangeResponse<_i9.Estimate>>
getEstimatedExchangeAmountFixedRate( getEstimatedExchangeAmountFixedRate(
{String? fromTicker, {String? fromTicker,
String? toTicker, String? toTicker,
@ -131,11 +128,9 @@ class MockChangeNowAPI extends _i1.Mock implements _i3.ChangeNowAPI {
#reversed: reversed, #reversed: reversed,
#apiKey: apiKey #apiKey: apiKey
}), }),
returnValue: Future< returnValue: Future<_i2.ExchangeResponse<_i9.Estimate>>.value(
_i2.ExchangeResponse< _FakeExchangeResponse_0<_i9.Estimate>()))
_i9.EstimatedExchangeAmount>>.value( as _i5.Future<_i2.ExchangeResponse<_i9.Estimate>>);
_FakeExchangeResponse_0<_i9.EstimatedExchangeAmount>()))
as _i5.Future<_i2.ExchangeResponse<_i9.EstimatedExchangeAmount>>);
@override @override
_i5.Future<_i2.ExchangeResponse<_i10.CNExchangeEstimate>> _i5.Future<_i2.ExchangeResponse<_i10.CNExchangeEstimate>>
getEstimatedExchangeAmountV2( getEstimatedExchangeAmountV2(

View file

@ -10,16 +10,16 @@ import 'package:http/http.dart' as _i13;
import 'package:mockito/mockito.dart' as _i1; import 'package:mockito/mockito.dart' as _i1;
import 'package:stackwallet/models/exchange/change_now/cn_exchange_estimate.dart' import 'package:stackwallet/models/exchange/change_now/cn_exchange_estimate.dart'
as _i18; as _i18;
import 'package:stackwallet/models/exchange/change_now/estimated_exchange_amount.dart'
as _i17;
import 'package:stackwallet/models/exchange/change_now/exchange_transaction.dart' import 'package:stackwallet/models/exchange/change_now/exchange_transaction.dart'
as _i20; as _i20;
import 'package:stackwallet/models/exchange/change_now/exchange_transaction_status.dart' import 'package:stackwallet/models/exchange/change_now/exchange_transaction_status.dart'
as _i21; as _i21;
import 'package:stackwallet/models/exchange/change_now/fixed_rate_market.dart'
as _i19;
import 'package:stackwallet/models/exchange/response_objects/currency.dart' import 'package:stackwallet/models/exchange/response_objects/currency.dart'
as _i14; as _i14;
import 'package:stackwallet/models/exchange/response_objects/estimate.dart'
as _i17;
import 'package:stackwallet/models/exchange/response_objects/fixed_rate_market.dart'
as _i19;
import 'package:stackwallet/models/exchange/response_objects/pair.dart' as _i22; import 'package:stackwallet/models/exchange/response_objects/pair.dart' as _i22;
import 'package:stackwallet/models/exchange/response_objects/range.dart' import 'package:stackwallet/models/exchange/response_objects/range.dart'
as _i16; as _i16;
@ -405,27 +405,23 @@ class MockChangeNowAPI extends _i1.Mock implements _i12.ChangeNowAPI {
_FakeExchangeResponse_0<_i16.Range>())) _FakeExchangeResponse_0<_i16.Range>()))
as _i7.Future<_i2.ExchangeResponse<_i16.Range>>); as _i7.Future<_i2.ExchangeResponse<_i16.Range>>);
@override @override
_i7.Future<_i2.ExchangeResponse<_i17.EstimatedExchangeAmount>> _i7.Future<_i2.ExchangeResponse<_i17.Estimate>> getEstimatedExchangeAmount(
getEstimatedExchangeAmount( {String? fromTicker,
{String? fromTicker, String? toTicker,
String? toTicker, _i15.Decimal? fromAmount,
_i15.Decimal? fromAmount, String? apiKey}) =>
String? apiKey}) => (super.noSuchMethod(
(super.noSuchMethod( Invocation.method(#getEstimatedExchangeAmount, [], {
Invocation.method(#getEstimatedExchangeAmount, [], { #fromTicker: fromTicker,
#fromTicker: fromTicker, #toTicker: toTicker,
#toTicker: toTicker, #fromAmount: fromAmount,
#fromAmount: fromAmount, #apiKey: apiKey
#apiKey: apiKey }),
}), returnValue: Future<_i2.ExchangeResponse<_i17.Estimate>>.value(
returnValue: Future< _FakeExchangeResponse_0<_i17.Estimate>()))
_i2.ExchangeResponse< as _i7.Future<_i2.ExchangeResponse<_i17.Estimate>>);
_i17.EstimatedExchangeAmount>>.value(
_FakeExchangeResponse_0<_i17.EstimatedExchangeAmount>()))
as _i7
.Future<_i2.ExchangeResponse<_i17.EstimatedExchangeAmount>>);
@override @override
_i7.Future<_i2.ExchangeResponse<_i17.EstimatedExchangeAmount>> _i7.Future<_i2.ExchangeResponse<_i17.Estimate>>
getEstimatedExchangeAmountFixedRate( getEstimatedExchangeAmountFixedRate(
{String? fromTicker, {String? fromTicker,
String? toTicker, String? toTicker,
@ -433,19 +429,16 @@ class MockChangeNowAPI extends _i1.Mock implements _i12.ChangeNowAPI {
bool? reversed, bool? reversed,
String? apiKey}) => String? apiKey}) =>
(super.noSuchMethod( (super.noSuchMethod(
Invocation.method(#getEstimatedExchangeAmountFixedRate, [], { Invocation.method(#getEstimatedExchangeAmountFixedRate, [], {
#fromTicker: fromTicker, #fromTicker: fromTicker,
#toTicker: toTicker, #toTicker: toTicker,
#fromAmount: fromAmount, #fromAmount: fromAmount,
#reversed: reversed, #reversed: reversed,
#apiKey: apiKey #apiKey: apiKey
}), }),
returnValue: Future< returnValue: Future<_i2.ExchangeResponse<_i17.Estimate>>.value(
_i2.ExchangeResponse< _FakeExchangeResponse_0<_i17.Estimate>())) as _i7
_i17.EstimatedExchangeAmount>>.value( .Future<_i2.ExchangeResponse<_i17.Estimate>>);
_FakeExchangeResponse_0<_i17.EstimatedExchangeAmount>()))
as _i7
.Future<_i2.ExchangeResponse<_i17.EstimatedExchangeAmount>>);
@override @override
_i7.Future<_i2.ExchangeResponse<_i18.CNExchangeEstimate>> _i7.Future<_i2.ExchangeResponse<_i18.CNExchangeEstimate>>
getEstimatedExchangeAmountV2( getEstimatedExchangeAmountV2(