mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2025-03-12 09:27:01 +00:00
changenow reverse fixed rate trade support
This commit is contained in:
parent
bb12e149f6
commit
a8396977ef
11 changed files with 54 additions and 102 deletions
|
@ -13,6 +13,8 @@ class IncompleteExchangeModel {
|
|||
|
||||
final ExchangeRateType rateType;
|
||||
|
||||
final bool reversed;
|
||||
|
||||
String? recipientAddress;
|
||||
String? refundAddress;
|
||||
|
||||
|
@ -27,6 +29,7 @@ class IncompleteExchangeModel {
|
|||
required this.sendAmount,
|
||||
required this.receiveAmount,
|
||||
required this.rateType,
|
||||
required this.reversed,
|
||||
this.rateId,
|
||||
});
|
||||
}
|
||||
|
|
|
@ -202,12 +202,13 @@ class Trade {
|
|||
);
|
||||
}
|
||||
|
||||
factory Trade.fromExchangeTransaction(ExchangeTransaction exTx) {
|
||||
factory Trade.fromExchangeTransaction(
|
||||
ExchangeTransaction exTx, bool reversed) {
|
||||
return Trade(
|
||||
uuid: exTx.uuid,
|
||||
tradeId: exTx.id,
|
||||
rateType: "",
|
||||
direction: "direct",
|
||||
direction: reversed ? "reverse" : "direct",
|
||||
timestamp: exTx.date,
|
||||
updatedAt: DateTime.tryParse(exTx.statusObject!.updatedAt) ?? exTx.date,
|
||||
payInCurrency: exTx.fromCurrency,
|
||||
|
|
|
@ -21,7 +21,6 @@ import 'package:stackwallet/pages/exchange_view/sub_widgets/exchange_rate_sheet.
|
|||
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/change_now_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';
|
||||
|
@ -530,37 +529,20 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
|
|||
|
||||
final rateType = ref.read(prefsChangeNotifierProvider).exchangeRateType;
|
||||
|
||||
final response = await ref.read(changeNowProvider).getEstimate(
|
||||
fromTicker,
|
||||
toTicker,
|
||||
sendAmount,
|
||||
false,
|
||||
false,
|
||||
);
|
||||
|
||||
if (response.value == null) {
|
||||
unawaited(showDialog<dynamic>(
|
||||
context: context,
|
||||
barrierDismissible: true,
|
||||
builder: (_) => StackDialog(
|
||||
title: "Failed to update trade estimate",
|
||||
message: response.exception?.toString(),
|
||||
),
|
||||
));
|
||||
return;
|
||||
}
|
||||
final estimate = ref.read(exchangeFormStateProvider).estimate!;
|
||||
|
||||
String rate =
|
||||
"1 ${fromTicker.toUpperCase()} ~${(response.value!.estimatedAmount / sendAmount).toDecimal(scaleOnInfinitePrecision: 8).toStringAsFixed(8)} ${toTicker.toUpperCase()}";
|
||||
"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: sendAmount,
|
||||
receiveAmount: response.value!.estimatedAmount,
|
||||
receiveAmount: estimate.estimatedAmount,
|
||||
rateType: rateType,
|
||||
rateId: response.value!.rateId,
|
||||
rateId: estimate.rateId,
|
||||
reversed: estimate.reversed,
|
||||
);
|
||||
|
||||
if (mounted) {
|
||||
|
@ -587,35 +569,19 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
|
|||
|
||||
final rateType = ref.read(prefsChangeNotifierProvider).exchangeRateType;
|
||||
|
||||
final response = await ref.read(changeNowProvider).getEstimate(
|
||||
fromTicker,
|
||||
toTicker,
|
||||
sendAmount,
|
||||
true,
|
||||
false,
|
||||
);
|
||||
final estimate = ref.read(exchangeFormStateProvider).estimate!;
|
||||
|
||||
bool? shouldCancel;
|
||||
|
||||
if (response.value == null) {
|
||||
unawaited(showDialog<dynamic>(
|
||||
context: context,
|
||||
barrierDismissible: true,
|
||||
builder: (_) => StackDialog(
|
||||
title: "Failed to update trade estimate",
|
||||
message: response.exception?.toString(),
|
||||
),
|
||||
));
|
||||
return;
|
||||
} else if (response.value!.warningMessage != null &&
|
||||
response.value!.warningMessage!.isNotEmpty) {
|
||||
if (estimate.warningMessage != null &&
|
||||
estimate.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?",
|
||||
"${estimate.warningMessage!}\n\nDo you want to attempt trade anyways?",
|
||||
leftButton: TextButton(
|
||||
style: Theme.of(context)
|
||||
.extension<StackColors>()!
|
||||
|
@ -657,10 +623,13 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
|
|||
sendTicker: fromTicker,
|
||||
receiveTicker: toTicker,
|
||||
rateInfo: rate,
|
||||
sendAmount: sendAmount,
|
||||
receiveAmount: response.value!.estimatedAmount,
|
||||
sendAmount: estimate.reversed ? estimate.estimatedAmount : sendAmount,
|
||||
receiveAmount: estimate.reversed
|
||||
? ref.read(exchangeFormStateProvider).toAmount!
|
||||
: estimate.estimatedAmount,
|
||||
rateType: rateType,
|
||||
rateId: response.value!.rateId,
|
||||
rateId: estimate.rateId,
|
||||
reversed: estimate.reversed,
|
||||
);
|
||||
|
||||
if (mounted) {
|
||||
|
|
|
@ -348,23 +348,9 @@ class _Step2ViewState extends ConsumerState<Step2View> {
|
|||
"sendViewScanQrButtonKey"),
|
||||
onTap: () async {
|
||||
try {
|
||||
// ref
|
||||
// .read(
|
||||
// shouldShowLockscreenOnResumeStateProvider
|
||||
// .state)
|
||||
// .state = false;
|
||||
final qrResult =
|
||||
await scanner.scan();
|
||||
|
||||
// Future<void>.delayed(
|
||||
// const Duration(seconds: 2),
|
||||
// () => ref
|
||||
// .read(
|
||||
// shouldShowLockscreenOnResumeStateProvider
|
||||
// .state)
|
||||
// .state = true,
|
||||
// );
|
||||
|
||||
final results =
|
||||
AddressUtils.parseUri(
|
||||
qrResult.rawContent);
|
||||
|
@ -385,16 +371,10 @@ class _Step2ViewState extends ConsumerState<Step2View> {
|
|||
setState(() {});
|
||||
}
|
||||
} on PlatformException catch (e, s) {
|
||||
// ref
|
||||
// .read(
|
||||
// shouldShowLockscreenOnResumeStateProvider
|
||||
// .state)
|
||||
// .state = true;
|
||||
// here we ignore the exception caused by not giving permission
|
||||
// to use the camera to scan a qr code
|
||||
Logging.instance.log(
|
||||
"Failed to get camera permissions while trying to scan qr code in SendView: $e\n$s",
|
||||
level: LogLevel.Warning);
|
||||
"Failed to get camera permissions while trying to scan qr code in SendView: $e\n$s",
|
||||
level: LogLevel.Warning,
|
||||
);
|
||||
}
|
||||
},
|
||||
child: const QrCodeIcon(),
|
||||
|
@ -585,23 +565,9 @@ class _Step2ViewState extends ConsumerState<Step2View> {
|
|||
"sendViewScanQrButtonKey"),
|
||||
onTap: () async {
|
||||
try {
|
||||
// ref
|
||||
// .read(
|
||||
// shouldShowLockscreenOnResumeStateProvider
|
||||
// .state)
|
||||
// .state = false;
|
||||
final qrResult =
|
||||
await scanner.scan();
|
||||
|
||||
// Future<void>.delayed(
|
||||
// const Duration(seconds: 2),
|
||||
// () => ref
|
||||
// .read(
|
||||
// shouldShowLockscreenOnResumeStateProvider
|
||||
// .state)
|
||||
// .state = true,
|
||||
// );
|
||||
|
||||
final results =
|
||||
AddressUtils.parseUri(
|
||||
qrResult.rawContent);
|
||||
|
@ -622,16 +588,10 @@ class _Step2ViewState extends ConsumerState<Step2View> {
|
|||
setState(() {});
|
||||
}
|
||||
} on PlatformException catch (e, s) {
|
||||
// ref
|
||||
// .read(
|
||||
// shouldShowLockscreenOnResumeStateProvider
|
||||
// .state)
|
||||
// .state = true;
|
||||
// here we ignore the exception caused by not giving permission
|
||||
// to use the camera to scan a qr code
|
||||
Logging.instance.log(
|
||||
"Failed to get camera permissions while trying to scan qr code in SendView: $e\n$s",
|
||||
level: LogLevel.Warning);
|
||||
"Failed to get camera permissions while trying to scan qr code in SendView: $e\n$s",
|
||||
level: LogLevel.Warning,
|
||||
);
|
||||
}
|
||||
},
|
||||
child: const QrCodeIcon(),
|
||||
|
@ -680,8 +640,9 @@ class _Step2ViewState extends ConsumerState<Step2View> {
|
|||
child: TextButton(
|
||||
onPressed: () {
|
||||
Navigator.of(context).pushNamed(
|
||||
Step3View.routeName,
|
||||
arguments: model);
|
||||
Step3View.routeName,
|
||||
arguments: model,
|
||||
);
|
||||
},
|
||||
style: Theme.of(context)
|
||||
.extension<StackColors>()!
|
||||
|
|
|
@ -251,10 +251,15 @@ class _Step3ViewState extends ConsumerState<Step3View> {
|
|||
to: model.receiveTicker,
|
||||
fixedRate: model.rateType !=
|
||||
ExchangeRateType.estimated,
|
||||
amount: model.sendAmount,
|
||||
amount: model.reversed
|
||||
? model.receiveAmount
|
||||
: model.sendAmount,
|
||||
addressTo: model.recipientAddress!,
|
||||
extraId: null,
|
||||
addressRefund: model.refundAddress!,
|
||||
refundExtraId: "",
|
||||
rateId: model.rateId,
|
||||
reversed: model.reversed,
|
||||
);
|
||||
|
||||
if (response.value == null) {
|
||||
|
|
|
@ -1198,7 +1198,7 @@ abstract class SWB {
|
|||
|
||||
Trade trade;
|
||||
if (exTx != null) {
|
||||
trade = Trade.fromExchangeTransaction(exTx);
|
||||
trade = Trade.fromExchangeTransaction(exTx, false);
|
||||
} else {
|
||||
trade = Trade.fromMap(trades[i] as Map<String, dynamic>);
|
||||
}
|
||||
|
@ -1220,7 +1220,7 @@ abstract class SWB {
|
|||
|
||||
Trade trade;
|
||||
if (exTx != null) {
|
||||
trade = Trade.fromExchangeTransaction(exTx);
|
||||
trade = Trade.fromExchangeTransaction(exTx, false);
|
||||
} else {
|
||||
trade = Trade.fromMap(trades.last as Map<String, dynamic>);
|
||||
}
|
||||
|
|
|
@ -678,6 +678,7 @@ class ChangeNowAPI {
|
|||
required String receivingAddress,
|
||||
required Decimal amount,
|
||||
required String rateId,
|
||||
required bool reversed,
|
||||
String extraId = "",
|
||||
String userId = "",
|
||||
String contactEmail = "",
|
||||
|
@ -689,7 +690,6 @@ class ChangeNowAPI {
|
|||
"from": fromTicker,
|
||||
"to": toTicker,
|
||||
"address": receivingAddress,
|
||||
"amount": amount.toString(),
|
||||
"flow": "fixed-rate",
|
||||
"extraId": extraId,
|
||||
"userId": userId,
|
||||
|
@ -699,8 +699,16 @@ class ChangeNowAPI {
|
|||
"rateId": rateId,
|
||||
};
|
||||
|
||||
if (reversed) {
|
||||
map["result"] = amount.toString();
|
||||
} else {
|
||||
map["amount"] = amount.toString();
|
||||
}
|
||||
|
||||
final uri = _buildUri(
|
||||
"/transactions/fixed-rate/${apiKey ?? kChangeNowApiKey}", null);
|
||||
"/transactions/fixed-rate${reversed ? "/from-result" : ""}/${apiKey ?? kChangeNowApiKey}",
|
||||
null,
|
||||
);
|
||||
|
||||
try {
|
||||
// simple json object is expected here
|
||||
|
|
|
@ -27,6 +27,7 @@ class ChangeNowExchange extends Exchange {
|
|||
required String addressRefund,
|
||||
required String refundExtraId,
|
||||
String? rateId,
|
||||
required bool reversed,
|
||||
}) async {
|
||||
late final ExchangeResponse<ExchangeTransaction> response;
|
||||
if (fixedRate) {
|
||||
|
@ -39,6 +40,7 @@ class ChangeNowExchange extends Exchange {
|
|||
extraId: extraId ?? "",
|
||||
refundAddress: addressRefund,
|
||||
refundExtraId: refundExtraId,
|
||||
reversed: reversed,
|
||||
);
|
||||
} else {
|
||||
response = await ChangeNowAPI.instance.createStandardExchangeTransaction(
|
||||
|
@ -66,6 +68,7 @@ class ChangeNowExchange extends Exchange {
|
|||
response.value!.copyWith(
|
||||
statusObject: statusResponse.value!,
|
||||
),
|
||||
reversed,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -47,5 +47,6 @@ abstract class Exchange {
|
|||
required String addressRefund,
|
||||
required String refundExtraId,
|
||||
String? rateId,
|
||||
required bool reversed,
|
||||
});
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ class SimpleSwapExchange extends Exchange {
|
|||
required String addressRefund,
|
||||
required String refundExtraId,
|
||||
String? rateId,
|
||||
required bool reversed,
|
||||
}) async {
|
||||
return await SimpleSwapAPI.instance.createNewExchange(
|
||||
isFixedRate: fixedRate,
|
||||
|
|
|
@ -128,7 +128,7 @@ class DbVersionMigrator {
|
|||
|
||||
for (final old in trades) {
|
||||
if (old.statusObject != null) {
|
||||
final trade = Trade.fromExchangeTransaction(old);
|
||||
final trade = Trade.fromExchangeTransaction(old, false);
|
||||
await DB.instance.put<Trade>(
|
||||
boxName: DB.boxNameTradesV2,
|
||||
key: trade.uuid,
|
||||
|
|
Loading…
Reference in a new issue