Merged 4.0.9

This commit is contained in:
M 2020-12-11 20:10:06 +02:00
commit eede39ee7a
52 changed files with 986 additions and 126 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 374 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 KiB

BIN
assets/images/pre_seed_dark.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

BIN
assets/images/pre_seed_light.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

View file

@ -354,7 +354,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = 3;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = 32J6BB6VUS;
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
@ -371,7 +371,7 @@
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
MARKETING_VERSION = 4.0.8;
MARKETING_VERSION = 4.0.9;
PRODUCT_BUNDLE_IDENTIFIER = com.fotolockr.cakewallet;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@ -494,7 +494,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = 3;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = 32J6BB6VUS;
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
@ -511,7 +511,7 @@
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
MARKETING_VERSION = 4.0.8;
MARKETING_VERSION = 4.0.9;
PRODUCT_BUNDLE_IDENTIFIER = com.fotolockr.cakewallet;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@ -528,7 +528,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = 3;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = 32J6BB6VUS;
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
@ -545,7 +545,7 @@
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
MARKETING_VERSION = 4.0.8;
MARKETING_VERSION = 4.0.9;
PRODUCT_BUNDLE_IDENTIFIER = com.fotolockr.cakewallet;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";

View file

@ -60,7 +60,7 @@ class AddressValidator extends TextValidator {
case CryptoCurrency.bnb:
return [42];
case CryptoCurrency.btc:
return [33, 34, 42];
return [33, 34, 42, 62];
case CryptoCurrency.dai:
return [42];
case CryptoCurrency.dash:

View file

@ -4,7 +4,11 @@ class InitialExecutionState extends ExecutionState {}
class IsExecutingState extends ExecutionState {}
class ExecutedSuccessfullyState extends ExecutionState {}
class ExecutedSuccessfullyState extends ExecutionState {
ExecutedSuccessfullyState({this.payload});
final dynamic payload;
}
class FailureState extends ExecutionState {
FailureState(this.error);

View file

@ -7,7 +7,7 @@ class MoneroLabelValidator extends TextValidator {
MoneroLabelValidator({@required CryptoCurrency type})
: super(
errorMessage: S.current.error_text_account_name,
pattern: '^[a-zA-Z0-9_]{1,15}\$',
pattern: '^[a-zA-Z0-9_ ]{1,15}\$',
minLength: 1,
maxLength: 15);
}

View file

@ -22,6 +22,7 @@ import 'package:cake_wallet/src/screens/nodes/nodes_list_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/wallet_restore_page.dart';
import 'package:cake_wallet/src/screens/seed/pre_seed_page.dart';
import 'package:cake_wallet/src/screens/seed/wallet_seed_page.dart';
import 'package:cake_wallet/src/screens/send/send_template_page.dart';
import 'package:cake_wallet/src/screens/settings/change_language.dart';
@ -49,6 +50,7 @@ import 'package:cake_wallet/store/wallet_list_store.dart';
import 'package:cake_wallet/view_model/contact_list/contact_list_view_model.dart';
import 'package:cake_wallet/view_model/contact_list/contact_view_model.dart';
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/rescan_view_model.dart';
@ -274,7 +276,7 @@ Future setup(
getIt.registerFactory(() => MoneroAccountListPage(
accountListViewModel: getIt.get<MoneroAccountListViewModel>()));
getIt.registerFactory(() {
/*getIt.registerFactory(() {
final wallet = getIt.get<AppStore>().wallet;
if (wallet is MoneroWallet) {
@ -287,7 +289,19 @@ Future setup(
getIt.registerFactory(() => MoneroAccountEditOrCreatePage(
moneroAccountCreationViewModel:
getIt.get<MoneroAccountEditOrCreateViewModel>()));
getIt.get<MoneroAccountEditOrCreateViewModel>()));*/
getIt.registerFactoryParam<MoneroAccountEditOrCreateViewModel,
AccountListItem, void>(
(AccountListItem account, _) => MoneroAccountEditOrCreateViewModel(
(getIt.get<AppStore>().wallet as MoneroWallet).accountList,
accountListItem: account));
getIt.registerFactoryParam<MoneroAccountEditOrCreatePage, AccountListItem,
void>(
(AccountListItem account, _) => MoneroAccountEditOrCreatePage(
moneroAccountCreationViewModel:
getIt.get<MoneroAccountEditOrCreateViewModel>(param1: account)));
getIt.registerFactory(() {
final appStore = getIt.get<AppStore>();
@ -411,4 +425,6 @@ Future setup(
void Function(BuildContext, WalletType), bool>(
(para1, param2) => NewWalletTypePage(getIt.get<WalletNewVM>(),
onTypeSelected: para1, isNewWallet: param2));
getIt.registerFactory(() => PreSeedPage());
}

View file

@ -14,7 +14,8 @@ class Node extends HiveObject with Keyable {
{@required this.uri,
@required WalletType type,
this.login,
this.password}) {
this.password,
this.useSSL}) {
this.type = type;
}
@ -22,7 +23,8 @@ class Node extends HiveObject with Keyable {
: uri = map['uri'] as String ?? '',
login = map['login'] as String,
password = map['password'] as String,
typeRaw = map['typeRaw'] as int;
typeRaw = map['typeRaw'] as int,
useSSL = map['useSSL'] as bool;
static const boxName = 'Nodes';
@ -38,6 +40,11 @@ class Node extends HiveObject with Keyable {
@HiveField(3)
int typeRaw;
@HiveField(4)
bool useSSL;
bool get isSSL => useSSL ?? false;
@override
dynamic get keyIndex {
_keyIndex ??= key;

View file

@ -14,7 +14,8 @@ class TradeIsCreatedSuccessfully extends ExchangeTradeState {
}
class TradeIsCreatedFailure extends ExchangeTradeState {
TradeIsCreatedFailure({@required this.error});
TradeIsCreatedFailure({@required this.title, @required this.error});
final String title;
final String error;
}

View file

@ -12,6 +12,7 @@ import 'package:cake_wallet/exchange/xmrto/xmrto_trade_request.dart';
import 'package:cake_wallet/exchange/trade_not_created_exeption.dart';
import 'package:cake_wallet/exchange/exchange_provider_description.dart';
import 'package:cake_wallet/exchange/trade_not_found_exeption.dart';
import 'package:cake_wallet/generated/i18n.dart';
class XMRTOExchangeProvider extends ExchangeProvider {
XMRTOExchangeProvider()
@ -90,12 +91,25 @@ class XMRTOExchangeProvider extends ExchangeProvider {
Future<Trade> createTrade({TradeRequest request}) async {
final _request = request as XMRTOTradeRequest;
final url = originalApiUri + _orderCreateUriSuffix;
final _amount = _request.isBTCRequest
? _request.receiveAmount
: _request.amount;
final _amountCurrency = _request.isBTCRequest
? _request.to.toString()
: _request.from.toString();
final pattern = '^([0-9]+([.\,][0-9]{0,8})?|[.\,][0-9]{1,8})\$';
final isValid = RegExp(pattern).hasMatch(_amount);
if (!isValid) {
throw TradeNotCreatedException(description,
description: S.current.xmr_to_error_description);
}
final body = {
'amount':
_request.isBTCRequest ? _request.receiveAmount : _request.amount,
'amount_currency': _request.isBTCRequest
? _request.to.toString()
: _request.from.toString(),
'amount': _amount,
'amount_currency': _amountCurrency,
'btc_dest_address': _request.address
};
final response = await post(url,

File diff suppressed because it is too large Load diff

View file

@ -40,6 +40,10 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance> with Store {
fullBalance: monero_wallet.getFullBalance(accountIndex: 0),
unlockedBalance: monero_wallet.getFullBalance(accountIndex: 0));
_onAccountChangeReaction = reaction((_) => account, (Account account) {
balance = MoneroBalance(
fullBalance: monero_wallet.getFullBalance(accountIndex: account.id),
unlockedBalance:
monero_wallet.getUnlockedBalance(accountIndex: account.id));
subaddressList.update(accountIndex: account.id);
subaddress = subaddressList.subaddresses.first;
address = subaddress.address;
@ -94,7 +98,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance> with Store {
bool _isSavingAfterNewTransaction;
Future<void> init() async {
await accountList.update();
accountList.update();
account = accountList.accounts.first;
subaddressList.update(accountIndex: account.id ?? 0);
subaddress = subaddressList.getAll().first;
@ -147,8 +151,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance> with Store {
address: node.uri,
login: node.login,
password: node.password,
useSSL: false,
// FIXME: hardcoded value
useSSL: node.isSSL,
isLightWallet: false); // FIXME: hardcoded value
syncStatus = ConnectedSyncStatus();
} catch (e) {
@ -256,6 +259,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance> with Store {
monero_wallet.rescanBlockchainAsync();
await startSync();
_askForUpdateBalance();
accountList.update();
await _askForUpdateTransactionHistory();
await save();
await walletInfo.save();
@ -363,17 +367,20 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance> with Store {
void _onNewBlock(int height, int blocksLeft, double ptc) async {
if (walletInfo.isRecovery) {
_askForUpdateTransactionHistory();
await _askForUpdateTransactionHistory();
_askForUpdateBalance();
accountList.update();
}
if (blocksLeft < 100) {
await _askForUpdateTransactionHistory();
_askForUpdateBalance();
accountList.update();
syncStatus = SyncedSyncStatus();
await _afterSyncSave();
if (walletInfo.isRecovery) {
setAsRecovered();
await setAsRecovered();
}
} else {
syncStatus = SyncingSyncStatus(blocksLeft, ptc);

View file

@ -2,7 +2,9 @@ import 'package:cake_wallet/entities/contact_record.dart';
import 'package:cake_wallet/entities/transaction_description.dart';
import 'package:cake_wallet/src/screens/pin_code/pin_code_widget.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/store/settings_store.dart';
import 'package:cake_wallet/view_model/monero_account_list/account_list_item.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/routes.dart';
@ -70,7 +72,7 @@ Route<dynamic> createRoute(RouteSettings settings) {
return CupertinoPageRoute<void>(
builder: (_) => getIt.get<NewWalletTypePage>(
param1: (BuildContext context, WalletType _) =>
Navigator.of(context).pushNamed(Routes.seed, arguments: true),
Navigator.of(context).pushNamed(Routes.preSeed, arguments: true),
param2: true));
case Routes.newWallet:
@ -245,7 +247,8 @@ Route<dynamic> createRoute(RouteSettings settings) {
case Routes.accountCreation:
return CupertinoPageRoute<String>(
builder: (_) => getIt.get<MoneroAccountEditOrCreatePage>());
builder: (_) => getIt.get<MoneroAccountEditOrCreatePage>(
param1: settings.arguments as AccountListItem));
case Routes.addressBook:
return MaterialPageRoute<void>(
@ -306,6 +309,10 @@ Route<dynamic> createRoute(RouteSettings settings) {
return MaterialPageRoute<void>(
builder: (_) => getIt.get<LanguageListPage>());
case Routes.preSeed:
return MaterialPageRoute<void>(
builder: (_) => getIt.get<PreSeedPage>());
default:
return MaterialPageRoute<void>(
builder: (_) => Scaffold(

View file

@ -47,4 +47,5 @@ class Routes {
static const exchangeTemplate = '/exchange_template';
static const restoreWalletType = '/restore_wallet_type';
static const restoreWallet = '/restore_wallet';
static const preSeed = '/pre_seed';
}

View file

@ -39,7 +39,7 @@ class AddressPage extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
S.of(context).addresses,
S.of(context).accounts_subaddresses,
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w500,

View file

@ -5,6 +5,7 @@ import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
import 'package:cake_wallet/entities/wallet_type.dart';
import 'package:cake_wallet/src/screens/dashboard/wallet_menu.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
// FIXME: terrible design.
@ -147,7 +148,7 @@ class MenuWidgetState extends State<MenuWidget> {
),
if (widget.dashboardViewModel.subname !=
null)
Text(
Observer(builder: (_) => Text(
widget.dashboardViewModel.subname,
style: TextStyle(
color: Theme.of(context)
@ -156,7 +157,7 @@ class MenuWidgetState extends State<MenuWidget> {
.decorationColor,
fontWeight: FontWeight.w500,
fontSize: 12),
)
))
],
),
))

View file

@ -547,7 +547,7 @@ class ExchangePage extends BasePage {
context: context,
builder: (BuildContext context) {
return AlertWithOneAction(
alertTitle: S.of(context).error,
alertTitle: S.of(context).provider_error(state.title),
alertContent: state.error,
buttonText: S.of(context).ok,
buttonAction: () => Navigator.of(context).pop());
@ -555,6 +555,7 @@ class ExchangePage extends BasePage {
});
}
if (state is TradeIsCreatedSuccessfully) {
exchangeViewModel.reset();
Navigator.of(context).pushNamed(Routes.exchangeConfirm);
}
});

View file

@ -103,7 +103,12 @@ class MoneroAccountListPage extends StatelessWidget {
accountListViewModel
.select(account);
Navigator.of(context).pop();
});
},
onEdit: () async =>
await Navigator.of(context)
.pushNamed(
Routes.accountCreation,
arguments: account));
},
),
isAlwaysShowScrollThumb

View file

@ -1,15 +1,19 @@
import 'package:flutter/material.dart';
import 'package:flutter_slidable/flutter_slidable.dart';
import 'package:cake_wallet/generated/i18n.dart';
class AccountTile extends StatelessWidget {
AccountTile({
@required this.isCurrent,
@required this.accountName,
@required this.onTap
@required this.onTap,
@required this.onEdit
});
final bool isCurrent;
final String accountName;
final VoidCallback onTap;
final Function() onTap;
final Function() onEdit;
@override
Widget build(BuildContext context) {
@ -20,7 +24,7 @@ class AccountTile extends StatelessWidget {
? Theme.of(context).textTheme.subtitle.color
: Theme.of(context).textTheme.display4.color;
return GestureDetector(
final Widget cell = GestureDetector(
onTap: onTap,
child: Container(
height: 77,
@ -39,5 +43,17 @@ class AccountTile extends StatelessWidget {
),
),
);
return isCurrent ? cell : Slidable(
key: Key(accountName),
child: cell,
actionPane: SlidableDrawerActionPane(),
secondaryActions: <Widget>[
IconSlideAction(
caption: S.of(context).edit,
color: Colors.blue,
icon: Icons.edit,
onTap: () => onEdit?.call())
]);
}
}

View file

@ -1,3 +1,7 @@
import 'package:cake_wallet/core/execution_state.dart';
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
import 'package:cake_wallet/src/widgets/standard_checkbox.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
@ -67,6 +71,39 @@ class NodeCreateOrEditPage extends BasePage {
@override
Widget body(BuildContext context) {
reaction((_) => nodeCreateOrEditViewModel.connectionState,
(ExecutionState state) {
if (state is ExecutedSuccessfullyState) {
WidgetsBinding.instance.addPostFrameCallback((_) {
showPopUp<void>(
context: context,
builder: (BuildContext context) =>
AlertWithOneAction(
alertTitle: S.of(context).new_node_testing,
alertContent: state.payload as bool
? S.of(context).node_connection_successful
: S.of(context).node_connection_failed,
buttonText: S.of(context).ok,
buttonAction: () => Navigator.of(context).pop()));
});
}
if (state is FailureState) {
WidgetsBinding.instance.addPostFrameCallback((_) {
showPopUp<void>(
context: context,
builder: (BuildContext context) {
return AlertWithOneAction(
alertTitle: S.of(context).error,
alertContent: state.error,
buttonText: S.of(context).ok,
buttonAction: () => Navigator.of(context).pop());
});
});
}
});
return Container(
padding: EdgeInsets.only(left: 24, right: 24),
child: ScrollableWithBottomSection(
@ -122,7 +159,22 @@ class NodeCreateOrEditPage extends BasePage {
)
)
],
)
),
Padding(
padding: EdgeInsets.only(top: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: [
Observer(
builder: (_) => StandardCheckbox(
value: nodeCreateOrEditViewModel.useSSL,
onChanged: (value) =>
nodeCreateOrEditViewModel.useSSL = value,
caption: S.of(context).use_ssl,
))
],
))
]
],
)),
@ -133,9 +185,18 @@ class NodeCreateOrEditPage extends BasePage {
Flexible(
child: Container(
padding: EdgeInsets.only(right: 8.0),
child: PrimaryButton(
onPressed: () => nodeCreateOrEditViewModel.reset(),
text: S.of(context).reset,
child: LoadingPrimaryButton(
onPressed: () async {
if (!_formKey.currentState.validate()) {
return;
}
await nodeCreateOrEditViewModel.connect();
},
isLoading: nodeCreateOrEditViewModel
.connectionState is IsExecutingState,
text: S.of(context).node_test,
isDisabled: !nodeCreateOrEditViewModel.isReady,
color: Colors.orange,
textColor: Colors.white),
)),
@ -154,7 +215,9 @@ class NodeCreateOrEditPage extends BasePage {
text: S.of(context).save,
color: Theme.of(context).accentTextTheme.body2.color,
textColor: Colors.white,
isDisabled: !nodeCreateOrEditViewModel.isReady,
isDisabled: (!nodeCreateOrEditViewModel.isReady)||
(nodeCreateOrEditViewModel
.connectionState is IsExecutingState),
),
)),
],

View file

@ -99,9 +99,9 @@ class NodeListPage extends BasePage {
await showPopUp<void>(
context: context,
builder: (BuildContext context) {
// FIXME: Add translation.
return AlertWithTwoActions(
alertTitle: 'Change current node',
alertTitle: S.of(context)
.change_current_node_title,
alertContent: S
.of(context)
.change_current_node(node.uri),

View file

@ -117,7 +117,7 @@ class ReceivePage extends BasePage {
Icons.arrow_forward_ios,
size: 14,
color:
Theme.of(context).textTheme.display1.color,
Theme.of(context).textTheme.display1.color,
));
}
@ -130,7 +130,7 @@ class ReceivePage extends BasePage {
Icons.add,
size: 20,
color:
Theme.of(context).textTheme.display1.color,
Theme.of(context).textTheme.display1.color,
));
}
@ -140,13 +140,13 @@ class ReceivePage extends BasePage {
addressListViewModel.address.address;
final backgroundColor = isCurrent
? Theme.of(context)
.textTheme
.display3
.decorationColor
.textTheme
.display3
.decorationColor
: Theme.of(context)
.textTheme
.display2
.decorationColor;
.textTheme
.display2
.decorationColor;
final textColor = isCurrent
? Theme.of(context).textTheme.display3.color
: Theme.of(context).textTheme.display2.color;
@ -155,8 +155,7 @@ class ReceivePage extends BasePage {
isCurrent: isCurrent,
backgroundColor: backgroundColor,
textColor: textColor,
onTap: (_) =>
addressListViewModel.setAddress(item),
onTap: (_) => addressListViewModel.setAddress(item),
onEdit: () => Navigator.of(context).pushNamed(
Routes.newSubaddress,
arguments: item));
@ -166,11 +165,11 @@ class ReceivePage extends BasePage {
return index != 0
? cell
: ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(30),
topRight: Radius.circular(30)),
child: cell,
);
borderRadius: BorderRadius.only(
topLeft: Radius.circular(30),
topRight: Radius.circular(30)),
child: cell,
);
})),
],
),

View file

@ -14,6 +14,7 @@ class AddressCell extends StatelessWidget {
address: item.address,
name: item.name,
isCurrent: isCurrent,
isPrimary: item.isPrimary,
backgroundColor: backgroundColor,
textColor: textColor,
onTap: onTap,
@ -23,6 +24,7 @@ class AddressCell extends StatelessWidget {
{@required this.address,
@required this.name,
@required this.isCurrent,
@required this.isPrimary,
@required this.backgroundColor,
@required this.textColor,
this.onTap,
@ -31,6 +33,7 @@ class AddressCell extends StatelessWidget {
final String address;
final String name;
final bool isCurrent;
final bool isPrimary;
final Color backgroundColor;
final Color textColor;
final Function(String) onTap;
@ -56,7 +59,7 @@ class AddressCell extends StatelessWidget {
),
));
return isCurrent
return (isCurrent || isPrimary)
? cell
: Slidable(
key: Key(address),

View file

@ -52,19 +52,9 @@ class QRWidget extends StatelessWidget {
))))),
Spacer(flex: 3)
]),
Padding(
padding: EdgeInsets.only(top: 20),
child: Text(
S.of(context).scan_qr_code,
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w500,
color: Theme.of(context).indicatorColor),
),
),
isAmountFieldShow
? Padding(
padding: EdgeInsets.only(top: 40),
padding: EdgeInsets.only(top: 60),
child: Row(
children: <Widget>[
Expanded(

View file

@ -0,0 +1,67 @@
import 'package:cake_wallet/di.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/store/settings_store.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/widgets/primary_button.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
class PreSeedPage extends BasePage {
static final imageLight = Image.asset('assets/images/pre_seed_light.png');
static final imageDark = Image.asset('assets/images/pre_seed_dark.png');
@override
Widget leading(BuildContext context) => null;
@override
String get title => S.current.pre_seed_title;
@override
Widget body(BuildContext context) {
final image =
getIt.get<SettingsStore>().isDarkTheme ? imageDark : imageLight;
return WillPopScope(
onWillPop: () async => false,
child: Container(
padding: EdgeInsets.all(24),
child: Column(
children: [
Flexible(
flex: 2,
child: AspectRatio(
aspectRatio: 1,
child: FittedBox(child: image, fit: BoxFit.contain))),
Flexible(
flex: 3,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Padding(
padding: EdgeInsets.only(top: 70, left: 16, right: 16),
child: Text(
S.of(context).pre_seed_description,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal,
color: Theme.of(context)
.primaryTextTheme
.caption
.color),
),
),
PrimaryButton(
onPressed: () => Navigator.of(context)
.popAndPushNamed(Routes.seed, arguments: true),
text: S.of(context).pre_seed_button_text,
color: Theme.of(context).accentTextTheme.body2.color,
textColor: Colors.white)
],
))
],
),
));
}
}

View file

@ -86,7 +86,7 @@ class WalletSeedPage extends BasePage {
final image =
getIt.get<SettingsStore>().isDarkTheme ? imageDark : imageLight;
return Container(
return WillPopScope(onWillPop: () async => false, child: Container(
padding: EdgeInsets.all(24),
child: Column(
children: <Widget>[
@ -194,6 +194,6 @@ class WalletSeedPage extends BasePage {
],
))
],
));
)));
}
}

