Merge branch 'main' into deploy

wownero
M 3 years ago
commit 47c12a459c

@ -7,9 +7,9 @@ import io.flutter.plugins.GeneratedPluginRegistrant;
public class MainActivity extends FlutterFragmentActivity {
@Override
public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
GeneratedPluginRegistrant.registerWith(flutterEngine);
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

@ -1,4 +1,4 @@
Last Modified: January 28, 2021
Last Modified: March 1, 2021
Acceptance of the Terms of Use
These terms of use are entered into by and between You and Cake Technologies LLC ("Company," "we," or "us"). The following terms and conditions "Terms of Use") govern your access to and use of the Cake Wallet app, including any content, functionality, and services offered on or through the Cake Wallet app (the “App").
Please read the Terms of Use carefully before you start to use the App. By using the App you accept and agree to be bound and abide by these Terms of Use and our Privacy Policy, , incorporated herein by reference. If you do not wish to agree to these Terms of Use or the Privacy Policy, you must not access or use the App.
@ -45,7 +45,7 @@ Links from the App
If the App contains links to other sites and resources provided by third parties, these links are provided for your convenience only. We have no control over the contents of those sites or resources, and accept no responsibility for them or for any loss or damage that may arise from your use of them. If you decide to access any of the third-party Apps or services linked to this App, you do so entirely at your own risk and subject to the terms and conditions of use for such Apps.
Geographic Restrictions
The owner of the App is based in the State of Florida in the United States. We provide this App for use only by persons located in the United States. We make no claims that the App or any of its content is accessible or appropriate outside of the United States. Access to the App may not be legal by certain persons or in certain countries. If you access the App from outside the United States, you do so on your own initiative and are responsible for compliance with local laws.
The owner of the App is based in the State of Florida in the United States. Please consult with qualified legal counsel to assess the appropriate use of the App or any of its contents in the jurisdiction(s) you intend to use the App. The owner of the App makes no representation or warranty as to the suitability for use, compliance or other matter of law with respect to use in any jurisdiction. If you access the App from outside the United States, you do so on your own initiative and are responsible for compliance with local laws and regulations.
Translations
The App may contain translations of the English version of the content available on the App. These translations are provided only as a convenience. In the event of any conflict between the English language version and the translated version, the English language version shall take precedence. If you notice any inconsistencies, please report them on GitHub.
Risks Related to the use of the App

@ -4,8 +4,10 @@ import 'package:cake_wallet/core/wallet_service.dart';
import 'package:cake_wallet/entities/biometric_auth.dart';
import 'package:cake_wallet/entities/contact_record.dart';
import 'package:cake_wallet/entities/load_current_wallet.dart';
import 'package:cake_wallet/entities/order.dart';
import 'package:cake_wallet/entities/transaction_description.dart';
import 'package:cake_wallet/entities/transaction_info.dart';
import 'package:cake_wallet/entities/wyre_service.dart';
import 'package:cake_wallet/monero/monero_wallet_service.dart';
import 'package:cake_wallet/entities/contact.dart';
import 'package:cake_wallet/entities/node.dart';
@ -22,6 +24,7 @@ import 'package:cake_wallet/src/screens/faq/faq_page.dart';
import 'package:cake_wallet/src/screens/new_wallet/new_wallet_type_page.dart';
import 'package:cake_wallet/src/screens/nodes/node_create_or_edit_page.dart';
import 'package:cake_wallet/src/screens/nodes/nodes_list_page.dart';
import 'package:cake_wallet/src/screens/order_details/order_details_page.dart';
import 'package:cake_wallet/src/screens/pin_code/pin_code_widget.dart';
import 'package:cake_wallet/src/screens/rescan/rescan_page.dart';
import 'package:cake_wallet/src/screens/restore/restore_from_backup_page.dart';
@ -39,6 +42,8 @@ import 'package:cake_wallet/src/screens/transaction_details/transaction_details_
import 'package:cake_wallet/src/screens/wallet_keys/wallet_keys_page.dart';
import 'package:cake_wallet/src/screens/exchange/exchange_page.dart';
import 'package:cake_wallet/src/screens/exchange/exchange_template_page.dart';
import 'package:cake_wallet/src/screens/wyre/wyre_page.dart';
import 'package:cake_wallet/store/dashboard/orders_store.dart';
import 'package:cake_wallet/store/node_list_store.dart';
import 'package:cake_wallet/store/secret_store.dart';
import 'package:cake_wallet/store/settings_store.dart';
@ -63,6 +68,7 @@ import 'package:cake_wallet/view_model/exchange/exchange_trade_view_model.dart';
import 'package:cake_wallet/view_model/monero_account_list/account_list_item.dart';
import 'package:cake_wallet/view_model/node_list/node_list_view_model.dart';
import 'package:cake_wallet/view_model/node_list/node_create_or_edit_view_model.dart';
import 'package:cake_wallet/view_model/order_details_view_model.dart';
import 'package:cake_wallet/view_model/rescan_view_model.dart';
import 'package:cake_wallet/view_model/restore_from_backup_view_model.dart';
import 'package:cake_wallet/view_model/setup_pin_code_view_model.dart';
@ -83,6 +89,7 @@ import 'package:cake_wallet/view_model/wallet_list/wallet_list_view_model.dart';
import 'package:cake_wallet/view_model/wallet_restore_view_model.dart';
import 'package:cake_wallet/view_model/wallet_seed_view_model.dart';
import 'package:cake_wallet/view_model/exchange/exchange_view_model.dart';
import 'package:cake_wallet/view_model/wyre_view_model.dart';
import 'package:flutter/widgets.dart';
import 'package:get_it/get_it.dart';
import 'package:hive/hive.dart';
@ -116,6 +123,7 @@ Box<Trade> _tradesSource;
Box<Template> _templates;
Box<ExchangeTemplate> _exchangeTemplates;
Box<TransactionDescription> _transactionDescriptionBox;
Box<Order> _ordersSource;
Future setup(
{Box<WalletInfo> walletInfoSource,
@ -124,7 +132,8 @@ Future setup(
Box<Trade> tradesSource,
Box<Template> templates,
Box<ExchangeTemplate> exchangeTemplates,
Box<TransactionDescription> transactionDescriptionBox}) async {
Box<TransactionDescription> transactionDescriptionBox,
Box<Order> ordersSource}) async {
_walletInfoSource = walletInfoSource;
_nodeSource = nodeSource;
_contactSource = contactSource;
@ -132,6 +141,7 @@ Future setup(
_templates = templates;
_exchangeTemplates = exchangeTemplates;
_transactionDescriptionBox = transactionDescriptionBox;
_ordersSource = ordersSource;
if (!_isSetupFinished) {
getIt.registerSingletonAsync<SharedPreferences>(
@ -162,6 +172,8 @@ Future setup(
nodeListStore: getIt.get<NodeListStore>()));
getIt.registerSingleton<TradesStore>(TradesStore(
tradesSource: _tradesSource, settingsStore: getIt.get<SettingsStore>()));
getIt.registerSingleton<OrdersStore>(OrdersStore(
ordersSource: _ordersSource, settingsStore: getIt.get<SettingsStore>()));
getIt.registerSingleton<TradeFilterStore>(TradeFilterStore());
getIt.registerSingleton<TransactionFilterStore>(TransactionFilterStore());
getIt.registerSingleton<FiatConversionStore>(FiatConversionStore());
@ -225,7 +237,10 @@ Future setup(
tradesStore: getIt.get<TradesStore>(),
tradeFilterStore: getIt.get<TradeFilterStore>(),
transactionFilterStore: getIt.get<TransactionFilterStore>(),
settingsStore: settingsStore));
settingsStore: settingsStore,
ordersSource: _ordersSource,
ordersStore: getIt.get<OrdersStore>(),
wyreViewModel: getIt.get<WyreViewModel>()));
getIt.registerFactory<AuthService>(() => AuthService(
secureStorage: getIt.get<FlutterSecureStorage>(),
@ -517,6 +532,30 @@ Future setup(
getIt.registerFactoryParam<TradeDetailsPage, Trade, void>((Trade trade, _) =>
TradeDetailsPage(getIt.get<TradeDetailsViewModel>(param1: trade)));
getIt.registerFactory(() {
final wallet = getIt.get<AppStore>().wallet;
return WyreService(walletType: wallet.type, walletAddress: wallet.address);
});
getIt.registerFactory(() {
final wallet = getIt.get<AppStore>().wallet;
return WyreViewModel(ordersSource, getIt.get<OrdersStore>(),
walletId: wallet.id, address: wallet.address, type: wallet.type,
wyreService: getIt.get<WyreService>());
});
getIt.registerFactoryParam<WyrePage, String, void>((String url, _) =>
WyrePage(getIt.get<WyreViewModel>(),
ordersStore: getIt.get<OrdersStore>(), url: url));
getIt.registerFactoryParam<OrderDetailsViewModel, Order, void>(
(order, _) => OrderDetailsViewModel(
wyreViewModel: getIt.get<WyreViewModel>(),
orderForDetails: order));
getIt.registerFactoryParam<OrderDetailsPage, Order, void>((Order order, _) =>
OrderDetailsPage(getIt.get<OrderDetailsViewModel>(param1: order)));
getIt.registerFactory(() => SupportViewModel());
getIt.registerFactory(() => SupportPage(getIt.get<SupportViewModel>()));

@ -0,0 +1,55 @@
import 'package:hive/hive.dart';
import 'package:cake_wallet/exchange/trade_state.dart';
import 'package:cake_wallet/entities/format_amount.dart';
part 'order.g.dart';
@HiveType(typeId: Order.typeId)
class Order extends HiveObject {
Order(
{this.id,
this.transferId,
this.from,
this.to,
TradeState state,
this.createdAt,
this.amount,
this.receiveAddress,
this.walletId})
: stateRaw = state?.raw;
static const typeId = 8;
static const boxName = 'Orders';
static const boxKey = 'ordersBoxKey';
@HiveField(0)
String id;
@HiveField(1)
String transferId;
@HiveField(2)
String from;
@HiveField(3)
String to;
@HiveField(4)
String stateRaw;
TradeState get state => TradeState.deserialize(raw: stateRaw);
@HiveField(5)
DateTime createdAt;
@HiveField(6)
String amount;
@HiveField(7)
String receiveAddress;
@HiveField(8)
String walletId;
String amountFormatted() => formatAmount(amount);
}

@ -0,0 +1,8 @@
class WyreException implements Exception {
WyreException(this.description);
String description;
@override
String toString() => description;
}

@ -0,0 +1,111 @@
import 'dart:convert';
import 'package:cake_wallet/entities/wyre_exception.dart';
import 'package:cake_wallet/exchange/trade_state.dart';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart';
import 'package:cake_wallet/.secrets.g.dart' as secrets;
import 'package:cake_wallet/entities/order.dart';
import 'package:cake_wallet/entities/wallet_type.dart';
class WyreService {
WyreService({
@required this.walletType,
@required this.walletAddress,
this.isTestEnvironment = false}) {
baseApiUrl = isTestEnvironment
? _baseTestApiUrl
: _baseProductApiUrl;
trackUrl = isTestEnvironment
? _trackTestUrl
: _trackProductUrl;
}
static const _baseTestApiUrl = 'https://api.testwyre.com';
static const _baseProductApiUrl = 'https://api.sendwyre.com';
static const _trackTestUrl = 'https://dash.testwyre.com/track/';
static const _trackProductUrl = 'https://dash.sendwyre.com/track/';
static const _ordersSuffix = '/v3/orders';
static const _reserveSuffix = '/reserve';
static const _timeStampSuffix = '?timestamp=';
static const _transferSuffix = '/v2/transfer/';
static const _trackSuffix = '/track';
final bool isTestEnvironment;
final WalletType walletType;
final String walletAddress;
String baseApiUrl;
String trackUrl;
Future<String> getWyreUrl() async {
final timestamp = DateTime.now().millisecondsSinceEpoch.toString();
final url = baseApiUrl + _ordersSuffix + _reserveSuffix +
_timeStampSuffix + timestamp;
final secretKey = secrets.wyreSecretKey;
final accountId = secrets.wyreAccountId;
final body = {
'destCurrency': walletTypeToCryptoCurrency(walletType).title,
'dest': walletTypeToString(walletType).toLowerCase() + ':' + walletAddress,
'referrerAccountId': accountId,
'lockFields': ['destCurrency', 'dest']
};
final response = await post(url,
headers: {
'Authorization': 'Bearer $secretKey',
'Content-Type': 'application/json',
'cache-control': 'no-cache'
},
body: json.encode(body));
if (response.statusCode != 200) {
throw WyreException('Url $url is not found!');
}
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final urlFromResponse = responseJSON['url'] as String;
return urlFromResponse;
}
Future<Order> findOrderById(String id) async {
final orderUrl = baseApiUrl + _ordersSuffix + '/$id';
final orderResponse = await get(orderUrl);
if (orderResponse.statusCode != 200) {
throw WyreException('Order $id is not found!');
}
final orderResponseJSON =
json.decode(orderResponse.body) as Map<String, dynamic>;
final transferId = orderResponseJSON['transferId'] as String;
final from = orderResponseJSON['sourceCurrency'] as String;
final to = orderResponseJSON['destCurrency'] as String;
final status = orderResponseJSON['status'] as String;
final state = TradeState.deserialize(raw: status.toLowerCase());
final createdAtRaw = orderResponseJSON['createdAt'] as int;
final createdAt =
DateTime.fromMillisecondsSinceEpoch(createdAtRaw).toLocal();
final transferUrl =
baseApiUrl + _transferSuffix + transferId + _trackSuffix;
final transferResponse = await get(transferUrl);
if (transferResponse.statusCode != 200) {
throw WyreException('Transfer $transferId is not found!');
}
final transferResponseJSON =
json.decode(transferResponse.body) as Map<String, dynamic>;
final amount = transferResponseJSON['destAmount'] as double;
return Order(
id: id,
transferId: transferId,
from: from,
to: to,
state: state,
createdAt: createdAt,
amount: amount.toString()
);
}
}

@ -368,7 +368,7 @@ class S implements WidgetsLocalizations {
String error_text_maximum_limit(String provider, String max, String currency) => "Trade for ${provider} is not created. Amount is more then maximum: ${max} ${currency}";
String error_text_minimal_limit(String provider, String min, String currency) => "Trade for ${provider} is not created. Amount is less then minimal: ${min} ${currency}";
String exchange_result_confirm(String fetchingLabel, String from, String walletName) => "By pressing confirm, you will be sending ${fetchingLabel} ${from} from your wallet called ${walletName} to the address shown below. Or you can send from your external wallet to the below address/QR code.\n\nPlease press confirm to continue or go back to change the amounts.";
String exchange_result_description(String fetchingLabel, String from) => "Please send ${fetchingLabel} ${from} to the address shown on the next page.";
String exchange_result_description(String fetchingLabel, String from) => "You must send a minimum of ${fetchingLabel} ${from} to the address shown on the next page. If you send an amount lower than ${fetchingLabel} ${from} it may not get converted and it may not be refunded.";
String failed_authentication(String state_error) => "Failed authentication. ${state_error}";
String max_value(String value, String currency) => "Max: ${value} ${currency}";
String min_value(String value, String currency) => "Min: ${value} ${currency}";
@ -1132,7 +1132,7 @@ class $de extends S {
@override
String error_text_limits_loading_failed(String provider) => "Handel für ${provider} wird nicht erstellt. Das Laden der Limits ist fehlgeschlagen";
@override
String exchange_result_description(String fetchingLabel, String from) => "Bitte senden ${fetchingLabel} ${from} an die auf der nächsten Seite angegebene Adresse.'";
String exchange_result_description(String fetchingLabel, String from) => "Sie müssen mindestens ${fetchingLabel} ${from} an die auf der nächsten Seite angegebene Adresse senden. Wenn Sie einen Betrag unter ${fetchingLabel} ${from} senden, wird dieser möglicherweise nicht konvertiert und möglicherweise nicht erstattet.";
@override
String commit_transaction_amount_fee(String amount, String fee) => "Transaktion festschreiben\nMenge: ${amount}\nGebühr: ${fee}";
@override
@ -1896,7 +1896,7 @@ class $hi extends S {
@override
String error_text_limits_loading_failed(String provider) => "व्यापार ${provider} के लिए नहीं बनाया गया है। लोडिंग की सीमाएं विफल रहीं";
@override
String exchange_result_description(String fetchingLabel, String from) => "कृपया भेजें ${fetchingLabel} ${from} अगले पृष्ठ पर दिखाए गए पते पर";
String exchange_result_description(String fetchingLabel, String from) => "आपको अगले पृष्ठ पर दिखाए गए पते पर न्यूनतम ${fetchingLabel} ${from} भेजना होगा। यदि आप ${fetchingLabel} ${from} से कम राशि भेजते हैं तो यह परिवर्तित नहीं हो सकती है और इसे वापस नहीं किया जा सकता है।";
@override
String commit_transaction_amount_fee(String amount, String fee) => "लेन-देन करें\nरकम: ${amount}\nशुल्क: ${fee}";
@override
@ -2660,7 +2660,7 @@ class $ru extends S {
@override
String error_text_limits_loading_failed(String provider) => "Сделка для ${provider} не создана. Ошибка загрузки лимитов";
@override
String exchange_result_description(String fetchingLabel, String from) => "Пожалуйста отправьте ${fetchingLabel} ${from} на адрес, указанный на следующей странице.";
String exchange_result_description(String fetchingLabel, String from) => "Вы должны отправить минимум ${fetchingLabel} ${from} на адрес, указанный на следующей странице. Если вы отправите сумму менее ${fetchingLabel} ${from}, то она может быть не конвертирована и не возвращена.";
@override
String commit_transaction_amount_fee(String amount, String fee) => "Подтвердить транзакцию \nСумма: ${amount}\nКомиссия: ${fee}";
@override
@ -3424,7 +3424,7 @@ class $ko extends S {
@override
String error_text_limits_loading_failed(String provider) => "거래 ${provider} 가 생성되지 않습니다. 로딩 실패";
@override
String exchange_result_description(String fetchingLabel, String from) => "보내주세요 ${fetchingLabel} ${from} 다음 페이지에 표시된 주소로.";
String exchange_result_description(String fetchingLabel, String from) => "다음 페이지에 표시된 주소로 최소 ${fetchingLabel} ${from} 를 보내야합니다. ${fetchingLabel} ${from} 보다 적은 금액을 보내면 변환되지 않고 환불되지 않을 수 있습니다.";
@override
String commit_transaction_amount_fee(String amount, String fee) => "커밋 거래\n양: ${amount}\n보수: ${fee}";
@override
@ -4188,7 +4188,7 @@ class $pt extends S {
@override
String error_text_limits_loading_failed(String provider) => "A troca por ${provider} não é criada. Falha no carregamento dos limites";
@override
String exchange_result_description(String fetchingLabel, String from) => "Por favor, envie ${fetchingLabel} ${from} para o endereço mostrado na próxima página.";
String exchange_result_description(String fetchingLabel, String from) => "Você deve enviar no mínimo ${fetchingLabel} ${from} para o endereço mostrado na próxima página. Se você enviar um valor inferior a ${fetchingLabel} ${from}, ele pode não ser convertido e pode não ser reembolsado.";
@override
String commit_transaction_amount_fee(String amount, String fee) => "Confirmar transação\nQuantia: ${amount}\nTaxa: ${fee}";
@override
@ -4952,7 +4952,7 @@ class $uk extends S {
@override
String error_text_limits_loading_failed(String provider) => "Операція для ${provider} не створена. Помилка завантаження лімітів";
@override
String exchange_result_description(String fetchingLabel, String from) => "Будь ласка, відправте ${fetchingLabel} ${from} на адресу, вказану на наступній сторінці.";
String exchange_result_description(String fetchingLabel, String from) => "Ви повинні надіслати мінімум ${fetchingLabel} ${from} на адресу, вказану на наступній сторінці. Якщо ви надішлете суму меншу за ${fetchingLabel} ${from}, то вона може бути не конвертованою і не поверненою.";
@override
String commit_transaction_amount_fee(String amount, String fee) => "Підтвердити транзакцію \nСума: ${amount}\nКомісія: ${fee}";
@override
@ -5716,7 +5716,7 @@ class $ja extends S {
@override
String error_text_limits_loading_failed(String provider) => "${provider} の取引は作成されません。 制限の読み込みに失敗しました";
@override
String exchange_result_description(String fetchingLabel, String from) => "送信してください ${fetchingLabel} ${from} 次のページに表示されているアドレスに.";
String exchange_result_description(String fetchingLabel, String from) => "次のページに示されているアドレスに最低 ${fetchingLabel} ${from} を送信する必要があります。 ${fetchingLabel} ${from} 未満の金額を送信すると、変換されず、返金されない場合があります。";
@override
String commit_transaction_amount_fee(String amount, String fee) => "トランザクションをコミット\n量: ${amount}\n費用: ${fee}";
@override
@ -6484,7 +6484,7 @@ class $pl extends S {
@override
String error_text_limits_loading_failed(String provider) => "Wymiana dla ${provider} nie została utworzona. Ładowanie limitów nie powiodło się";
@override
String exchange_result_description(String fetchingLabel, String from) => "Proszę wyślij ${fetchingLabel} ${from} pod adres podany na następnej stronie.";
String exchange_result_description(String fetchingLabel, String from) => "Musisz wysłać co najmniej ${fetchingLabel} ${from} na adres podany na następnej stronie. Jeśli wyślesz kwotę niższą niż ${fetchingLabel} ${from}, może ona nie zostać przeliczona i może nie zostać zwrócona.";
@override
String commit_transaction_amount_fee(String amount, String fee) => "Zatwierdź transakcję\nIlość: ${amount}\nOpłata: ${fee}";
@override
@ -7248,7 +7248,7 @@ class $es extends S {
@override
String error_text_limits_loading_failed(String provider) => "El comercio por ${provider} no se crea. Límites de carga fallidos";
@override
String exchange_result_description(String fetchingLabel, String from) => "Envíe ${fetchingLabel} ${from} a la dirección que se muestra en la página siguiente.";
String exchange_result_description(String fetchingLabel, String from) => "Debe enviar un mínimo de ${fetchingLabel} ${from} a la dirección que se muestra en la página siguiente. Si envía una cantidad inferior a ${fetchingLabel} ${from}, es posible que no se convierta y no se reembolse.";
@override
String commit_transaction_amount_fee(String amount, String fee) => "Confirmar transacción\nCantidad: ${amount}\nCuota: ${fee}";
@override
@ -8012,7 +8012,7 @@ class $nl extends S {
@override
String error_text_limits_loading_failed(String provider) => "Ruil voor ${provider} is niet gemaakt. Beperkingen laden mislukt";
@override
String exchange_result_description(String fetchingLabel, String from) => "Zend alstublieft ${fetchingLabel} ${from} naar het adres op de volgende pagina.";
String exchange_result_description(String fetchingLabel, String from) => "U moet minimaal ${fetchingLabel} ${from} verzenden naar het adres dat op de volgende pagina wordt weergegeven. Als u een bedrag verzendt dat lager is dan ${fetchingLabel} ${from}, wordt het mogelijk niet omgezet en wordt het mogelijk niet terugbetaald.";
@override
String commit_transaction_amount_fee(String amount, String fee) => "Verricht transactie\nBedrag: ${amount}\nhonorarium: ${fee}";
@override
@ -8776,7 +8776,7 @@ class $zh extends S {
@override
String error_text_limits_loading_failed(String provider) => "未創建 ${provider} 交易。 限制加載失敗";
@override
String exchange_result_description(String fetchingLabel, String from) => "请发${fetchingLabel} ${from} 到下一頁顯示的地址.";
String exchange_result_description(String fetchingLabel, String from) => "您必須至少發${fetchingLabel} ${from} 到下一頁上顯示的地址。 如果您發送的金額少於 ${fetchingLabel} ${from},則可能無法轉換,因此無法退還。";
@override
String commit_transaction_amount_fee(String amount, String fee) => "提交交易\n量: ${amount}\nFee: ${fee}";
@override

@ -1,3 +1,4 @@
import 'package:cake_wallet/entities/order.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:hive/hive.dart';
@ -69,11 +70,17 @@ Future<void> main() async {
Hive.registerAdapter(ExchangeTemplateAdapter());
}
if (!Hive.isAdapterRegistered(Order.typeId)) {
Hive.registerAdapter(OrderAdapter());
}
final secureStorage = FlutterSecureStorage();
final transactionDescriptionsBoxKey = await getEncryptionKey(
secureStorage: secureStorage, forKey: TransactionDescription.boxKey);
final tradesBoxKey = await getEncryptionKey(
secureStorage: secureStorage, forKey: Trade.boxKey);
final ordersBoxKey = await getEncryptionKey(
secureStorage: secureStorage, forKey: Order.boxKey);
final contacts = await Hive.openBox<Contact>(Contact.boxName);
final nodes = await Hive.openBox<Node>(Node.boxName);
final transactionDescriptions = await Hive.openBox<TransactionDescription>(
@ -81,6 +88,8 @@ Future<void> main() async {
encryptionKey: transactionDescriptionsBoxKey);
final trades =
await Hive.openBox<Trade>(Trade.boxName, encryptionKey: tradesBoxKey);
final orders =
await Hive.openBox<Order>(Order.boxName, encryptionKey: ordersBoxKey);
final walletInfoSource = await Hive.openBox<WalletInfo>(WalletInfo.boxName);
final templates = await Hive.openBox<Template>(Template.boxName);
final exchangeTemplates =
@ -91,6 +100,7 @@ Future<void> main() async {
walletInfoSource: walletInfoSource,
contactSource: contacts,
tradesSource: trades,
ordersSource: orders,
// fiatConvertationService: fiatConvertationService,
templates: templates,
exchangeTemplates: exchangeTemplates,
@ -118,6 +128,7 @@ Future<void> initialSetup(
@required Box<WalletInfo> walletInfoSource,
@required Box<Contact> contactSource,
@required Box<Trade> tradesSource,
@required Box<Order> ordersSource,
// @required FiatConvertationService fiatConvertationService,
@required Box<Template> templates,
@required Box<ExchangeTemplate> exchangeTemplates,
@ -139,7 +150,8 @@ Future<void> initialSetup(
tradesSource: tradesSource,
templates: templates,
exchangeTemplates: exchangeTemplates,
transactionDescriptionBox: transactionDescriptions);
transactionDescriptionBox: transactionDescriptions,
ordersSource: ordersSource);
await bootstrap(navigatorKey);
monero_wallet.onStartup();
}

@ -1,12 +1,15 @@
import 'package:cake_wallet/entities/contact_record.dart';
import 'package:cake_wallet/entities/order.dart';
import 'package:cake_wallet/entities/transaction_description.dart';
import 'package:cake_wallet/src/screens/backup/backup_page.dart';
import 'package:cake_wallet/src/screens/backup/edit_backup_password_page.dart';
import 'package:cake_wallet/src/screens/order_details/order_details_page.dart';
import 'package:cake_wallet/src/screens/pin_code/pin_code_widget.dart';
import 'package:cake_wallet/src/screens/restore/restore_from_backup_page.dart';
import 'package:cake_wallet/src/screens/restore/wallet_restore_page.dart';
import 'package:cake_wallet/src/screens/seed/pre_seed_page.dart';
import 'package:cake_wallet/src/screens/support/support_page.dart';
import 'package:cake_wallet/src/screens/wyre/wyre_page.dart';
import 'package:cake_wallet/store/settings_store.dart';
import 'package:cake_wallet/view_model/monero_account_list/account_list_item.dart';
import 'package:flutter/cupertino.dart';
@ -285,6 +288,16 @@ Route<dynamic> createRoute(RouteSettings settings) {
builder: (_) =>
getIt.get<TradeDetailsPage>(param1: settings.arguments as Trade));
case Routes.orderDetails:
return MaterialPageRoute<void>(
builder: (_) =>
getIt.get<OrderDetailsPage>(param1: settings.arguments as Order));
case Routes.wyre:
return MaterialPageRoute<void>(
builder: (_) =>
getIt.get<WyrePage>(param1: settings.arguments as String));
case Routes.restoreWalletFromSeedDetails:
final args = settings.arguments as List;
final walletRestorationFromSeedVM =

@ -52,4 +52,6 @@ class Routes {
static const editBackupPassword = '/edit_backup_passowrd';
static const restoreFromBackup = '/restore_from_backup';
static const support = '/support';
static const orderDetails = '/order_details';
static const wyre = '/wyre';
}

@ -1,3 +1,4 @@
import 'package:cake_wallet/entities/wallet_type.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/themes/theme_base.dart';
@ -12,7 +13,9 @@ import 'package:cake_wallet/src/screens/dashboard/widgets/address_page.dart';
import 'package:cake_wallet/src/screens/dashboard/widgets/transactions_page.dart';
import 'package:cake_wallet/src/screens/dashboard/widgets/sync_indicator.dart';
import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_view_model.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:smooth_page_indicator/smooth_page_indicator.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
class DashboardPage extends BasePage {
DashboardPage({
@ -81,7 +84,7 @@ class DashboardPage extends BasePage {
final exchangeImage = Image.asset('assets/images/transfer.png',
height: 24.27, width: 22.25,
color: Theme.of(context).accentTextTheme.display3.backgroundColor);
final receiveImage = Image.asset('assets/images/download.png',
final buyImage = Image.asset('assets/images/coins.png',
height: 22.24, width: 24,
color: Theme.of(context).accentTextTheme.display3.backgroundColor);
_setEffects();
@ -111,7 +114,7 @@ class DashboardPage extends BasePage {
)),
Container(
padding: EdgeInsets.only(left: 45, right: 45, bottom: 24),
child: Row(
child: Observer(builder: (_) => Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
ActionButton(
@ -122,8 +125,41 @@ class DashboardPage extends BasePage {
image: exchangeImage,
title: S.of(context).exchange,
route: Routes.exchange),
if (walletViewModel.type == WalletType.bitcoin) Observer(
builder: (_) => Stack(
clipBehavior: Clip.none,
alignment: Alignment.topCenter,
children: [
if (walletViewModel.isRunningWebView) Positioned(
top: -5,
child: SpinKitRing(
color: Theme.of(context).buttonColor,
lineWidth: 3,
size: 70.0,
),
),
ActionButton(
image: buyImage,
title: S.of(context).buy,
onClick: walletViewModel.isRunningWebView
? null
: () async {
try {
walletViewModel.isRunningWebView = true;
final url =
await walletViewModel.wyreViewModel.wyreUrl;
await Navigator.of(context)
.pushNamed(Routes.wyre, arguments: url);
walletViewModel.isRunningWebView = false;
} catch(e) {
print(e.toString());
walletViewModel.isRunningWebView = false;
}
})
],
)),
],
),
)),
)
],
));

@ -3,14 +3,16 @@ import 'package:flutter/material.dart';
class ActionButton extends StatelessWidget {
ActionButton(
{@required this.image,
@required this.title,
@required this.route,
this.alignment = Alignment.center});
@required this.title,
this.route,
this.onClick,
this.alignment = Alignment.center});
final Image image;
final String title;
final String route;
final Alignment alignment;
final void Function() onClick;
@override
Widget build(BuildContext context) {
@ -23,8 +25,10 @@ class ActionButton extends StatelessWidget {
children: <Widget>[
GestureDetector(
onTap: () {
if (route.isNotEmpty) {
if (route?.isNotEmpty ?? false) {
Navigator.of(context, rootNavigator: true).pushNamed(route);
} else {
onClick?.call();
}
},
child: Container(
@ -48,4 +52,4 @@ class ActionButton extends StatelessWidget {
),
);
}
}
}

@ -0,0 +1,72 @@
import 'package:flutter/material.dart';
class OrderRow extends StatelessWidget {
OrderRow({
@required this.onTap,
this.from,
this.to,
this.createdAtFormattedDate,
this.formattedAmount});
final VoidCallback onTap;
final String from;
final String to;
final String createdAtFormattedDate;
final String formattedAmount;
final wyreImage =
Image.asset('assets/images/wyre-icon.png', width: 36, height: 36);
@override
Widget build(BuildContext context) {
return InkWell(
onTap: onTap,
child: Container(
padding: EdgeInsets.fromLTRB(24, 8, 24, 8),
color: Colors.transparent,
child: Row(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
wyreImage,
SizedBox(width: 12),
Expanded(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text('$from$to',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Theme.of(context).accentTextTheme.
display3.backgroundColor
)),
formattedAmount != null
? Text(formattedAmount + ' ' + to,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Theme.of(context).accentTextTheme.
display3.backgroundColor
))
: Container()
]),
SizedBox(height: 5),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(createdAtFormattedDate,
style: TextStyle(
fontSize: 14,
color: Theme.of(context).textTheme
.overline.backgroundColor))
])
],
)
)
],
),
));
}
}

@ -1,3 +1,5 @@
import 'package:cake_wallet/src/screens/dashboard/widgets/order_row.dart';
import 'package:cake_wallet/view_model/dashboard/order_list_item.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
@ -75,6 +77,21 @@ class TransactionsPage extends StatelessWidget {
);
}
if (item is OrderListItem) {
final order = item.order;
return OrderRow(
onTap: () => Navigator.of(context).pushNamed(
Routes.orderDetails,
arguments: order),
from: order.from,
to: order.to,
createdAtFormattedDate:
DateFormat('HH:mm').format(order.createdAt),
formattedAmount: item.orderFormattedAmount,
);
}
return Container(
color: Colors.transparent,
height: 1);

@ -272,7 +272,7 @@ class ExchangePage extends BasePage {
],
),
),
if (exchangeViewModel.isReceiveAmountEditable) Padding(
/*if (exchangeViewModel.isReceiveAmountEditable) Padding(
padding: EdgeInsets.only(top: 12, left: 24),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
@ -286,7 +286,7 @@ class ExchangePage extends BasePage {
),
],
)
),
),*/
Padding(
padding: EdgeInsets.only(top: 30, left: 24, bottom: 24),
child: Row(

@ -0,0 +1,47 @@
import 'package:cake_wallet/src/widgets/standard_list.dart';
import 'package:cake_wallet/utils/show_bar.dart';
import 'package:cake_wallet/view_model/order_details_view_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/services.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/widgets/standart_list_row.dart';
import 'package:cake_wallet/src/screens/trade_details/track_trade_list_item.dart';
class OrderDetailsPage extends BasePage {
OrderDetailsPage(this.orderDetailsViewModel);
@override
String get title => 'Order Details';
final OrderDetailsViewModel orderDetailsViewModel;
@override
Widget body(BuildContext context) {
return Observer(builder: (_) {
return SectionStandardList(
sectionCount: 1,
itemCounter: (int _) => orderDetailsViewModel.items.length,
itemBuilder: (_, __, index) {
final item = orderDetailsViewModel.items[index];
if (item is TrackTradeListItem) {
return GestureDetector(
onTap: item.onTap,
child: StandartListRow(
title: '${item.title}', value: '${item.value}'));
} else {
return GestureDetector(
onTap: () {
Clipboard.setData(ClipboardData(text: '${item.value}'));
showBar<void>(context, S.of(context).copied_to_clipboard);
},
child: StandartListRow(
title: '${item.title}', value: '${item.value}'));
}
});
});
}
}

@ -0,0 +1,97 @@
import 'dart:async';
import 'dart:io';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/palette.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/store/dashboard/orders_store.dart';
import 'package:cake_wallet/view_model/wyre_view_model.dart';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
class WyrePage extends BasePage {
WyrePage(this.wyreViewModel,
{@required this.ordersStore, @required this.url});
final OrdersStore ordersStore;
final String url;
final WyreViewModel wyreViewModel;
@override
String get title => S.current.buy;
@override
Color get backgroundDarkColor => Colors.white;
@override
Color get titleColor => Palette.darkBlueCraiola;
@override
Widget body(BuildContext context) =>
WyrePageBody(wyreViewModel, ordersStore: ordersStore, url: url);
}
class WyrePageBody extends StatefulWidget {
WyrePageBody(this.wyreViewModel, {this.ordersStore, this.url});
final OrdersStore ordersStore;
final String url;
final WyreViewModel wyreViewModel;
@override
WyrePageBodyState createState() => WyrePageBodyState();
}
class WyrePageBodyState extends State<WyrePageBody> {
String orderId;
WebViewController _webViewController;
GlobalKey _webViewkey;
Timer _timer;
bool _isSaving;
@override
void initState() {
super.initState();
_webViewkey = GlobalKey();
_isSaving = false;
widget.ordersStore.orderId = '';
if (Platform.isAndroid) WebView.platform = SurfaceAndroidWebView();
_timer?.cancel();
_timer = Timer.periodic(Duration(seconds: 1), (timer) async {
try {
if (_webViewController == null || _isSaving) {
return;
}
final url = await _webViewController.currentUrl();
if (url.contains('completed')) {
final urlParts = url.split('/');
orderId = urlParts.last;
widget.ordersStore.orderId = orderId;
if (orderId.isNotEmpty) {
_isSaving = true;
await widget.wyreViewModel.saveOrder(orderId);
timer.cancel();
}
}
} catch (e) {
_isSaving = false;
print(e);
}
});
}
@override
Widget build(BuildContext context) {
return WebView(
key: _webViewkey,
initialUrl: widget.url,
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController controller) =>
setState(() => _webViewController = controller));
}
}

@ -0,0 +1,45 @@
import 'dart:async';
import 'package:cake_wallet/entities/order.dart';
import 'package:cake_wallet/view_model/dashboard/order_list_item.dart';
import 'package:hive/hive.dart';
import 'package:mobx/mobx.dart';
import 'package:cake_wallet/store/settings_store.dart';
part 'orders_store.g.dart';
class OrdersStore = OrdersStoreBase with _$OrdersStore;
abstract class OrdersStoreBase with Store {
OrdersStoreBase({this.ordersSource, this.settingsStore}) {
orders = <OrderListItem>[];
orderId = '';
_onOrdersChanged =
ordersSource.watch().listen((_) async => await updateOrderList());
updateOrderList();
}
Box<Order> ordersSource;
StreamSubscription<BoxEvent> _onOrdersChanged;
SettingsStore settingsStore;
@observable
List<OrderListItem> orders;
@observable
Order order;
@observable
String orderId;
@action
void setOrder(Order order) => this.order = order;
@action
Future updateOrderList() async => orders =
ordersSource.values.map((order) => OrderListItem(
order: order,
displayMode: settingsStore.balanceDisplayMode)).toList();
}

@ -1,7 +1,12 @@
import 'dart:convert';
import 'dart:io';
import 'package:cake_wallet/bitcoin/bitcoin_transaction_info.dart';
import 'package:cake_wallet/bitcoin/bitcoin_wallet.dart';
import 'package:cake_wallet/entities/balance.dart';
import 'package:cake_wallet/entities/order.dart';
import 'package:cake_wallet/entities/transaction_history.dart';
import 'package:cake_wallet/exchange/trade_state.dart';
import 'package:cake_wallet/monero/account.dart';
import 'package:cake_wallet/monero/monero_balance.dart';
import 'package:cake_wallet/monero/monero_transaction_history.dart';
@ -14,13 +19,20 @@ import 'package:cake_wallet/entities/transaction_info.dart';
import 'package:cake_wallet/exchange/exchange_provider_description.dart';
import 'package:cake_wallet/exchange/trade.dart';
import 'package:cake_wallet/store/settings_store.dart';
import 'package:cake_wallet/store/dashboard/orders_store.dart';
import 'package:cake_wallet/utils/mobx.dart';
import 'package:cake_wallet/view_model/dashboard/balance_view_model.dart';
import 'package:cake_wallet/view_model/dashboard/filter_item.dart';
import 'package:cake_wallet/view_model/dashboard/order_list_item.dart';
import 'package:cake_wallet/view_model/dashboard/trade_list_item.dart';
import 'package:cake_wallet/view_model/dashboard/transaction_list_item.dart';
import 'package:cake_wallet/view_model/dashboard/action_list_item.dart';
import 'package:cake_wallet/view_model/dashboard/action_list_display_mode.dart';
import 'package:cake_wallet/view_model/wyre_view_model.dart';
import 'package:crypto/crypto.dart';
import 'package:flutter/services.dart';
import 'package:hive/hive.dart';
import 'package:http/http.dart';
import 'package:mobx/mobx.dart';
import 'package:cake_wallet/core/wallet_base.dart';
import 'package:cake_wallet/entities/sync_status.dart';
@ -31,6 +43,8 @@ import 'package:cake_wallet/store/dashboard/trades_store.dart';
import 'package:cake_wallet/store/dashboard/trade_filter_store.dart';
import 'package:cake_wallet/store/dashboard/transaction_filter_store.dart';
import 'package:cake_wallet/view_model/dashboard/formatted_item_list.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:convert/convert.dart';
part 'dashboard_view_model.g.dart';
@ -43,7 +57,10 @@ abstract class DashboardViewModelBase with Store {
this.tradesStore,
this.tradeFilterStore,
this.transactionFilterStore,
this.settingsStore}) {
this.settingsStore,
this.ordersSource,
this.ordersStore,
this.wyreViewModel}) {
filterItems = {
S.current.transactions: [
FilterItem(
@ -78,6 +95,8 @@ abstract class DashboardViewModelBase with Store {
]
};
isRunningWebView = false;
name = appStore.wallet?.name;
wallet ??= appStore.wallet;
type = wallet.type;
@ -143,6 +162,9 @@ abstract class DashboardViewModelBase with Store {
@observable
String subname;
@observable
bool isRunningWebView;
@computed
String get address => wallet.address;
@ -173,6 +195,11 @@ abstract class DashboardViewModelBase with Store {
.where((trade) => trade.trade.walletId == wallet.id)
.toList();
@computed
List<OrderListItem> get orders => ordersStore.orders
.where((item) => item.order.walletId == wallet.id)
.toList();
@computed
double get price => balanceViewModel.price;
@ -182,6 +209,7 @@ abstract class DashboardViewModelBase with Store {
_items.addAll(transactionFilterStore.filtered(transactions: transactions));
_items.addAll(tradeFilterStore.filtered(trades: trades, wallet: wallet));
_items.addAll(orders);
return formattedItemsList(_items);
}
@ -191,6 +219,8 @@ abstract class DashboardViewModelBase with Store {
bool get hasRescan => wallet.type == WalletType.monero;
Box<Order> ordersSource;
BalanceViewModel balanceViewModel;
AppStore appStore;
@ -199,10 +229,14 @@ abstract class DashboardViewModelBase with Store {
TradesStore tradesStore;
OrdersStore ordersStore;
TradeFilterStore tradeFilterStore;
TransactionFilterStore transactionFilterStore;
WyreViewModel wyreViewModel;
Map<String, List<FilterItem>> filterItems;
bool get isBuyEnabled => settingsStore.isBitcoinBuyEnabled;
@ -285,4 +319,6 @@ abstract class DashboardViewModelBase with Store {
balanceViewModel: balanceViewModel,
settingsStore: appStore.settingsStore)));
}
}

@ -0,0 +1,21 @@
import 'package:cake_wallet/entities/order.dart';
import 'package:cake_wallet/view_model/dashboard/action_list_item.dart';
import 'package:cake_wallet/entities/balance_display_mode.dart';
class OrderListItem extends ActionListItem {
OrderListItem({this.order, this.displayMode});
final Order order;
final BalanceDisplayMode displayMode;
String get orderFormattedAmount {
return order.amount != null
? displayMode == BalanceDisplayMode.hiddenBalance
? '---'
: order.amountFormatted()
: order.amount;
}
@override
DateTime get date => order.createdAt;
}

@ -405,12 +405,13 @@ abstract class ExchangeViewModelBase with Store {
}
void _defineIsReceiveAmountEditable() {
if ((provider is ChangeNowExchangeProvider)
/*if ((provider is ChangeNowExchangeProvider)
&&(depositCurrency == CryptoCurrency.xmr)
&&(receiveCurrency == CryptoCurrency.btc)) {
isReceiveAmountEditable = true;
} else {
isReceiveAmountEditable = false;
}
}*/
isReceiveAmountEditable = false;
}
}

@ -0,0 +1,85 @@
import 'dart:async';
import 'package:cake_wallet/entities/order.dart';
import 'package:cake_wallet/utils/date_formatter.dart';
import 'package:cake_wallet/view_model/wyre_view_model.dart';
import 'package:mobx/mobx.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/screens/transaction_details/standart_list_item.dart';
import 'package:cake_wallet/src/screens/trade_details/track_trade_list_item.dart';
import 'package:url_launcher/url_launcher.dart';
part 'order_details_view_model.g.dart';
class OrderDetailsViewModel = OrderDetailsViewModelBase
with _$OrderDetailsViewModel;
abstract class OrderDetailsViewModelBase with Store {
OrderDetailsViewModelBase({this.wyreViewModel, Order orderForDetails}) {
order = orderForDetails;
items = ObservableList<StandartListItem>();
_updateItems();
_updateOrder();
_timer = Timer.periodic(Duration(seconds: 20), (_) async => _updateOrder());
}
@observable
Order order;
@observable
ObservableList<StandartListItem> items;
WyreViewModel wyreViewModel;
Timer _timer;
@action
Future<void> _updateOrder() async {
try {
final updatedOrder =
await wyreViewModel.wyreService.findOrderById(order.id);
updatedOrder.receiveAddress = order.receiveAddress;
updatedOrder.walletId = order.walletId;
order = updatedOrder;
_updateItems();
} catch (e) {
print(e.toString());
}
}
void _updateItems() {
final dateFormat = DateFormatter.withCurrentLocal();
final buildURL =
wyreViewModel.trackUrl + '${order.transferId}';
items?.clear();
items.addAll([
StandartListItem(
title: 'Transfer ID',
value: order.transferId),
StandartListItem(
title: S.current.trade_details_state,
value: order.state != null
? order.state.toString()
: S.current.trade_details_fetching),
TrackTradeListItem(
title: 'Track',
value: buildURL,
onTap: () {
launch(buildURL);
}),
StandartListItem(
title: S.current.trade_details_created_at,
value: dateFormat.format(order.createdAt).toString()),
StandartListItem(
title: S.current.trade_details_pair,
value: '${order.from}${order.to}')
]);
}
}

@ -0,0 +1,42 @@
import 'package:cake_wallet/entities/wyre_service.dart';
import 'package:flutter/foundation.dart';
import 'package:hive/hive.dart';
import 'package:cake_wallet/entities/order.dart';
import 'package:cake_wallet/entities/wallet_type.dart';
import 'package:cake_wallet/store/dashboard/orders_store.dart';
import 'package:mobx/mobx.dart';
part 'wyre_view_model.g.dart';
class WyreViewModel = WyreViewModelBase with _$WyreViewModel;
abstract class WyreViewModelBase with Store {
WyreViewModelBase(this.ordersSource, this.ordersStore,
{@required this.walletId, @required this.address, @required this.type,
@required this.wyreService});
Future<String> get wyreUrl => wyreService.getWyreUrl();
String get trackUrl => wyreService.trackUrl;
final Box<Order> ordersSource;
final OrdersStore ordersStore;
final String walletId;
final WalletType type;
final String address;
final WyreService wyreService;
Future<void> saveOrder(String orderId) async {
try {
final order = await wyreService.findOrderById(orderId);
order.receiveAddress = address;
order.walletId = walletId;
await ordersSource.add(order);
ordersStore.setOrder(order);
} catch (e) {
print(e.toString());
}
}
}

@ -55,6 +55,8 @@ dependencies:
auto_size_text: ^2.1.0
dotted_border: ^1.0.5
smooth_page_indicator: ^0.2.0
webview_flutter: ^1.0.7
flutter_spinkit: ^4.1.2
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.

@ -89,7 +89,7 @@
"trade_is_powered_by" : "Dieser Handel wird betrieben von ${provider}",
"copy_address" : "Adresse kopieren",
"exchange_result_confirm" : "Durch Drücken von Bestätigen wird gesendet ${fetchingLabel} ${from} von Ihrer Brieftasche aus angerufen ${walletName} an die unten angegebene Adresse. Oder Sie können von Ihrem externen Portemonnaie an die unten angegebene Adresse / QR-Code senden.\n\nBitte bestätigen Sie, um fortzufahren, oder gehen Sie zurück, um die Beträge zu änderns.",
"exchange_result_description" : "Bitte senden ${fetchingLabel} ${from} an die auf der nächsten Seite angegebene Adresse.'",
"exchange_result_description" : "Sie müssen mindestens ${fetchingLabel} ${from} an die auf der nächsten Seite angegebene Adresse senden. Wenn Sie einen Betrag unter ${fetchingLabel} ${from} senden, wird dieser möglicherweise nicht konvertiert und möglicherweise nicht erstattet.",
"exchange_result_write_down_ID" : "*Bitte kopieren oder notieren Sie Ihren oben gezeigten Ausweis.",
"confirm" : "Bestätigen",
"confirm_sending" : "Bestätigen Sie das Senden",

@ -89,7 +89,7 @@
"trade_is_powered_by" : "This trade is powered by ${provider}",
"copy_address" : "Copy Address",
"exchange_result_confirm" : "By pressing confirm, you will be sending ${fetchingLabel} ${from} from your wallet called ${walletName} to the address shown below. Or you can send from your external wallet to the below address/QR code.\n\nPlease press confirm to continue or go back to change the amounts.",
"exchange_result_description" : "Please send ${fetchingLabel} ${from} to the address shown on the next page.",
"exchange_result_description" : "You must send a minimum of ${fetchingLabel} ${from} to the address shown on the next page. If you send an amount lower than ${fetchingLabel} ${from} it may not get converted and it may not be refunded.",
"exchange_result_write_down_ID" : "*Please copy or write down your ID shown above.",
"confirm" : "Confirm",
"confirm_sending" : "Confirm sending",

@ -89,7 +89,7 @@
"trade_is_powered_by" : "Este comercio es impulsado por ${provider}",
"copy_address" : "Copiar dirección ",
"exchange_result_confirm" : "Al presionar confirmar, enviará ${fetchingLabel} ${from} desde su billetera llamada ${walletName} a la dirección que se muestra a continuación. O puede enviar desde su billetera externa a la siguiente dirección / código QR anterior.\n\nPresione confirmar para continuar o regrese para cambiar los montos.",
"exchange_result_description" : "Envíe ${fetchingLabel} ${from} a la dirección que se muestra en la página siguiente.",
"exchange_result_description" : "Debe enviar un mínimo de ${fetchingLabel} ${from} a la dirección que se muestra en la página siguiente. Si envía una cantidad inferior a ${fetchingLabel} ${from}, es posible que no se convierta y no se reembolse.",
"exchange_result_write_down_ID" : "*Copie o escriba su identificación que se muestra arriba.",
"confirm" : "Confirmar",
"confirm_sending" : "Confirmar envío",

@ -89,7 +89,7 @@
"trade_is_powered_by" : "यह व्यापार द्वारा संचालित है ${provider}",
"copy_address" : "पता कॉपी करें",
"exchange_result_confirm" : "पुष्टि दबाकर, आप भेज रहे होंगे ${fetchingLabel} ${from} अपने बटुए से ${walletName} नीचे दिखाए गए पते पर। या आप अपने बाहरी वॉलेट से नीचे के पते पर भेज सकते हैं / क्यूआर कोड पर भेज सकते हैं।\n\nकृपया जारी रखने या राशि बदलने के लिए वापस जाने के लिए पुष्टि करें दबाएं.",
"exchange_result_description" : "कृपया भेजें ${fetchingLabel} ${from} अगले पृष्ठ पर दिखाए गए पते पर",
"exchange_result_description" : "आपको अगले पृष्ठ पर दिखाए गए पते पर न्यूनतम ${fetchingLabel} ${from} भेजना होगा। यदि आप ${fetchingLabel} ${from} से कम राशि भेजते हैं तो यह परिवर्तित नहीं हो सकती है और इसे वापस नहीं किया जा सकता है।",
"exchange_result_write_down_ID" : "*कृपया ऊपर दिखाए गए अपने ID को कॉपी या लिख लें.",
"confirm" : "की पुष्टि करें",
"confirm_sending" : "भेजने की पुष्टि करें",

@ -89,7 +89,7 @@
"trade_is_powered_by" : "この取引は ${provider}",
"copy_address" : "住所をコピー",
"exchange_result_confirm" : "確認を押すと、送信されます ${fetchingLabel} ${from} と呼ばれるあなたの財布から ${walletName} 下記の住所へ。 または、外部ウォレットから以下のアドレスに送信することもできます/ QRコードに送信できます.\n\n確認を押して続行するか、戻って金額を変更してください.",
"exchange_result_description" : "送信してください ${fetchingLabel} ${from} 次のページに表示されているアドレスに.",
"exchange_result_description" : 次のページに示されているアドレスに最低 ${fetchingLabel} ${from} を送信する必要があります。 ${fetchingLabel} ${from} 未満の金額を送信すると、変換されず、返金されない場合があります。",
"exchange_result_write_down_ID" : "*上記のIDをコピーまたは書き留めてください.",
"confirm" : "確認する",
"confirm_sending" : "送信を確認",

@ -89,7 +89,7 @@
"trade_is_powered_by" : "이 거래는 ${provider}",
"copy_address" : "주소 복사",
"exchange_result_confirm" : "확인을 누르면 전송됩니다 ${fetchingLabel} ${from} 지갑에서 ${walletName} 아래 주소로. 또는 외부 지갑에서 아래 주소로 보낼 수 있습니다 / QR 코드로 보낼 수 있습니다.\n\n확인을 눌러 계속하거나 금액을 변경하려면 돌아가십시오.",
"exchange_result_description" : "보내주세요 ${fetchingLabel} ${from} 다음 페이지에 표시된 주소로.",
"exchange_result_description" : "다음 페이지에 표시된 주소로 최소 ${fetchingLabel} ${from} 를 보내야합니다. ${fetchingLabel} ${from} 보다 적은 금액을 보내면 변환되지 않고 환불되지 않을 수 있습니다.",
"exchange_result_write_down_ID" : "*위에 표시된 ID를 복사하거나 적어 두십시오.",
"confirm" : "확인",
"confirm_sending" : "전송 확인",

@ -89,7 +89,7 @@
"trade_is_powered_by" : "Deze transactie wordt mogelijk gemaakt door ${provider}",
"copy_address" : "Adres kopiëren",
"exchange_result_confirm" : "Door op bevestigen te drukken, wordt u verzonden ${fetchingLabel} ${from} uit je portemonnee genoemd ${walletName} naar het onderstaande adres. Of u kunt vanuit uw externe portemonnee naar het onderstaande adres verzenden / QR-code sturen.\n\nDruk op bevestigen om door te gaan of terug te gaan om de bedragen te wijzigen.",
"exchange_result_description" : "Zend alstublieft ${fetchingLabel} ${from} naar het adres op de volgende pagina.",
"exchange_result_description" : "U moet minimaal ${fetchingLabel} ${from} verzenden naar het adres dat op de volgende pagina wordt weergegeven. Als u een bedrag verzendt dat lager is dan ${fetchingLabel} ${from}, wordt het mogelijk niet omgezet en wordt het mogelijk niet terugbetaald.",
"exchange_result_write_down_ID" : "*Kopieer of noteer uw hierboven getoonde ID.",
"confirm" : "Bevestigen",
"confirm_sending" : "Bevestig verzending",

@ -89,7 +89,7 @@
"trade_is_powered_by" : "Ten handel jest zasilany przez ${provider}",
"copy_address" : "Skopiuj adress",
"exchange_result_confirm" : "Naciskając Potwierdź, wyślesz ${fetchingLabel} ${from} z twojego portfela ${walletName} na adres podany poniżej. Lub możesz wysłać z zewnętrznego portfela na poniższy adres / kod QR.\n\nNaciśnij Potwierdź, aby kontynuować lub wróć, aby zmienić kwoty.",
"exchange_result_description" : "Proszę wyślij ${fetchingLabel} ${from} pod adres podany na następnej stronie.",
"exchange_result_description" : "Musisz wysłać co najmniej ${fetchingLabel} ${from} na adres podany na następnej stronie. Jeśli wyślesz kwotę niższą niż ${fetchingLabel} ${from}, może ona nie zostać przeliczona i może nie zostać zwrócona.",
"exchange_result_write_down_ID" : "*Skopiuj lub zanotuj swój identyfikator pokazany powyżej.",
"confirm" : "Potwierdzać",
"confirm_sending" : "Potwierdź wysłanie",

@ -89,7 +89,7 @@
"trade_is_powered_by" : "Troca realizada por ${provider}",
"copy_address" : "Copiar endereço",
"exchange_result_confirm" : "Ao confirmar, você enviará ${fetchingLabel} ${from} da sua carteira ${walletName} para o endereço mostrado abaixo. Ou você pode enviar de sua carteira externa para o endereço abaixo/código QR acima.\n\nPressione Confirmar para continuar ou volte para alterar os valores.",
"exchange_result_description" : "Por favor, envie ${fetchingLabel} ${from} para o endereço mostrado na próxima página.",
"exchange_result_description" : "Você deve enviar no mínimo ${fetchingLabel} ${from} para o endereço mostrado na próxima página. Se você enviar um valor inferior a ${fetchingLabel} ${from}, ele pode não ser convertido e pode não ser reembolsado.",
"exchange_result_write_down_ID" : "*Copie ou anote seu ID mostrado acima.",
"confirm" : "Confirmar",
"confirm_sending" : "Confirmar o envio",

@ -89,7 +89,7 @@
"trade_is_powered_by" : "Сделка выполнена через ${provider}",
"copy_address" : "Cкопировать адрес",
"exchange_result_confirm" : "Нажимая подтвердить, вы отправите ${fetchingLabel} ${from} с вашего кошелька ${walletName} на адрес указанный ниже. Или вы можете отправить со своего внешнего кошелька на нижеуказанный адрес/QR-код.\n\nПожалуйста, нажмите подтвердить для продолжения, или вернитесь назад для изменения суммы.",
"exchange_result_description" : "Пожалуйста отправьте ${fetchingLabel} ${from} на адрес, указанный на следующей странице.",
"exchange_result_description" : "Вы должны отправить минимум ${fetchingLabel} ${from} на адрес, указанный на следующей странице. Если вы отправите сумму менее ${fetchingLabel} ${from}, то она может быть не конвертирована и не возвращена.",
"exchange_result_write_down_ID" : "*Пожалуйста, скопируйте или запишите ID, указанный выше.",
"confirm" : "Подтвердить",
"confirm_sending" : "Подтвердить отправку",

@ -89,7 +89,7 @@
"trade_is_powered_by" : "Операція виконана через ${provider}",
"copy_address" : "Cкопіювати адресу",
"exchange_result_confirm" : "Натиснувши підтвердити, ви відправите ${fetchingLabel} ${from} з вашого гаманця ${walletName} на адресу вказану нижче. Або ви можете відправити зі свого зовнішнього гаманця на нижчевказану адресу/QR-код.\n\nБудь ласка, натисніть підтвердити для продовження або поверніться назад щоб змінити суму.",
"exchange_result_description" : "Будь ласка, відправте ${fetchingLabel} ${from} на адресу, вказану на наступній сторінці.",
"exchange_result_description" : "Ви повинні надіслати мінімум ${fetchingLabel} ${from} на адресу, вказану на наступній сторінці. Якщо ви надішлете суму меншу за ${fetchingLabel} ${from}, то вона може бути не конвертованою і не поверненою.",
"exchange_result_write_down_ID" : "*Будь ласка, скопіюйте або запишіть ID, вказаний вище.",
"confirm" : "Підтвердити",
"confirm_sending" : "Підтвердити відправлення",

@ -89,7 +89,7 @@
"trade_is_powered_by" : "该交易由 ${provider}",
"copy_address" : "复制地址",
"exchange_result_confirm" : "点击确认 您将发送 ${fetchingLabel} ${from} 从你的钱包里 ${walletName} 到下面顯示的地址。 或者您可以從外部錢包發送到以下地址/ QR码。\n\n请按确认继续或返回以更改金额",
"exchange_result_description" : "请发送 ${fetchingLabel} ${from} 到下一頁顯示的地址.",
"exchange_result_description" : "您必須至少發送 ${fetchingLabel} ${from} 到下一頁上顯示的地址。 如果您發送的金額少於 ${fetchingLabel} ${from},則可能無法轉換,因此無法退還。",
"exchange_result_write_down_ID" : "*请复制或写下您上面显示的ID.",
"confirm" : "确认",
"confirm_sending" : "确认发送",

Loading…
Cancel
Save