Merge pull request #87 from cake-tech/CAKE-278-implement-fixed-rate-flow-for-changenow

Cake 278 implement fixed rate flow for changenow
This commit is contained in:
M 2021-03-01 19:34:25 +02:00
commit bc70a3302b
20 changed files with 383 additions and 143 deletions

View file

@ -29,6 +29,8 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
static const _exchangeAmountUriSufix = '/exchange-amount/';
static const _transactionsUriSufix = '/transactions/';
static const _minAmountUriSufix = '/min-amount/';
static const _marketInfoUriSufix = '/market-info/';
static const _fixedRateUriSufix = 'fixed-rate/';
@override
String get title => 'ChangeNOW';
@ -44,19 +46,43 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
Future<bool> checkIsAvailable() async => true;
@override
Future<Limits> fetchLimits({CryptoCurrency from, CryptoCurrency to}) async {
Future<Limits> fetchLimits({CryptoCurrency from, CryptoCurrency to,
bool isFixedRateMode}) async {
final symbol = from.toString() + '_' + to.toString();
final url = apiUri + _minAmountUriSufix + symbol;
final url = isFixedRateMode
? apiUri + _marketInfoUriSufix + _fixedRateUriSufix + apiKey
: apiUri + _minAmountUriSufix + symbol;
final response = await get(url);
if (isFixedRateMode) {
final responseJSON = json.decode(response.body) as List<dynamic>;
for (var elem in responseJSON) {
final elemFrom = elem["from"] as String;
final elemTo = elem["to"] as String;
if ((elemFrom == from.toString().toLowerCase()) &&
(elemTo == to.toString().toLowerCase())) {
final min = elem["min"] as double;
final max = elem["max"] as double;
return Limits(min: min, max: max);
}
}
return Limits(min: 0, max: 0);
} else {
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final min = responseJSON['minAmount'] as double;
return Limits(min: min, max: null);
}
}
@override
Future<Trade> createTrade({TradeRequest request}) async {
const url = apiUri + _transactionsUriSufix + apiKey;
Future<Trade> createTrade({TradeRequest request, bool isFixedRateMode}) async {
final url = isFixedRateMode
? apiUri + _transactionsUriSufix + _fixedRateUriSufix + apiKey
: apiUri + _transactionsUriSufix + apiKey;
final _request = request as ChangeNowRequest;
final body = {
'from': _request.from.toString(),
@ -127,7 +153,24 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
final state = TradeState.deserialize(raw: status);
final extraId = responseJSON['payinExtraId'] as String;
final outputTransaction = responseJSON['payoutHash'] as String;
final expiredAtRaw = responseJSON['validUntil'] as String;
final expiredAt = expiredAtRaw != null
? DateTime.parse(expiredAtRaw).toLocal()
: null;
if (expiredAt != null) {
return Trade(
id: id,
from: from,
to: to,
provider: description,
inputAddress: inputAddress,
amount: expectedSendAmount,
state: state,
extraId: extraId,
expiredAt: expiredAt,
outputTransaction: outputTransaction);
} else {
return Trade(
id: id,
from: from,
@ -139,14 +182,50 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
extraId: extraId,
outputTransaction: outputTransaction);
}
}
@override
Future<double> calculateAmount(
{CryptoCurrency from,
CryptoCurrency to,
double amount,
bool isFixedRateMode,
bool isReceiveAmount}) async {
final url = apiUri +
if (isReceiveAmount && isFixedRateMode) {
final url = apiUri + _marketInfoUriSufix + _fixedRateUriSufix + apiKey;
final response = await get(url);
final responseJSON = json.decode(response.body) as List<dynamic>;
var rate = 0.0;
var fee = 0.0;
for (var elem in responseJSON) {
final elemFrom = elem["from"] as String;
final elemTo = elem["to"] as String;
if ((elemFrom == to.toString().toLowerCase()) &&
(elemTo == from.toString().toLowerCase())) {
rate = elem["rate"] as double;
fee = elem["minerFee"] as double;
break;
}
}
final estimatedAmount = (amount == 0.0)||(rate == 0.0) ? 0.0
: (amount + fee)/rate;
return estimatedAmount;
} else {
final url = isFixedRateMode
? apiUri +
_exchangeAmountUriSufix +
_fixedRateUriSufix +
amount.toString() +
'/' +
from.toString() +
'_' +
to.toString() +
'?api_key=' + apiKey
: apiUri +
_exchangeAmountUriSufix +
amount.toString() +
'/' +
@ -159,4 +238,5 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
return estimatedAmount;
}
}
}

View file

@ -17,10 +17,11 @@ abstract class ExchangeProvider {
@override
String toString() => title;
Future<Limits> fetchLimits({CryptoCurrency from, CryptoCurrency to});
Future<Trade> createTrade({TradeRequest request});
Future<Limits> fetchLimits(
{CryptoCurrency from, CryptoCurrency to, bool isFixedRateMode});
Future<Trade> createTrade({TradeRequest request, bool isFixedRateMode});
Future<Trade> findTradeById({@required String id});
Future<double> calculateAmount(
{CryptoCurrency from, CryptoCurrency to, double amount, bool isReceiveAmount});
Future<double> calculateAmount({CryptoCurrency from, CryptoCurrency to,
double amount, bool isFixedRateMode, bool isReceiveAmount});
Future<bool> checkIsAvailable();
}

View file

@ -71,7 +71,7 @@ class MorphTokenExchangeProvider extends ExchangeProvider {
Future<bool> checkIsAvailable() async => true;
@override
Future<Limits> fetchLimits({CryptoCurrency from, CryptoCurrency to}) async {
Future<Limits> fetchLimits({CryptoCurrency from, CryptoCurrency to, bool isFixedRateMode}) async {
final url = apiUri + _limitsURISuffix;
final headers = {'Content-type': 'application/json'};
final body = json.encode({
@ -100,7 +100,7 @@ class MorphTokenExchangeProvider extends ExchangeProvider {
}
@override
Future<Trade> createTrade({TradeRequest request}) async {
Future<Trade> createTrade({TradeRequest request, bool isFixedRateMode}) async {
const url = apiUri + _morphURISuffix;
final _request = request as MorphTokenRequest;
final body = {
@ -191,7 +191,7 @@ class MorphTokenExchangeProvider extends ExchangeProvider {
@override
Future<double> calculateAmount(
{CryptoCurrency from, CryptoCurrency to, double amount,
{CryptoCurrency from, CryptoCurrency to, double amount, bool isFixedRateMode,
bool isReceiveAmount}) async {
final url = apiUri + _ratesURISuffix;
final response = await get(url);

View file

@ -58,7 +58,7 @@ class XMRTOExchangeProvider extends ExchangeProvider {
}
@override
Future<Limits> fetchLimits({CryptoCurrency from, CryptoCurrency to}) async {
Future<Limits> fetchLimits({CryptoCurrency from, CryptoCurrency to, bool isFixedRateMode}) async {
final url = originalApiUri + _orderParameterUriSuffix;
final response = await get(url);
final correction = 0.001;
@ -91,7 +91,7 @@ class XMRTOExchangeProvider extends ExchangeProvider {
}
@override
Future<Trade> createTrade({TradeRequest request}) async {
Future<Trade> createTrade({TradeRequest request, bool isFixedRateMode}) async {
final _request = request as XMRTOTradeRequest;
final url = originalApiUri + _orderCreateUriSuffix;
final _amount =
@ -188,6 +188,7 @@ class XMRTOExchangeProvider extends ExchangeProvider {
{CryptoCurrency from,
CryptoCurrency to,
double amount,
bool isFixedRateMode,
bool isReceiveAmount}) async {
if (from != CryptoCurrency.xmr && to != CryptoCurrency.btc) {
return 0;

View file

@ -35,7 +35,7 @@ class S implements WidgetsLocalizations {
String get all => "ALL";
String get amount => "Amount: ";
String get amount_is_estimate => "The receive amount is an estimate";
String get amount_is_guaranteed => "In xmr.to, to receive a guaranteed BTC amount, enter the BTC amount and not the XMR amount above";
String get amount_is_guaranteed => "The receive amount is guaranteed";
String get auth_store_ban_timeout => "ban_timeout";
String get auth_store_banned_for => "Banned for ";
String get auth_store_banned_minutes => " minutes";
@ -395,6 +395,8 @@ class S implements WidgetsLocalizations {
String get confirmed => 'Confirmed';
String get unconfirmed => 'Unconfirmed';
String get displayable => 'Displayable';
String get fixed_rate => 'Fixed rate';
String get fixed_rate_alert => 'You will be able to enter receive amount when fixed rate mode is checked. Do you want to switch to fixed rate mode?';
String get xlm_extra_info => 'Please dont forget to specify the Memo ID while sending the XLM transaction for the exchange';
String get xrp_extra_info => 'Please dont forget to specify the Destination Tag while sending the XRP transaction for the exchange';
}
@ -538,7 +540,7 @@ class $de extends S {
@override
String get receive => "Erhalten";
@override
String get amount_is_guaranteed => "Geben Sie in xmr.to den BTC-Betrag und nicht den oben genannten XMR-Betrag ein, um einen garantierten BTC-Betrag zu erhalten";
String get amount_is_guaranteed => "Der Empfangsbetrag ist garantiert";
@override
String get auth_store_banned_for => "Gebannt für ";
@override
@ -1154,6 +1156,10 @@ class $de extends S {
@override
String get displayable => 'Anzeigebar';
@override
String get fixed_rate => 'Fester Zinssatz';
@override
String get fixed_rate_alert => 'Sie können den Empfangsbetrag eingeben, wenn der Festpreismodus aktiviert ist. Möchten Sie in den Festpreismodus wechseln?';
@override
String get xlm_extra_info => 'Bitte vergessen Sie nicht, die Memo-ID anzugeben, während Sie die XLM-Transaktion für den Austausch senden';
@override
String get xrp_extra_info => 'Bitte vergessen Sie nicht, das Ziel-Tag anzugeben, während Sie die XRP-Transaktion für den Austausch senden';
@ -1298,7 +1304,7 @@ class $hi extends S {
@override
String get receive => "प्राप्त करना";
@override
String get amount_is_guaranteed => "Xmr.to में, गारंटीशुदा BTC राशि प्राप्त करने के लिए, BTC राशि दर्ज करें और ऊपर XMR राशि नही";
String get amount_is_guaranteed => "प्राप्त राशि की गारंटी है";
@override
String get auth_store_banned_for => "के लिए प्रतिबंधित है ";
@override
@ -1914,6 +1920,10 @@ class $hi extends S {
@override
String get displayable => 'प्रदर्शन योग्य';
@override
String get fixed_rate => 'निर्धारित दर';
@override
String get fixed_rate_alert => 'फिक्स्ड रेट मोड की जांच करने पर आप प्राप्त राशि दर्ज कर पाएंगे। क्या आप निश्चित दर मोड पर स्विच करना चाहते हैं?';
@override
String get xlm_extra_info => 'एक्सचेंज के लिए XLM ट्रांजेक्शन भेजते समय मेमो आईडी निर्दिष्ट करना न भूलें';
@override
String get xrp_extra_info => 'एक्सचेंज के लिए एक्सआरपी लेनदेन भेजते समय कृपया गंतव्य टैग निर्दिष्ट करना न भूलें';
@ -2058,7 +2068,7 @@ class $ru extends S {
@override
String get receive => "Получить";
@override
String get amount_is_guaranteed => "В xmr.to, чтобы получить гарантированную сумму BTC, введите сумму BTC, а не сумму XMR выше";
String get amount_is_guaranteed => "Полученная сумма гарантирована";
@override
String get auth_store_banned_for => "Заблокировано на ";
@override
@ -2674,6 +2684,10 @@ class $ru extends S {
@override
String get displayable => 'Отображаемый';
@override
String get fixed_rate => 'Фиксированная ставка';
@override
String get fixed_rate_alert => 'Вы сможете ввести сумму получения тогда, когда будет установлен режим фиксированной ставки. Вы хотите перейти в режим фиксированной ставки?';
@override
String get xlm_extra_info => 'Не забудьте указать Memo ID (памятка) при отправке транзакции XLM для обмена';
@override
String get xrp_extra_info => 'Не забудьте указать целевой тег при отправке транзакции XRP для обмена';
@ -2818,7 +2832,7 @@ class $ko extends S {
@override
String get receive => "받다";
@override
String get amount_is_guaranteed => "xmr.to에서 보장 된 BTC 금액을 받으려면 위의 XMR 금액이 아닌 BTC 금액을 입력하십시오.";
String get amount_is_guaranteed => "수령 금액이 보장됩니다.";
@override
String get auth_store_banned_for => "금지";
@override
@ -3434,6 +3448,10 @@ class $ko extends S {
@override
String get displayable => '표시 가능';
@override
String get fixed_rate => '고정 비율';
@override
String get fixed_rate_alert => '고정 금리 모드 체크시 수취 금액 입력이 가능합니다. 고정 속도 모드로 전환 하시겠습니까?';
@override
String get xlm_extra_info => '교환을 위해 XLM 거래를 보낼 때 메모 ID를 지정하는 것을 잊지 마십시오';
@override
String get xrp_extra_info => '교환을 위해 XRP 트랜잭션을 보내는 동안 대상 태그를 지정하는 것을 잊지 마십시오';
@ -3578,7 +3596,7 @@ class $pt extends S {
@override
String get receive => "Receber";
@override
String get amount_is_guaranteed => "Em xmr.to, para receber um valor BTC garantido, insira o valor BTC e não o valor XMR acima";
String get amount_is_guaranteed => "O valor recebido é garantido";
@override
String get auth_store_banned_for => "Banido por";
@override
@ -4194,6 +4212,10 @@ class $pt extends S {
@override
String get displayable => 'Exibível';
@override
String get fixed_rate => 'Taxa fixa';
@override
String get fixed_rate_alert => 'Você poderá inserir a quantia recebida quando o modo de taxa fixa estiver marcado. Quer mudar para o modo de taxa fixa?';
@override
String get xlm_extra_info => 'Não se esqueça de especificar o Memo ID ao enviar a transação XLM para a troca';
@override
String get xrp_extra_info => 'Não se esqueça de especificar a etiqueta de destino ao enviar a transação XRP para a troca';
@ -4338,7 +4360,7 @@ class $uk extends S {
@override
String get receive => "Отримати";
@override
String get amount_is_guaranteed => "У xmr.to, щоб отримати гарантовану суму BTC, введіть суму BTC, а не XMR вище";
String get amount_is_guaranteed => "Отримана сума є гарантованою";
@override
String get auth_store_banned_for => "Заблоковано на ";
@override
@ -4954,6 +4976,10 @@ class $uk extends S {
@override
String get displayable => 'Відображуваний';
@override
String get fixed_rate => 'Фіксована ставка';
@override
String get fixed_rate_alert => 'Ви зможете ввести суму отримання тоді, коли буде встановлений режим фіксованої ставки. Ви хочете перейти в режим фіксованої ставки?';
@override
String get xlm_extra_info => "Будь ласка, не забудьте вказати ідентифікатор пам'ятки під час надсилання транзакції XLM для обміну";
@override
String get xrp_extra_info => 'Будь ласка, не забудьте вказати тег призначення під час надсилання XRP-транзакції для обміну';
@ -5098,7 +5124,7 @@ class $ja extends S {
@override
String get receive => "受け取る";
@override
String get amount_is_guaranteed => "xmr.toで、保証されたBTC金額を受け取るには、上記のXMR金額ではなく、BTC金額を入力します";
String get amount_is_guaranteed => "受け取り金額は保証されています";
@override
String get auth_store_banned_for => "禁止されています ";
@override
@ -5714,6 +5740,10 @@ class $ja extends S {
@override
String get displayable => '表示可能';
@override
String get fixed_rate => '固定金利';
@override
String get fixed_rate_alert => '固定金利モードにチェックを入れると、受取額を入力できるようになります。 固定金利モードに切り替えますか?';
@override
String get xlm_extra_info => '交換用のXLMトランザクションを送信するときに、メモIDを指定することを忘れないでください';
@override
String get xrp_extra_info => '取引所のXRPトランザクションを送信するときに、宛先タグを指定することを忘れないでください';
@ -5862,7 +5892,7 @@ class $pl extends S {
@override
String get receive => "Otrzymać";
@override
String get amount_is_guaranteed => "W xmr.to, aby otrzymać gwarantowaną kwotę BTC, wprowadź kwotę BTC, a nie kwotę XMR powyżej";
String get amount_is_guaranteed => "Otrzymana kwota jest gwarantowana";
@override
String get auth_store_banned_for => "Bzbanowany za ";
@override
@ -6478,6 +6508,10 @@ class $pl extends S {
@override
String get displayable => 'Wyświetlane';
@override
String get fixed_rate => 'Stała stawka';
@override
String get fixed_rate_alert => 'Będziesz mógł wprowadzić kwotę otrzymaną, gdy zaznaczony jest tryb stałej stawki. Czy chcesz przejść do trybu stałej stawki?';
@override
String get xlm_extra_info => 'Nie zapomnij podać identyfikatora notatki podczas wysyłania transakcji XLM do wymiany';
@override
String get xrp_extra_info => 'Nie zapomnij podać tagu docelowego podczas wysyłania transakcji XRP do wymiany';
@ -6622,7 +6656,7 @@ class $es extends S {
@override
String get receive => "Recibir";
@override
String get amount_is_guaranteed => "En xmr.to, para recibir una cantidad BTC garantizada, ingrese la cantidad BTC y no la cantidad XMR arriba";
String get amount_is_guaranteed => "La cantidad recibida está garantizada";
@override
String get auth_store_banned_for => "Prohibido para ";
@override
@ -7238,6 +7272,10 @@ class $es extends S {
@override
String get displayable => 'Visualizable';
@override
String get fixed_rate => 'Tipo de interés fijo';
@override
String get fixed_rate_alert => 'Podrá ingresar la cantidad recibida cuando el modo de tarifa fija esté marcado. ¿Quieres cambiar al modo de tarifa fija?';
@override
String get xlm_extra_info => 'No olvide especificar el ID de nota al enviar la transacción XLM para el intercambio';
@override
String get xrp_extra_info => 'No olvide especificar la etiqueta de destino al enviar la transacción XRP para el intercambio';
@ -7382,7 +7420,7 @@ class $nl extends S {
@override
String get receive => "Krijgen";
@override
String get amount_is_guaranteed => "Om een gegarandeerd BTC-bedrag te ontvangen, voert u in xmr.to het BTC-bedrag in en niet het bovenstaande XMR-bedrag";
String get amount_is_guaranteed => "Het ontvangen bedrag is gegarandeerd";
@override
String get auth_store_banned_for => "Verboden voor ";
@override
@ -7998,6 +8036,10 @@ class $nl extends S {
@override
String get displayable => 'Weer te geven';
@override
String get fixed_rate => 'Vast tarief';
@override
String get fixed_rate_alert => 'U kunt het ontvangen bedrag invoeren wanneer de modus voor vaste tarieven is aangevinkt. Wilt u overschakelen naar de vaste-tariefmodus?';
@override
String get xlm_extra_info => 'Vergeet niet om de Memo-ID op te geven tijdens het verzenden van de XLM-transactie voor de uitwisseling';
@override
String get xrp_extra_info => 'Vergeet niet om de Destination Tag op te geven tijdens het verzenden van de XRP-transactie voor de uitwisseling';
@ -8142,7 +8184,7 @@ class $zh extends S {
@override
String get receive => "接收";
@override
String get amount_is_guaranteed => "在xmr.to中要接收保证的BTC数量请输入BTC数量而不要输入上方的XMR数量";
String get amount_is_guaranteed => "接收金額有保證";
@override
String get auth_store_banned_for => "禁止 ";
@override
@ -8758,6 +8800,10 @@ class $zh extends S {
@override
String get displayable => '可显示';
@override
String get fixed_rate => '固定利率';
@override
String get fixed_rate_alert => '選中固定費率模式後,您將可以輸入接收金額。 您要切換到固定速率模式嗎?';
@override
String get xlm_extra_info => '發送用於交換的XLM交易時請不要忘記指定備忘錄ID';
@override
String get xrp_extra_info => '發送用於交換的XRP交易時請不要忘記指定目標標記';

View file

@ -1,6 +1,8 @@
import 'dart:ui';
import 'package:cake_wallet/entities/sync_status.dart';
import 'package:cake_wallet/entities/wallet_type.dart';
import 'package:cake_wallet/exchange/changenow/changenow_exchange_provider.dart';
import 'package:cake_wallet/src/widgets/standard_checkbox.dart';
import 'package:dotted_border/dotted_border.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
@ -37,6 +39,7 @@ class ExchangePage extends BasePage {
final ExchangeViewModel exchangeViewModel;
final depositKey = GlobalKey<ExchangeCardState>();
final receiveKey = GlobalKey<ExchangeCardState>();
final checkBoxKey = GlobalKey<StandardCheckboxState>();
final _formKey = GlobalKey<FormState>();
final _depositAmountFocus = FocusNode();
final _receiveAmountFocus = FocusNode();
@ -115,7 +118,7 @@ class ExchangePage extends BasePage {
key: _formKey,
child: ScrollableWithBottomSection(
contentPadding: EdgeInsets.only(bottom: 24),
content: Column(
content: Observer(builder: (_) => Column(
children: <Widget>[
Container(
padding: EdgeInsets.only(bottom: 32),
@ -240,9 +243,7 @@ class ExchangePage extends BasePage {
? exchangeViewModel.wallet.address
: exchangeViewModel.receiveAddress,
initialIsAmountEditable: exchangeViewModel
.provider is XMRTOExchangeProvider
? true
: false,
.isReceiveAmountEditable,
initialIsAddressEditable:
exchangeViewModel
.isReceiveAddressEnabled,
@ -271,6 +272,21 @@ class ExchangePage extends BasePage {
],
),
),
if (exchangeViewModel.isReceiveAmountEditable) Padding(
padding: EdgeInsets.only(top: 12, left: 24),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
StandardCheckbox(
key: checkBoxKey,
value: exchangeViewModel.isFixedRateMode,
caption: S.of(context).fixed_rate,
onChanged: (value) =>
exchangeViewModel.isFixedRateMode = value,
),
],
)
),
Padding(
padding: EdgeInsets.only(top: 30, left: 24, bottom: 24),
child: Row(
@ -395,15 +411,14 @@ class ExchangePage extends BasePage {
],
)))
],
),
)),
bottomSectionPadding:
EdgeInsets.only(left: 24, right: 24, bottom: 24),
bottomSection: Column(children: <Widget>[
Padding(
padding: EdgeInsets.only(bottom: 15),
child: Observer(builder: (_) {
final description =
exchangeViewModel.provider is XMRTOExchangeProvider
final description = exchangeViewModel.isFixedRateMode
? S.of(context).amount_is_guaranteed
: S.of(context).amount_is_estimate;
return Center(
@ -464,17 +479,9 @@ class ExchangePage extends BasePage {
currency: CryptoCurrency.fromString(template.receiveCurrency));
switch (template.provider) {
case 'XMR.TO':
exchangeViewModel.changeProvider(
provider: exchangeViewModel.providerList[0]);
break;
case 'ChangeNOW':
exchangeViewModel.changeProvider(
provider: exchangeViewModel.providerList[1]);
break;
case 'MorphToken':
exchangeViewModel.changeProvider(
provider: exchangeViewModel.providerList[2]);
provider: exchangeViewModel.providerList[0]);
break;
}
@ -482,6 +489,7 @@ class ExchangePage extends BasePage {
exchangeViewModel.depositAddress = template.depositAddress;
exchangeViewModel.receiveAddress = template.receiveAddress;
exchangeViewModel.isReceiveAmountEntered = false;
exchangeViewModel.isFixedRateMode = false;
}
void _setReactions(
@ -566,10 +574,10 @@ class ExchangePage extends BasePage {
receiveKey.currentState.isAddressEditable(isEditable: isEnabled);
});
reaction((_) => exchangeViewModel.provider, (ExchangeProvider provider) {
provider is XMRTOExchangeProvider
? receiveKey.currentState.isAmountEditable(isEditable: true)
: receiveKey.currentState.isAmountEditable(isEditable: false);
reaction((_) => exchangeViewModel.isReceiveAmountEditable,
(bool isReceiveAmountEditable) {
receiveKey.currentState
.isAmountEditable(isEditable: isReceiveAmountEditable);
});
reaction((_) => exchangeViewModel.tradeState, (ExchangeTradeState state) {
@ -647,6 +655,45 @@ class ExchangePage extends BasePage {
}
});
_receiveAmountFocus.addListener(() {
if (_receiveAmountFocus.hasFocus && !exchangeViewModel.isFixedRateMode) {
showPopUp<void>(
context: context,
builder: (BuildContext context) {
return AlertWithTwoActions(
alertTitle: S.of(context).exchange,
alertContent: S.of(context).fixed_rate_alert,
leftButtonText: S.of(context).cancel,
rightButtonText: S.of(context).ok,
actionLeftButton: () {
FocusScope.of(context).unfocus();
Navigator.of(context).pop();
},
actionRightButton: () {
exchangeViewModel.isFixedRateMode = true;
checkBoxKey.currentState
.changeValue(exchangeViewModel.isFixedRateMode);
Navigator.of(context).pop();
});
});
}
});
reaction((_) => exchangeViewModel.isFixedRateMode, (bool isFixedRateMode) {
if ((_receiveAmountFocus.hasFocus ||
exchangeViewModel.isReceiveAmountEntered) && !isFixedRateMode) {
FocusScope.of(context).unfocus();
receiveAmountController.text = '';
} else {
exchangeViewModel.changeDepositAmount(
amount: depositAmountController.text);
}
checkBoxKey.currentState
.changeValue(exchangeViewModel.isFixedRateMode);
exchangeViewModel.loadLimits();
});
_isReactionsSet = true;
}

View file

@ -4,9 +4,10 @@ import 'package:flutter/material.dart';
class StandardCheckbox extends StatefulWidget {
StandardCheckbox({
Key key,
@required this.value,
this.caption = '',
@required this.onChanged});
@required this.onChanged}) : super(key: key);
final bool value;
final String caption;
@ -24,6 +25,10 @@ class StandardCheckboxState extends State<StandardCheckbox> {
String caption;
Function(bool) onChanged;
void changeValue(bool newValue) {
setState(() => value = newValue);
}
@override
Widget build(BuildContext context) {
return GestureDetector(

View file

@ -57,7 +57,8 @@ abstract class ExchangeViewModelBase with Store {
_onPairChange();
}
});
_defineIsReceiveAmountEditable();
isFixedRateMode = false;
isReceiveAmountEntered = false;
loadLimits();
}
@ -106,6 +107,12 @@ abstract class ExchangeViewModelBase with Store {
@observable
bool isReceiveAmountEntered;
@observable
bool isReceiveAmountEditable;
@observable
bool isFixedRateMode;
@computed
SyncStatus get status => wallet.syncStatus;
@ -127,12 +134,15 @@ abstract class ExchangeViewModelBase with Store {
this.provider = provider;
depositAmount = '';
receiveAmount = '';
isFixedRateMode = false;
_defineIsReceiveAmountEditable();
loadLimits();
}
@action
void changeDepositCurrency({CryptoCurrency currency}) {
depositCurrency = currency;
isFixedRateMode = false;
_onPairChange();
isDepositAddressEnabled = !(depositCurrency == wallet.currency);
isReceiveAddressEnabled = !(receiveCurrency == wallet.currency);
@ -141,6 +151,7 @@ abstract class ExchangeViewModelBase with Store {
@action
void changeReceiveCurrency({CryptoCurrency currency}) {
receiveCurrency = currency;
isFixedRateMode = false;
_onPairChange();
isDepositAddressEnabled = !(depositCurrency == wallet.currency);
isReceiveAddressEnabled = !(receiveCurrency == wallet.currency);
@ -160,9 +171,10 @@ abstract class ExchangeViewModelBase with Store {
provider
.calculateAmount(
from: depositCurrency,
to: receiveCurrency,
from: receiveCurrency,
to: depositCurrency,
amount: _amount,
isFixedRateMode: isFixedRateMode,
isReceiveAmount: true)
.then((amount) => _cryptoNumberFormat
.format(amount)
@ -187,6 +199,7 @@ abstract class ExchangeViewModelBase with Store {
from: depositCurrency,
to: receiveCurrency,
amount: _amount,
isFixedRateMode: isFixedRateMode,
isReceiveAmount: false)
.then((amount) => _cryptoNumberFormat
.format(amount)
@ -200,8 +213,8 @@ abstract class ExchangeViewModelBase with Store {
limitsState = LimitsIsLoading();
try {
limits = await provider.fetchLimits(
from: depositCurrency, to: receiveCurrency);
limits = await provider.fetchLimits(from: depositCurrency,
to: receiveCurrency, isFixedRateMode: isFixedRateMode);
limitsState = LimitsLoadedSuccessfully(limits: limits);
} catch (e) {
limitsState = LimitsLoadedFailure(error: e.toString());
@ -265,7 +278,8 @@ abstract class ExchangeViewModelBase with Store {
} else {
try {
tradeState = TradeIsCreating();
final trade = await provider.createTrade(request: request);
final trade = await provider.createTrade(request: request,
isFixedRateMode: isFixedRateMode);
trade.walletId = wallet.id;
tradesStore.setTrade(trade);
await trades.add(trade);
@ -285,15 +299,15 @@ abstract class ExchangeViewModelBase with Store {
@action
void reset() {
_initialPairBasedOnWallet();
isReceiveAmountEntered = false;
depositAmount = '';
receiveAmount = '';
depositCurrency = CryptoCurrency.xmr;
receiveCurrency = CryptoCurrency.btc;
depositAddress = depositCurrency == wallet.currency ? wallet.address : '';
receiveAddress = receiveCurrency == wallet.currency ? wallet.address : '';
isDepositAddressEnabled = !(depositCurrency == wallet.currency);
isReceiveAddressEnabled = !(receiveCurrency == wallet.currency);
isFixedRateMode = false;
_onPairChange();
}
@ -364,7 +378,7 @@ abstract class ExchangeViewModelBase with Store {
}
}
depositAddress = depositCurrency == wallet.currency ? wallet.address : '';
_defineIsReceiveAmountEditable();
depositAmount = '';
receiveAmount = '';
loadLimits();
@ -389,4 +403,14 @@ abstract class ExchangeViewModelBase with Store {
break;
}
}
void _defineIsReceiveAmountEditable() {
if ((provider is ChangeNowExchangeProvider)
&&(depositCurrency == CryptoCurrency.xmr)
&&(receiveCurrency == CryptoCurrency.btc)) {
isReceiveAmountEditable = true;
} else {
isReceiveAmountEditable = false;
}
}
}

View file

@ -65,7 +65,7 @@
"change_exchange_provider" : "Wechseln Sie den Exchange-Anbieter",
"you_will_send" : "Konvertieren von",
"you_will_get" : "Konvertieren zu",
"amount_is_guaranteed" : "Geben Sie in xmr.to den BTC-Betrag und nicht den oben genannten XMR-Betrag ein, um einen garantierten BTC-Betrag zu erhalten",
"amount_is_guaranteed" : "Der Empfangsbetrag ist garantiert",
"amount_is_estimate" : "Der empfangene Betrag ist eine Schätzung",
"powered_by" : "Unterstützt von ${title}",
"error" : "Error",
@ -458,6 +458,9 @@
"import" : "Importieren",
"please_select_backup_file" : "Bitte wählen Sie die Sicherungsdatei und geben Sie das Sicherungskennwort ein.",
"fixed_rate" : "Fester Zinssatz",
"fixed_rate_alert" : "Sie können den Empfangsbetrag eingeben, wenn der Festpreismodus aktiviert ist. Möchten Sie in den Festpreismodus wechseln?",
"xlm_extra_info" : "Bitte vergessen Sie nicht, die Memo-ID anzugeben, während Sie die XLM-Transaktion für den Austausch senden",
"xrp_extra_info" : "Bitte vergessen Sie nicht, das Ziel-Tag anzugeben, während Sie die XRP-Transaktion für den Austausch senden"
}

View file

@ -65,7 +65,7 @@
"change_exchange_provider" : "Change Exchange Provider",
"you_will_send" : "Convert from",
"you_will_get" : "Convert to",
"amount_is_guaranteed" : "In xmr.to, to receive a guaranteed BTC amount, enter the BTC amount and not the XMR amount above",
"amount_is_guaranteed" : "The receive amount is guaranteed",
"amount_is_estimate" : "The receive amount is an estimate",
"powered_by" : "Powered by ${title}",
"error" : "Error",
@ -458,6 +458,9 @@
"import" : "Import",
"please_select_backup_file" : "Please select backup file and enter backup password.",
"fixed_rate" : "Fixed rate",
"fixed_rate_alert" : "You will be able to enter receive amount when fixed rate mode is checked. Do you want to switch to fixed rate mode?",
"xlm_extra_info" : "Please dont forget to specify the Memo ID while sending the XLM transaction for the exchange",
"xrp_extra_info" : "Please dont forget to specify the Destination Tag while sending the XRP transaction for the exchange"
}

View file

@ -65,7 +65,7 @@
"change_exchange_provider" : "Cambiar proveedor de intercambio",
"you_will_send" : "Convertir de",
"you_will_get" : "Convertir a",
"amount_is_guaranteed" : "En xmr.to, para recibir una cantidad BTC garantizada, ingrese la cantidad BTC y no la cantidad XMR arriba",
"amount_is_guaranteed" : "La cantidad recibida está garantizada",
"amount_is_estimate" : "El monto recibido es un estimado",
"powered_by" : "Energizado por ${title}",
"error" : "Error",
@ -458,6 +458,9 @@
"import" : "Importar",
"please_select_backup_file" : "Seleccione el archivo de respaldo e ingrese la contraseña de respaldo.",
"fixed_rate" : "Tipo de interés fijo",
"fixed_rate_alert" : "Podrá ingresar la cantidad recibida cuando el modo de tarifa fija esté marcado. ¿Quieres cambiar al modo de tarifa fija?",
"xlm_extra_info" : "No olvide especificar el ID de nota al enviar la transacción XLM para el intercambio",
"xrp_extra_info" : "No olvide especificar la etiqueta de destino al enviar la transacción XRP para el intercambio"
}

View file

@ -65,7 +65,7 @@
"change_exchange_provider" : "एक्सचेंज प्रदाता बदलें",
"you_will_send" : "से रूपांतरित करें",
"you_will_get" : "में बदलें",
"amount_is_guaranteed" : "Xmr.to में, गारंटीशुदा BTC राशि प्राप्त करने के लिए, BTC राशि दर्ज करें और ऊपर XMR राशि नहीं",
"amount_is_guaranteed" : "प्राप्त राशि की गारंटी है",
"amount_is_estimate" : "प्राप्त राशि एक अनुमान है",
"powered_by" : "द्वारा संचालित ${title}",
"error" : "त्रुटि",
@ -458,6 +458,9 @@
"import" : "आयात",
"please_select_backup_file" : "कृपया बैकअप फ़ाइल चुनें और बैकअप पासवर्ड डालें।",
"fixed_rate" : "निर्धारित दर",
"fixed_rate_alert" : "फिक्स्ड रेट मोड की जांच करने पर आप प्राप्त राशि दर्ज कर पाएंगे। क्या आप निश्चित दर मोड पर स्विच करना चाहते हैं?",
"xlm_extra_info" : "एक्सचेंज के लिए XLM ट्रांजेक्शन भेजते समय मेमो आईडी निर्दिष्ट करना न भूलें",
"xrp_extra_info" : "एक्सचेंज के लिए एक्सआरपी लेनदेन भेजते समय कृपया गंतव्य टैग निर्दिष्ट करना न भूलें"
}

View file

@ -65,7 +65,7 @@
"change_exchange_provider" : "Exchangeプロバイダーの変更",
"you_will_send" : "から変換",
"you_will_get" : "に変換",
"amount_is_guaranteed" : "xmr.toで、保証されたBTC金額を受け取るには、上記のXMR金額ではなく、BTC金額を入力します",
"amount_is_guaranteed" : "受け取り金額は保証されています",
"amount_is_estimate" : "受け取り金額は見積もりです",
"powered_by" : "搭載 ${title}",
"error" : "エラー",
@ -458,6 +458,9 @@
"import" : "インポート",
"please_select_backup_file" : "バックアップファイルを選択し、バックアップパスワードを入力してください。",
"fixed_rate" : "固定金利",
"fixed_rate_alert" : "固定金利モードにチェックを入れると、受取額を入力できるようになります。 固定金利モードに切り替えますか?",
"xlm_extra_info" : "交換用のXLMトランザクションを送信するときに、メモIDを指定することを忘れないでください",
"xrp_extra_info" : "取引所のXRPトランザクションを送信するときに、宛先タグを指定することを忘れないでください"
}

View file

@ -65,7 +65,7 @@
"change_exchange_provider" : "교환 공급자 변경",
"you_will_send" : "다음에서 변환",
"you_will_get" : "로 변환하다",
"amount_is_guaranteed" : "xmr.to에서 보장 된 BTC 금액을 받으려면 위의 XMR 금액이 아닌 BTC 금액을 입력하십시오.",
"amount_is_guaranteed" : "수령 금액이 보장됩니다.",
"amount_is_estimate" : "수신 금액은 견적입니다",
"powered_by" : "에 의해 구동 ${title}",
"error" : "오류",
@ -458,6 +458,9 @@
"import" : "수입",
"please_select_backup_file" : "백업 파일을 선택하고 백업 암호를 입력하십시오.",
"fixed_rate" : "고정 비율",
"fixed_rate_alert" : "고정 금리 모드 체크시 수취 금액 입력이 가능합니다. 고정 속도 모드로 전환 하시겠습니까?",
"xlm_extra_info" : "교환을 위해 XLM 거래를 보낼 때 메모 ID를 지정하는 것을 잊지 마십시오",
"xrp_extra_info" : "교환을 위해 XRP 트랜잭션을 보내는 동안 대상 태그를 지정하는 것을 잊지 마십시오"
}

View file

@ -65,7 +65,7 @@
"change_exchange_provider" : "Wijzig Exchange Provider",
"you_will_send" : "Converteren van",
"you_will_get" : "Converteren naar",
"amount_is_guaranteed" : "Om een gegarandeerd BTC-bedrag te ontvangen, voert u in xmr.to het BTC-bedrag in en niet het bovenstaande XMR-bedrag",
"amount_is_guaranteed" : "Het ontvangen bedrag is gegarandeerd",
"amount_is_estimate" : "Het ontvangen bedrag is een schatting",
"powered_by" : "Aangedreven door ${title}",
"error" : "Fout",
@ -458,6 +458,9 @@
"import" : "Importeren",
"please_select_backup_file" : "Selecteer een back-upbestand en voer een back-upwachtwoord in.",
"fixed_rate" : "Vast tarief",
"fixed_rate_alert" : "U kunt het ontvangen bedrag invoeren wanneer de modus voor vaste tarieven is aangevinkt. Wilt u overschakelen naar de vaste-tariefmodus?",
"xlm_extra_info" : "Vergeet niet om de Memo-ID op te geven tijdens het verzenden van de XLM-transactie voor de uitwisseling",
"xrp_extra_info" : "Vergeet niet om de Destination Tag op te geven tijdens het verzenden van de XRP-transactie voor de uitwisseling"
}

View file

@ -65,7 +65,7 @@
"change_exchange_provider" : "Zmień dostawcę programu Exchange",
"you_will_send" : "Konwertuj z",
"you_will_get" : "Konwertuj na",
"amount_is_guaranteed" : "W xmr.to, aby otrzymać gwarantowaną kwotę BTC, wprowadź kwotę BTC, a nie kwotę XMR powyżej",
"amount_is_guaranteed" : "Otrzymana kwota jest gwarantowana",
"amount_is_estimate" : "Otrzymana kwota jest wartością szacunkową",
"powered_by" : "Zasilany przez ${title}",
"error" : "Błąd",
@ -458,6 +458,9 @@
"import" : "Import",
"please_select_backup_file" : "Wybierz plik kopii zapasowej i wprowadź hasło zapasowe.",
"fixed_rate" : "Stała stawka",
"fixed_rate_alert" : "Będziesz mógł wprowadzić kwotę otrzymaną, gdy zaznaczony jest tryb stałej stawki. Czy chcesz przejść do trybu stałej stawki?",
"xlm_extra_info" : "Nie zapomnij podać identyfikatora notatki podczas wysyłania transakcji XLM do wymiany",
"xrp_extra_info" : "Nie zapomnij podać tagu docelowego podczas wysyłania transakcji XRP do wymiany"
}

View file

@ -65,7 +65,7 @@
"change_exchange_provider" : "Alterar o provedor de troca",
"you_will_send" : "Converter de",
"you_will_get" : "Converter para",
"amount_is_guaranteed" : "Em xmr.to, para receber um valor BTC garantido, insira o valor BTC e não o valor XMR acima",
"amount_is_guaranteed" : "O valor recebido é garantido",
"amount_is_estimate" : "O valor a ser recebido informado acima é uma estimativa",
"powered_by" : "Troca realizada por ${title}",
"error" : "Erro",
@ -458,6 +458,9 @@
"import" : "Importar",
"please_select_backup_file" : "Selecione o arquivo de backup e insira a senha de backup.",
"fixed_rate" : "Taxa fixa",
"fixed_rate_alert" : "Você poderá inserir a quantia recebida quando o modo de taxa fixa estiver marcado. Quer mudar para o modo de taxa fixa?",
"xlm_extra_info" : "Não se esqueça de especificar o Memo ID ao enviar a transação XLM para a troca",
"xrp_extra_info" : "Não se esqueça de especificar a etiqueta de destino ao enviar a transação XRP para a troca"
}

View file

@ -65,7 +65,7 @@
"change_exchange_provider" : "Изменить провайдера обмена",
"you_will_send" : "Конвертировать из",
"you_will_get" : "Конвертировать в",
"amount_is_guaranteed" : "В xmr.to, чтобы получить гарантированную сумму BTC, введите сумму BTC, а не сумму XMR выше",
"amount_is_guaranteed" : "Полученная сумма гарантирована",
"amount_is_estimate" : "Полученная сумма является приблизительной",
"powered_by" : "Используя ${title}",
"error" : "Ошибка",
@ -458,6 +458,9 @@
"import" : "Импортировать",
"please_select_backup_file" : "Выберите файл резервной копии и введите пароль резервной копии.",
"fixed_rate" : "Фиксированная ставка",
"fixed_rate_alert" : "Вы сможете ввести сумму получения тогда, когда будет установлен режим фиксированной ставки. Вы хотите перейти в режим фиксированной ставки?",
"xlm_extra_info" : "Не забудьте указать Memo ID (памятка) при отправке транзакции XLM для обмена",
"xrp_extra_info" : "Не забудьте указать целевой тег при отправке транзакции XRP для обмена"
}

View file

@ -65,7 +65,7 @@
"change_exchange_provider" : "Змінити провайдера обміну",
"you_will_send" : "Конвертувати з",
"you_will_get" : "Конвертувати в",
"amount_is_guaranteed" : "У xmr.to, щоб отримати гарантовану суму BTC, введіть суму BTC, а не XMR вище",
"amount_is_guaranteed" : "Отримана сума є гарантованою",
"amount_is_estimate" : "Отримана сума є приблизною",
"powered_by" : "Використовуючи ${title}",
"error" : "Помилка",
@ -458,6 +458,9 @@
"import" : "Імпортувати",
"please_select_backup_file" : "Виберіть файл резервної копії та введіть пароль резервної копії.",
"fixed_rate" : "Фіксована ставка",
"fixed_rate_alert" : "Ви зможете ввести суму отримання тоді, коли буде встановлений режим фіксованої ставки. Ви хочете перейти в режим фіксованої ставки?",
"xlm_extra_info" : "Будь ласка, не забудьте вказати ідентифікатор пам'ятки під час надсилання транзакції XLM для обміну",
"xrp_extra_info" : "Будь ласка, не забудьте вказати тег призначення під час надсилання XRP-транзакції для обміну"
}

View file

@ -65,7 +65,7 @@
"change_exchange_provider" : "更改交易所提供商",
"you_will_send" : "從轉換",
"you_will_get" : "轉換成",
"amount_is_guaranteed" : "在xmr.to中要接收保证的BTC数量请输入BTC数量而不要输入上方的XMR数量",
"amount_is_guaranteed" : "接收金額有保證",
"amount_is_estimate" : "收款金额为估算值",
"powered_by" : "供电 ${title}",
"error" : "错误",
@ -458,6 +458,9 @@
"import" : "進口",
"please_select_backup_file" : "請選擇備份文件,然後輸入備份密碼。",
"fixed_rate" : "固定利率",
"fixed_rate_alert" : "選中固定費率模式後,您將可以輸入接收金額。 您要切換到固定速率模式嗎?",
"xlm_extra_info" : "發送用於交換的XLM交易時請不要忘記指定備忘錄ID",
"xrp_extra_info" : "發送用於交換的XRP交易時請不要忘記指定目標標記"
}