View file

@ -243,7 +243,7 @@ class WalletListBodyState extends State<WalletListBody> {
changeProcessText(S.of(context).creating_new_wallet);
await widget.walletListViewModel.walletNewVM.create(options: 'English'); // FIXME: Unnamed constant
hideProgressText();
await Navigator.of(context).pushNamed(Routes.seed, arguments: true);
await Navigator.of(context).pushNamed(Routes.preSeed);
} catch(e) {
changeProcessText(S.of(context).creating_new_wallet_error(e.toString()));
}

View file

@ -0,0 +1,76 @@
import 'dart:ui';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class StandardCheckbox extends StatefulWidget {
StandardCheckbox({
@required this.value,
this.caption = '',
@required this.onChanged});
final bool value;
final String caption;
final Function(bool) onChanged;
@override
StandardCheckboxState createState() =>
StandardCheckboxState(value, caption, onChanged);
}
class StandardCheckboxState extends State<StandardCheckbox> {
StandardCheckboxState(this.value, this.caption, this.onChanged);
bool value;
String caption;
Function(bool) onChanged;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
value = !value;
onChanged(value);
setState(() {});
},
child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Container(
height: 24.0,
width: 24.0,
margin: EdgeInsets.only(
right: 10.0,
),
decoration: BoxDecoration(
border: Border.all(
color: Theme.of(context)
.primaryTextTheme
.caption
.color,
width: 1.0),
borderRadius: BorderRadius.all(
Radius.circular(8.0)),
color: Theme.of(context).backgroundColor),
child: value
? Icon(
Icons.check,
color: Colors.blue,
size: 20.0,
)
: Offstage(),
),
Text(
caption,
style: TextStyle(
fontSize: 16.0,
color: Theme.of(context)
.primaryTextTheme
.title
.color),
)
],
),
);
}
}

View file

@ -3,7 +3,7 @@ import 'package:mobx/mobx.dart';
import 'package:cake_wallet/exchange/exchange_provider_description.dart';
import 'package:cake_wallet/view_model/dashboard/trade_list_item.dart';
part 'trade_filter_store.g.dart';
part'trade_filter_store.g.dart';
class TradeFilterStore = TradeFilterStoreBase with _$TradeFilterStore;

View file

@ -1,5 +1,10 @@
import 'package:cake_wallet/bitcoin/bitcoin_transaction_info.dart';
import 'package:cake_wallet/bitcoin/bitcoin_wallet.dart';
import 'package:cake_wallet/entities/transaction_history.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';
import 'package:cake_wallet/monero/monero_transaction_info.dart';
import 'package:cake_wallet/monero/monero_wallet.dart';
import 'package:cake_wallet/entities/balance_display_mode.dart';
import 'package:cake_wallet/entities/crypto_currency.dart';
@ -74,28 +79,53 @@ abstract class DashboardViewModelBase with Store {
wallet ??= appStore.wallet;
type = wallet.type;
transactions = ObservableList.of(wallet
.transactionHistory.transactions.values
.map((transaction) => TransactionListItem(
transaction: transaction,
balanceViewModel: balanceViewModel,
settingsStore: appStore.settingsStore)));
_reaction = reaction((_) => appStore.wallet, _onWalletChange);
// FIXME: fixme
final _wallet = wallet;
if (_wallet is MoneroWallet) {
subname = _wallet.account?.label;
_onMoneroAccountChangeReaction = reaction((_) => _wallet.account,
(Account account) => _onMoneroAccountChange(_wallet));
_onMoneroBalanceChangeReaction = reaction((_) => _wallet.balance,
(MoneroBalance balance) => _onMoneroTransactionsUpdate(_wallet));
final _accountTransactions = _wallet
.transactionHistory.transactions.values
.where((tx) => tx.accountIndex == _wallet.account.id)
.toList();
transactions = ObservableList.of(_accountTransactions.map((transaction) =>
TransactionListItem(
transaction: transaction,
balanceViewModel: balanceViewModel,
settingsStore: appStore.settingsStore)));
} else {
transactions = ObservableList.of(wallet
.transactionHistory.transactions.values
.map((transaction) => TransactionListItem(
transaction: transaction,
balanceViewModel: balanceViewModel,
settingsStore: appStore.settingsStore)));
}
connectMapToListWithTransform(
appStore.wallet.transactionHistory.transactions,
transactions,
(TransactionInfo val) => TransactionListItem(
transaction: val,
balanceViewModel: balanceViewModel,
settingsStore: appStore.settingsStore));
settingsStore: appStore.settingsStore),
filter: (TransactionInfo tx) {
final wallet = _wallet;
if (tx is MoneroTransactionInfo && wallet is MoneroWallet) {
return tx.accountIndex == wallet.account.id;
}
final _wallet = wallet;
if (_wallet is MoneroWallet) {
subname = _wallet.account?.label;
}
return true;
});
}
@observable
@ -170,6 +200,10 @@ abstract class DashboardViewModelBase with Store {
ReactionDisposer _reaction;
ReactionDisposer _onMoneroAccountChangeReaction;
ReactionDisposer _onMoneroBalanceChangeReaction;
Future<void> reconnect() async {
final node = appStore.settingsStore.getCurrentNode(wallet.type);
await wallet.connectToNode(node: node);
@ -180,9 +214,47 @@ abstract class DashboardViewModelBase with Store {
this.wallet = wallet;
type = wallet.type;
name = wallet.name;
if (wallet is MoneroWallet) {
subname = wallet.account?.label;
_onMoneroAccountChangeReaction?.reaction?.dispose();
_onMoneroBalanceChangeReaction?.reaction?.dispose();
_onMoneroAccountChangeReaction = reaction((_) => wallet.account,
(Account account) => _onMoneroAccountChange(wallet));
_onMoneroBalanceChangeReaction = reaction((_) => wallet.balance,
(MoneroBalance balance) => _onMoneroTransactionsUpdate(wallet));
_onMoneroTransactionsUpdate(wallet);
} else {
transactions.clear();
transactions.addAll(wallet.transactionHistory.transactions.values.map(
(transaction) => TransactionListItem(
transaction: transaction,
balanceViewModel: balanceViewModel,
settingsStore: appStore.settingsStore)));
}
}
@action
void _onMoneroAccountChange(MoneroWallet wallet) {
subname = wallet.account?.label;
_onMoneroTransactionsUpdate(wallet);
}
@action
void _onMoneroTransactionsUpdate(MoneroWallet wallet) {
transactions.clear();
transactions.addAll(wallet.transactionHistory.transactions.values.map(
(transaction) => TransactionListItem(
final _accountTransactions = wallet.transactionHistory.transactions.values
.where((tx) => tx.accountIndex == wallet.account.id)
.toList();
transactions.addAll(_accountTransactions.map((transaction) =>
TransactionListItem(
transaction: transaction,
balanceViewModel: balanceViewModel,
settingsStore: appStore.settingsStore)));

View file

@ -174,7 +174,7 @@ abstract class ExchangeViewModelBase with Store {
return;
}
final _amount = double.parse(amount.replaceAll(',', '.'));
final _amount = double.parse(amount.replaceAll(',', '.')) ?? 0;
provider
.calculateAmount(
from: depositCurrency,
@ -247,10 +247,12 @@ abstract class ExchangeViewModelBase with Store {
if (limitsState is LimitsLoadedSuccessfully && amount != null) {
if (double.parse(amount) < limits.min) {
tradeState = TradeIsCreatedFailure(
title: provider.title,
error: S.current.error_text_minimal_limit('${provider.description}',
'${limits.min}', currency.toString()));
} else if (limits.max != null && double.parse(amount) > limits.max) {
tradeState = TradeIsCreatedFailure(
title: provider.title,
error: S.current.error_text_maximum_limit('${provider.description}',
'${limits.max}', currency.toString()));
} else {
@ -262,11 +264,14 @@ abstract class ExchangeViewModelBase with Store {
await trades.add(trade);
tradeState = TradeIsCreatedSuccessfully(trade: trade);
} catch (e) {
tradeState = TradeIsCreatedFailure(error: e.toString());
tradeState = TradeIsCreatedFailure(
title: provider.title,
error: e.toString());
}
}
} else {
tradeState = TradeIsCreatedFailure(
title: provider.title,
error: S.current
.error_text_limits_loading_failed('${provider.description}'));
}

View file

@ -13,6 +13,7 @@ abstract class MoneroAccountEditOrCreateViewModelBase with Store {
{AccountListItem accountListItem})
: state = InitialExecutionState(),
isEdit = accountListItem != null,
label = accountListItem?.label??'',
_accountListItem = accountListItem;
final bool isEdit;

View file

@ -12,7 +12,9 @@ class NodeCreateOrEditViewModel = NodeCreateOrEditViewModelBase
abstract class NodeCreateOrEditViewModelBase with Store {
NodeCreateOrEditViewModelBase(this._nodeSource, this._wallet)
: state = InitialExecutionState();
: state = InitialExecutionState(),
connectionState = InitialExecutionState(),
useSSL = false;
@observable
ExecutionState state;
@ -29,6 +31,12 @@ abstract class NodeCreateOrEditViewModelBase with Store {
@observable
String password;
@observable
ExecutionState connectionState;
@observable
bool useSSL;
@computed
bool get isReady =>
(address?.isNotEmpty ?? false) && (port?.isNotEmpty ?? false);
@ -54,6 +62,7 @@ abstract class NodeCreateOrEditViewModelBase with Store {
port = '';
login = '';
password = '';
useSSL = false;
}
@action
@ -61,11 +70,25 @@ abstract class NodeCreateOrEditViewModelBase with Store {
try {
state = IsExecutingState();
final node =
Node(uri: uri, type: _wallet.type, login: login, password: password);
Node(uri: uri, type: _wallet.type, login: login, password: password,
useSSL: useSSL);
await _nodeSource.add(node);
state = ExecutedSuccessfullyState();
} catch (e) {
state = FailureState(e.toString());
}
}
@action
Future<void> connect() async {
try {
connectionState = IsExecutingState();
final node =
Node(uri: uri, type: _wallet.type, login: login, password: password);
final isAlive = await node.requestNode();
connectionState = ExecutedSuccessfullyState(payload: isAlive);
} catch (e) {
connectionState = FailureState(e.toString());
}
}
}

View file

@ -2,10 +2,11 @@ import 'package:flutter/foundation.dart';
import 'package:cake_wallet/utils/list_item.dart';
class WalletAddressListItem extends ListItem {
const WalletAddressListItem({@required this.address, this.name, this.id})
: super();
const WalletAddressListItem({@required this.address, @required this.isPrimary,
this.name, this.id}) : super();
final int id;
final bool isPrimary;
final String address;
final String name;

View file

@ -97,16 +97,28 @@ abstract class WalletAddressListViewModelBase with Store {
final addressList = ObservableList<ListItem>();
if (wallet is MoneroWallet) {
addressList.addAll(wallet.subaddressList.subaddresses.map((subaddress) =>
WalletAddressListItem(
id: subaddress.id,
name: subaddress.label,
address: subaddress.address)));
final primaryAddress = wallet.subaddressList.subaddresses.first;
addressList.addAll(wallet.subaddressList.subaddresses.map((subaddress) {
final isPrimary = subaddress == primaryAddress;
return WalletAddressListItem(
id: subaddress.id,
isPrimary: isPrimary,
name: subaddress.label,
address: subaddress.address);
}));
}
if (wallet is BitcoinWallet) {
final bitcoinAddresses = wallet.addresses.map((addr) =>
WalletAddressListItem(name: addr.label, address: addr.address));
final primaryAddress = wallet.addresses.first;
final bitcoinAddresses = wallet.addresses.map((addr) {
final isPrimary = addr == primaryAddress;
return WalletAddressListItem(
isPrimary: isPrimary,
name: addr.label,
address: addr.address);
});
addressList.addAll(bitcoinAddresses);
}

View file

@ -11,7 +11,7 @@ description: Cake Wallet.
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 4.0.8+20
version: 4.0.9+21
environment:
sdk: ">=2.7.0 <3.0.0"

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" : "WICHTIG:\nWenn Sie einen garantierten BTC-Betrag erhalten möchten, geben Sie diesen Betrag in das Feld BTC ein. Wenn Sie stattdessen einen XMR-Betrag eingeben, handelt es sich bei dem erhaltenen BTC-Betrag um eine Schätzung, die je nach Kurs schwanken kann.",
"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_estimate" : "Der empfangene Betrag ist eine Schätzung",
"powered_by" : "Unterstützt von ${title}",
"error" : "Error",
@ -129,6 +129,11 @@
"remove" : "Löschen",
"delete" : "Löschen",
"add_new_node" : "Neuen Knoten hinzufügen",
"change_current_node_title" : "Ändern Sie den aktuellen Knoten",
"node_test" : "Test",
"node_connection_successful" : "Die Verbindung war erfolgreich",
"node_connection_failed" : "Verbindung fehlgeschlagen",
"new_node_testing" : "Neuer Knotentest",
"use" : "Verwenden Sie ",
@ -407,5 +412,16 @@
"seed_alert_back" : "Geh zurück",
"seed_alert_yes" : "Ja, habe ich",
"exchange_sync_alert_content" : "Bitte warten Sie, bis Ihre Brieftasche synchronisiert ist"
"exchange_sync_alert_content" : "Bitte warten Sie, bis Ihre Brieftasche synchronisiert ist",
"pre_seed_title" : "WICHTIG",
"pre_seed_description" : "Auf der nächsten Seite sehen Sie eine Reihe von 25 Wörtern. Dies ist Ihr einzigartiger und privater Samen und der EINZIGE Weg, um Ihren Geldbeutel im Falle eines Verlusts oder einer Fehlfunktion wiederherzustellen. Es liegt in IHRER Verantwortung, es aufzuschreiben und an einem sicheren Ort außerhalb der Cake Wallet App aufzubewahren.",
"pre_seed_button_text" : "Ich verstehe. Zeig mir meinen Samen",
"xmr_to_error" : "XMR.TO-Fehler",
"xmr_to_error_description" : "Ungültiger Betrag. Höchstgrenze 8 Stellen nach dem Dezimalpunkt",
"provider_error" : "${provider} Error",
"use_ssl" : "Verwenden Sie SSL"
}

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" : "IMPORTANT:\nIf you want to receive a guaranteed amount of BTC, please enter that amount in the BTC field. If you enter an XMR amount instead, then the BTC amount received is an estimate and can fluctuate depending on the rates.",
"amount_is_guaranteed" : "In xmr.to, to receive a guaranteed BTC amount, enter the BTC amount and not the XMR amount above",
"amount_is_estimate" : "The receive amount is an estimate",
"powered_by" : "Powered by ${title}",
"error" : "Error",
@ -129,6 +129,11 @@
"remove" : "Remove",
"delete" : "Delete",
"add_new_node" : "Add new node",
"change_current_node_title" : "Change current node",
"node_test" : "Test",
"node_connection_successful" : "Connection was successful",
"node_connection_failed" : "Connection was failed",
"new_node_testing" : "New node testing",
"use" : "Switch to ",
@ -407,5 +412,16 @@
"seed_alert_back" : "Go back",
"seed_alert_yes" : "Yes, I have",
"exchange_sync_alert_content" : "Please wait until your wallet is synchronized"
"exchange_sync_alert_content" : "Please wait until your wallet is synchronized",
"pre_seed_title" : "IMPORTANT",
"pre_seed_description" : "On the next page you will see a series of 25 words. This is your unique and private seed and it is the ONLY way to recover your wallet in case of loss or malfunction. It is YOUR responsibility to write it down and store it in a safe place outside of the Cake Wallet app.",
"pre_seed_button_text" : "I understand. Show me my seed",
"xmr_to_error" : "XMR.TO error",
"xmr_to_error_description" : "Invalid amount. Maximum limit 8 digits after the decimal point",
"provider_error" : "${provider} error",
"use_ssl" : "Use SSL"
}

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" : "IMPORTANTE:\nSi desea recibir una cantidad garantizada de BTC, ingrese esa cantidad en el campo BTC. Si ingresa una cantidad de XMR en su lugar, la cantidad de BTC recibida es una estimación y puede variar según las tarifas.",
"amount_is_guaranteed" : "En xmr.to, para recibir una cantidad BTC garantizada, ingrese la cantidad BTC y no la cantidad XMR arriba",
"amount_is_estimate" : "El monto recibido es un estimado",
"powered_by" : "Energizado por ${title}",
"error" : "Error",
@ -129,6 +129,11 @@
"remove" : "Retirar",
"delete" : "Borrar",
"add_new_node" : "Agregar nuevo nodo",
"change_current_node_title" : "Cambiar el nodo actual",
"node_test" : "Prueba",
"node_connection_successful" : "La conexión fue exitosa",
"node_connection_failed" : "La conexión falló",
"new_node_testing" : "Prueba de nuevos nodos",
"use" : "Utilizar a ",
@ -407,5 +412,16 @@
"seed_alert_back" : "Regresa",
"seed_alert_yes" : "Sí tengo",
"exchange_sync_alert_content" : "Espere hasta que su billetera esté sincronizada"
"exchange_sync_alert_content" : "Espere hasta que su billetera esté sincronizada",
"pre_seed_title" : "IMPORTANTE",
"pre_seed_description" : "En la página siguiente verá una serie de 25 palabras. Esta es su semilla única y privada y es la ÚNICA forma de recuperar su billetera en caso de pérdida o mal funcionamiento. Es SU responsabilidad escribirlo y guardarlo en un lugar seguro fuera de la aplicación Cake Wallet.",
"pre_seed_button_text" : "Entiendo. Muéstrame mi semilla",
"xmr_to_error" : "Error de XMR.TO",
"xmr_to_error_description" : "Monto invalido. Límite máximo de 8 dígitos después del punto decimal",
"provider_error" : "${provider} error",
"use_ssl" : "Utilice SSL"
}

View file

@ -65,7 +65,7 @@
"change_exchange_provider" : "एक्सचेंज प्रदाता बदलें",
"you_will_send" : "से रूपांतरित करें",
"you_will_get" : "में बदलें",
"amount_is_guaranteed" : "महत्वपूर्ण:\nयदि आप BTC की गारंटीकृत राशि प्राप्त करना चाहते हैं, तो कृपया उस राशि को BTC फ़ील्ड में दर्ज करें। यदि आप इसके बजाय एक एक्सएमआर राशि दर्ज करते हैं, तो प्राप्त बीटीसी राशि एक अनुमान है और दरों के आधार पर इसमें उतार-चढ़ाव हो सकता है।",
"amount_is_guaranteed" : "Xmr.to में, गारंटीशुदा BTC राशि प्राप्त करने के लिए, BTC राशि दर्ज करें और ऊपर XMR राशि नहीं",
"amount_is_estimate" : "प्राप्त राशि एक अनुमान है",
"powered_by" : "द्वारा संचालित ${title}",
"error" : "त्रुटि",
@ -129,6 +129,11 @@
"remove" : "हटाना",
"delete" : "हटाएं",
"add_new_node" : "नया नोड जोड़ें",
"change_current_node_title" : "वर्तमान नोड बदलें",
"node_test" : "परीक्षा",
"node_connection_successful" : "कनेक्शन सफल रहा",
"node_connection_failed" : "कनेक्शन विफल रहा",
"new_node_testing" : "नई नोड परीक्षण",
"use" : "उपयोग ",
@ -407,5 +412,16 @@
"seed_alert_back" : "वापस जाओ",
"seed_alert_yes" : "हाँ मेरे पास है",
"exchange_sync_alert_content" : "कृपया प्रतीक्षा करें जब तक आपका बटुआ सिंक्रनाइज़ नहीं किया जाता है"
"exchange_sync_alert_content" : "कृपया प्रतीक्षा करें जब तक आपका बटुआ सिंक्रनाइज़ नहीं किया जाता है",
"pre_seed_title" : "महत्वपूर्ण",
"pre_seed_description" : "अगले पेज पर आपको 25 शब्दों की एक श्रृंखला दिखाई देगी। यह आपका अद्वितीय और निजी बीज है और नुकसान या खराबी के मामले में अपने बटुए को पुनर्प्राप्त करने का एकमात्र तरीका है। यह आपकी जिम्मेदारी है कि इसे नीचे लिखें और इसे Cake Wallet ऐप के बाहर सुरक्षित स्थान पर संग्रहीत करें।",
"pre_seed_button_text" : "मै समझता हुँ। मुझे अपना बीज दिखाओ",
"xmr_to_error" : "XMR.TO त्रुटि",
"xmr_to_error_description" : "अवैध राशि। दशमलव बिंदु के बाद अधिकतम सीमा 8 अंक",
"provider_error" : "${provider} त्रुटि",
"use_ssl" : "उपयोग SSL"
}

View file

@ -65,7 +65,7 @@
"change_exchange_provider" : "Exchangeプロバイダーの変更",
"you_will_send" : "から変換",
"you_will_get" : "に変換",
"amount_is_guaranteed" : "重要:\n保証された金額のBTCを受け取りたい場合は、その金額を[BTC]フィールドに入力してください。 代わりにXMR金額を入力した場合、受け取ったBTC金額は見積もりであり、レートに応じて変動する可能性があります。",
"amount_is_guaranteed" : "xmr.toで、保証されたBTC金額を受け取るには、上記のXMR金額ではなく、BTC金額を入力します",
"amount_is_estimate" : "受け取り金額は見積もりです",
"powered_by" : "搭載 ${title}",
"error" : "エラー",
@ -129,6 +129,11 @@
"remove" : "削除する",
"delete" : "削除する",
"add_new_node" : "新しいノードを追加",
"change_current_node_title" : "現在のノードを変更する",
"node_test" : "テスト",
"node_connection_successful" : "接続に成功しました",
"node_connection_failed" : "接続に失敗しました",
"new_node_testing" : "新しいノードのテスト",
"use" : "使用する ",
@ -407,5 +412,16 @@
"seed_alert_back" : "戻る",
"seed_alert_yes" : "はい、あります",
"exchange_sync_alert_content" : "ウォレットが同期されるまでお待ちください"
"exchange_sync_alert_content" : "ウォレットが同期されるまでお待ちください",
"pre_seed_title" : "重要",
"pre_seed_description" : "次のページでは、一連の25語が表示されます。 これはあなたのユニークでプライベートなシードであり、紛失や誤動作が発生した場合にウォレットを回復する唯一の方法です。 それを書き留めて、Cake Wallet アプリの外の安全な場所に保管するのはあなたの責任です。",
"pre_seed_button_text" : "わかります。 種を見せて",
"xmr_to_error" : "XMR.TOエラー",
"xmr_to_error_description" : "金額が無効です。 小数点以下8桁の上限",
"provider_error" : "${provider} エラー",
"use_ssl" : "SSLを使用する"
}

View file

@ -65,7 +65,7 @@
"change_exchange_provider" : "교환 공급자 변경",
"you_will_send" : "다음에서 변환",
"you_will_get" : "로 변환하다",
"amount_is_guaranteed" : "중대한:\n보장 된 BTC 금액을 받으려면 BTC 필드에 해당 금액을 입력하십시오. 대신 XMR 금액을 입력하면 수령 한 BTC 금액이 추정치이며 요율에 따라 변동될 수 있습니다.",
"amount_is_guaranteed" : "xmr.to에서 보장 된 BTC 금액을 받으려면 위의 XMR 금액이 아닌 BTC 금액을 입력하십시오.",
"amount_is_estimate" : "수신 금액은 견적입니다",
"powered_by" : "에 의해 구동 ${title}",
"error" : "오류",
@ -129,6 +129,11 @@
"remove" : "없애다",
"delete" : "지우다",
"add_new_node" : "새 노드 추가",
"change_current_node_title" : "현재 노드 변경",
"node_test" : "테스트",
"node_connection_successful" : "성공적으로 연결되었습니다.",
"node_connection_failed" : "연결 실패",
"new_node_testing" : "새로운 노드 테스트",
"use" : "사용하다 ",
@ -407,5 +412,16 @@
"seed_alert_back" : "돌아 가기",
"seed_alert_yes" : "네, 있어요",
"exchange_sync_alert_content" : "지갑이 동기화 될 때까지 기다리십시오"
"exchange_sync_alert_content" : "지갑이 동기화 될 때까지 기다리십시오",
"pre_seed_title" : "중대한",
"pre_seed_description" : "다음 페이지에서 25 개의 단어를 볼 수 있습니다. 이것은 귀하의 고유하고 개인적인 시드이며 분실 또는 오작동시 지갑을 복구하는 유일한 방법입니다. 기록해두고 Cake Wallet 앱 외부의 안전한 장소에 보관하는 것은 귀하의 책임입니다.",
"pre_seed_button_text" : "이해 했어요. 내 씨앗을 보여줘",
"xmr_to_error" : "XMR.TO 오류",
"xmr_to_error_description" : "금액이 잘못되었습니다. 소수점 이하 최대 8 자리",
"provider_error" : "${provider} 오류",
"use_ssl" : "SSL 사용"
}

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" : "BELANGRIJK:\nAls u een gegarandeerd bedrag aan BTC wilt ontvangen, voert u dat bedrag in het BTC-veld in. Als u in plaats daarvan een XMR-bedrag invoert, is het ontvangen BTC-bedrag een schatting en kan het fluctueren afhankelijk van de tarieven.",
"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_estimate" : "Het ontvangen bedrag is een schatting",
"powered_by" : "Aangedreven door ${title}",
"error" : "Fout",
@ -129,6 +129,11 @@
"remove" : "Verwijderen",
"delete" : "Delete",
"add_new_node" : "Voeg een nieuw knooppunt toe",
"change_current_node_title" : "Wijzig het huidige knooppunt",
"node_test" : "Test",
"node_connection_successful" : "Verbinding is gelukt",
"node_connection_failed" : "De verbinding is mislukt",
"new_node_testing" : "Nieuwe knooppunttest",
"use" : "Gebruik ",
@ -407,5 +412,16 @@
"seed_alert_back" : "Ga terug",
"seed_alert_yes" : "Ja ik heb",
"exchange_sync_alert_content" : "Wacht tot uw portemonnee is gesynchroniseerd"
"exchange_sync_alert_content" : "Wacht tot uw portemonnee is gesynchroniseerd",
"pre_seed_title" : "BELANGRIJK",
"pre_seed_description" : "Op de volgende pagina ziet u een reeks van 25 woorden. Dit is uw unieke en persoonlijke zaadje en het is de ENIGE manier om uw portemonnee te herstellen in geval van verlies of storing. Het is JOUW verantwoordelijkheid om het op te schrijven en op een veilige plaats op te slaan buiten de Cake Wallet app.",
"pre_seed_button_text" : "Ik begrijp het. Laat me mijn zaad zien",
"xmr_to_error" : "XMR.TO-fout",
"xmr_to_error_description" : "Ongeldige hoeveelheid. Maximaal 8 cijfers achter de komma",
"provider_error" : "${provider} fout",
"use_ssl" : "Gebruik SSL"
}

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" : "WAŻNY:\nJeśli chcesz otrzymać gwarantowaną kwotę BTC, wprowadź tę kwotę w polu BTC. Jeśli zamiast tego wpiszesz kwotę XMR, otrzymana kwota BTC jest szacunkowa i może się zmieniać w zależności od stawek.",
"amount_is_guaranteed" : "W xmr.to, aby otrzymać gwarantowaną kwotę BTC, wprowadź kwotę BTC, a nie kwotę XMR powyżej",
"amount_is_estimate" : "Otrzymana kwota jest wartością szacunkową",
"powered_by" : "Zasilany przez ${title}",
"error" : "Błąd",
@ -129,6 +129,11 @@
"remove" : "Usunąć",
"delete" : "Kasować",
"add_new_node" : "Dodaj nowy węzeł",
"change_current_node_title" : "Zmień bieżący węzeł",
"node_test" : "Test",
"node_connection_successful" : "Połączenie powiodło się",
"node_connection_failed" : "Połączenie nie powiodło się",
"new_node_testing" : "Testowanie nowych węzłów",
"use" : "Używać ",
@ -407,5 +412,16 @@
"seed_alert_back" : "Wróć",
"seed_alert_yes" : "Tak",
"exchange_sync_alert_content" : "Poczekaj, aż portfel zostanie zsynchronizowany"
"exchange_sync_alert_content" : "Poczekaj, aż portfel zostanie zsynchronizowany",
"pre_seed_title" : "WAŻNY",
"pre_seed_description" : "Na następnej stronie zobaczysz serię 25 słów. To jest Twoje unikalne i prywatne ziarno i jest to JEDYNY sposób na odzyskanie portfela w przypadku utraty lub awarii. Twoim obowiązkiem jest zapisanie go i przechowywanie w bezpiecznym miejscu poza aplikacją Cake Wallet.",
"pre_seed_button_text" : "Rozumiem. Pokaż mi moje nasienie",
"xmr_to_error" : "Pomyłka XMR.TO",
"xmr_to_error_description" : "Nieprawidłowa kwota. Maksymalny limit 8 cyfr po przecinku",
"provider_error" : "${provider} pomyłka",
"use_ssl" : "Użyj SSL"
}

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" : "IMPORTANTE:\nSe você deseja receber um valor garantido de BTC, insira esse valor no campo BTC. Se, em vez disso, você inserir um valor XMR, o valor BTC recebido é uma estimativa e pode flutuar dependendo das taxas.",
"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_estimate" : "O valor a ser recebido informado acima é uma estimativa",
"powered_by" : "Troca realizada por ${title}",
"error" : "Erro",
@ -129,6 +129,11 @@
"remove" : "Remover",
"delete" : "Excluir",
"add_new_node" : "Adicionar novo nó",
"change_current_node_title" : "Mudar o nó atual",
"node_test" : "Teste",
"node_connection_successful" : "A conexão foi bem sucedida",
"node_connection_failed" : "A conexão falhou",
"new_node_testing" : "Teste de novo nó",
"use" : "Use PIN de ",
@ -407,5 +412,16 @@
"seed_alert_back" : "Volte",
"seed_alert_yes" : "Sim, eu tenho",
"exchange_sync_alert_content" : "Por favor, espere até que sua carteira seja sincronizada"
"exchange_sync_alert_content" : "Por favor, espere até que sua carteira seja sincronizada",
"pre_seed_title" : "IMPORTANTE",
"pre_seed_description" : "Na próxima página, você verá uma série de 25 palavras. Esta é a sua semente única e privada e é a ÚNICA maneira de recuperar sua carteira em caso de perda ou mau funcionamento. É SUA responsabilidade anotá-lo e armazená-lo em um local seguro fora do aplicativo Cake Wallet.",
"pre_seed_button_text" : "Compreendo. Me mostre minha semente",
"xmr_to_error" : "Erro XMR.TO",
"xmr_to_error_description" : "Montante inválido. Limite máximo de 8 dígitos após o ponto decimal",
"provider_error" : "${provider} erro",
"use_ssl" : "Use SSL"
}

View file

@ -65,7 +65,7 @@
"change_exchange_provider" : "Изменить провайдера обмена",
"you_will_send" : "Конвертировать из",
"you_will_get" : "Конвертировать в",
"amount_is_guaranteed" : "ВАЖНО:\nЕсли вы хотите получить гарантированную сумму BTC, введите эту сумму в поле BTC. Если вместо этого вы вводите сумму XMR, полученная сумма BTC является приблизительной и может колебаться в зависимости от курса.",
"amount_is_guaranteed" : "В xmr.to, чтобы получить гарантированную сумму BTC, введите сумму BTC, а не сумму XMR выше",
"amount_is_estimate" : "Полученная сумма является приблизительной",
"powered_by" : "Используя ${title}",
"error" : "Ошибка",
@ -129,6 +129,11 @@
"remove" : "Удалить",
"delete" : "Удалить",
"add_new_node" : "Добавить новую ноду",
"change_current_node_title" : "Изменить текущую ноду",
"node_test" : "Тест",
"node_connection_successful" : "Подключение прошло успешно",
"node_connection_failed" : "Подключение не удалось",
"new_node_testing" : "Тестирование новой ноды",
"use" : "Использовать ",
@ -407,5 +412,16 @@
"seed_alert_back" : "Назад",
"seed_alert_yes" : "Да",
"exchange_sync_alert_content" : "Подождите, пока ваш кошелек синхронизируется"
"exchange_sync_alert_content" : "Подождите, пока ваш кошелек синхронизируется",
"pre_seed_title" : "ВАЖНО",
"pre_seed_description" : "На следующей странице вы увидите серию из 25 слов. Это ваша уникальная и личная мнемоническая фраза, и это ЕДИНСТВЕННЫЙ способ восстановить свой кошелек в случае потери или неисправности. ВАМ необходимо записать ее и хранить в надежном месте вне приложения Cake Wallet.",
"pre_seed_button_text" : "Понятно. Покажите мнемоническую фразу",
"xmr_to_error" : "Ошибка XMR.TO",
"xmr_to_error_description" : "Недопустимая сумма. Максимум 8 цифр после десятичной точки",
"provider_error" : "${provider} ошибка",
"use_ssl" : "Использовать SSL"
}

View file

@ -65,7 +65,7 @@
"change_exchange_provider" : "Змінити провайдера обміну",
"you_will_send" : "Конвертувати з",
"you_will_get" : "Конвертувати в",
"amount_is_guaranteed" : "ВАЖЛИВО:\nЯкщо ви хочете отримати гарантовану суму BTC, введіть цю суму в поле BTC. Якщо замість цього ввести суму XMR, отримана сума BTC є приблизною і може коливатися залежно від курсу.",
"amount_is_guaranteed" : "У xmr.to, щоб отримати гарантовану суму BTC, введіть суму BTC, а не XMR вище",
"amount_is_estimate" : "Отримана сума є приблизною",
"powered_by" : "Використовуючи ${title}",
"error" : "Помилка",
@ -129,6 +129,11 @@
"remove" : "Видалити",
"delete" : "Видалити",
"add_new_node" : "Додати новий вузол",
"change_current_node_title" : "Змінити поточний вузол",
"node_test" : "Тест",
"node_connection_successful" : "З'єднання було успішним",
"node_connection_failed" : "Помилка з’єднання",
"new_node_testing" : "Тестування нового вузла",
"use" : "Використати ",
@ -407,5 +412,16 @@
"seed_alert_back" : "Назад",
"seed_alert_yes" : "Так",
"exchange_sync_alert_content" : "Зачекайте, поки ваш гаманець не синхронізується"
"exchange_sync_alert_content" : "Зачекайте, поки ваш гаманець не синхронізується",
"pre_seed_title" : "ВАЖЛИВО",
"pre_seed_description" : "На наступній сторінці ви побачите серію з 25 слів. Це ваша унікальна та приватна мнемонічна фраза, і це ЄДИНИЙ спосіб відновити ваш гаманець на випадок втрати або несправності. ВАМ необхідно записати її та зберігати в безпечному місці поза програмою Cake Wallet.",
"pre_seed_button_text" : "Зрозуміло. Покажіть мнемонічну фразу",
"xmr_to_error" : "Помилка XMR.TO",
"xmr_to_error_description" : "Неприпустима сума. Максимум 8 цифр після десяткової коми",
"provider_error" : "${provider} помилка",
"use_ssl" : "Використати SSL"
}

View file

@ -65,7 +65,7 @@
"change_exchange_provider" : "更改交易所提供商",
"you_will_send" : "從轉換",
"you_will_get" : "轉換成",
"amount_is_guaranteed" : "重要:\n如果您想獲得保證的BTC金額請在BTC字段中輸入該金額。 如果您輸入的是XMR金額則收到的BTC金額只是估算值可能會隨匯率而波動。",
"amount_is_guaranteed" : "在xmr.to中要接收保证的BTC数量请输入BTC数量而不要输入上方的XMR数量",
"amount_is_estimate" : "收款金额为估算值",
"powered_by" : "供电 ${title}",
"error" : "错误",
@ -129,6 +129,11 @@
"remove" : "去掉",
"delete" : "删除",
"add_new_node" : "添加新節點",
"change_current_node_title" : "更改當前節點",
"node_test" : "測試",
"node_connection_successful" : "連接成功",
"node_connection_failed" : "連接失敗",
"new_node_testing" : "新節點測試",
"use" : "採用 ",
@ -407,5 +412,16 @@
"seed_alert_back" : "回去",
"seed_alert_yes" : "是的,我有",
"exchange_sync_alert_content" : "請等待,直到您的錢包同步"
"exchange_sync_alert_content" : "請等待,直到您的錢包同步",
"pre_seed_title" : "重要",
"pre_seed_description" : "在下一頁上您將看到一系列25個單詞。 這是您獨特的私人種子,是丟失或出現故障時恢復錢包的唯一方法。 您有責任將其寫下並存儲在Cake Wallet應用程序外部的安全地方。",
"pre_seed_button_text" : "我明白。 給我看我的種子",
"xmr_to_error" : "XMR.TO錯誤",
"xmr_to_error_description" : "無效的金額。 小數點後最多8位數字",
"provider_error" : "${provider} 錯誤",
"use_ssl" : "使用SSL"
}