diff --git a/assets/nano_node_list.yml b/assets/nano_node_list.yml index 63b4baec1..2e4d1ec3c 100644 --- a/assets/nano_node_list.yml +++ b/assets/nano_node_list.yml @@ -3,4 +3,26 @@ useSSL: true is_default: true - - uri: node.perish.co:9076 \ No newline at end of file + uri: node.nautilus.io + path: /api + useSSL: true +- + uri: app.natrium.io + path: /api + useSSL: true +- + uri: rainstorm.city + path: /api + useSSL: true +- + uri: node.somenano.com + path: /proxy + useSSL: true +- + uri: nanoslo.0x.no + path: /proxy + useSSL: true +- + uri: www.bitrequest.app + port: 8020 + useSSL: true \ No newline at end of file diff --git a/cw_core/lib/n2_node.dart b/cw_core/lib/n2_node.dart new file mode 100644 index 000000000..0fad9d1b5 --- /dev/null +++ b/cw_core/lib/n2_node.dart @@ -0,0 +1,31 @@ +class N2Node { + N2Node({ + this.weight, + this.uptime, + this.score, + this.account, + this.alias, + }); + + String? uptime; + double? weight; + int? score; + String? account; + String? alias; + + factory N2Node.fromJson(Map json) => N2Node( + weight: double.tryParse((json['weight'] as num).toString()), + uptime: json['uptime'] as String?, + score: json['score'] as int?, + account: json['rep_address'] as String?, + alias: json['alias'] as String?, + ); + + Map toJson() => { + 'uptime': uptime, + 'weight': weight, + 'score': score, + 'rep_address': account, + 'alias': alias, + }; +} diff --git a/cw_core/lib/node.dart b/cw_core/lib/node.dart index 585bc3c38..d7e91d692 100644 --- a/cw_core/lib/node.dart +++ b/cw_core/lib/node.dart @@ -21,6 +21,7 @@ class Node extends HiveObject with Keyable { this.trusted = false, this.socksProxyAddress, String? uri, + String? path, WalletType? type, }) { if (uri != null) { @@ -29,10 +30,14 @@ class Node extends HiveObject with Keyable { if (type != null) { this.type = type; } + if (path != null) { + this.path = path; + } } Node.fromMap(Map map) : uriRaw = map['uri'] as String? ?? '', + path = map['path'] as String? ?? '', login = map['login'] as String?, password = map['password'] as String?, useSSL = map['useSSL'] as bool?, @@ -63,6 +68,9 @@ class Node extends HiveObject with Keyable { @HiveField(6) String? socksProxyAddress; + @HiveField(7, defaultValue: '') + String? path; + bool get isSSL => useSSL ?? false; bool get useSocksProxy => socksProxyAddress == null ? false : socksProxyAddress!.isNotEmpty; @@ -79,9 +87,9 @@ class Node extends HiveObject with Keyable { case WalletType.nano: case WalletType.banano: if (isSSL) { - return Uri.https(uriRaw, ''); + return Uri.https(uriRaw, path ?? ''); } else { - return Uri.http(uriRaw, ''); + return Uri.http(uriRaw, path ?? ''); } case WalletType.ethereum: case WalletType.polygon: @@ -103,7 +111,8 @@ class Node extends HiveObject with Keyable { other.typeRaw == typeRaw && other.useSSL == useSSL && other.trusted == trusted && - other.socksProxyAddress == socksProxyAddress); + other.socksProxyAddress == socksProxyAddress && + other.path == path); @override int get hashCode => @@ -113,7 +122,8 @@ class Node extends HiveObject with Keyable { typeRaw.hashCode ^ useSSL.hashCode ^ trusted.hashCode ^ - socksProxyAddress.hashCode; + socksProxyAddress.hashCode ^ + path.hashCode; @override dynamic get keyIndex { diff --git a/cw_nano/lib/nano_client.dart b/cw_nano/lib/nano_client.dart index 661fbcab8..064a0bdee 100644 --- a/cw_nano/lib/nano_client.dart +++ b/cw_nano/lib/nano_client.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'dart:convert'; import 'package:cw_core/nano_account_info_response.dart'; +import 'package:cw_core/n2_node.dart'; import 'package:cw_nano/nano_balance.dart'; import 'package:cw_nano/nano_transaction_model.dart'; import 'package:http/http.dart' as http; @@ -16,6 +17,8 @@ class NanoClient { "nano-app": "cake-wallet" }; + static const String N2_REPS_ENDPOINT = "https://rpc.nano.to"; + NanoClient() { SharedPreferences.getInstance().then((value) => prefs = value); } @@ -418,7 +421,7 @@ class NanoClient { body: jsonEncode({ "action": "account_history", "account": address, - "count": "250", // TODO: pick a number + "count": "100", // "raw": true, })); final data = await jsonDecode(response.body); @@ -434,4 +437,37 @@ class NanoClient { return []; } } + + Future> getN2Reps() async { + final response = await http.post( + Uri.parse(N2_REPS_ENDPOINT), + headers: CAKE_HEADERS, + body: jsonEncode({"action": "reps"}), + ); + try { + final List nodes = (json.decode(response.body) as List) + .map((dynamic e) => N2Node.fromJson(e as Map)) + .toList(); + return nodes; + } catch (error) { + return []; + } + } + + Future getRepScore(String rep) async { + final response = await http.post( + Uri.parse(N2_REPS_ENDPOINT), + headers: CAKE_HEADERS, + body: jsonEncode({ + "action": "rep_info", + "account": rep, + }), + ); + try { + final N2Node node = N2Node.fromJson(json.decode(response.body) as Map); + return node.score ?? 100; + } catch (error) { + return 100; + } + } } diff --git a/cw_nano/lib/nano_wallet.dart b/cw_nano/lib/nano_wallet.dart index 1f6ec36ae..265f78eb7 100644 --- a/cw_nano/lib/nano_wallet.dart +++ b/cw_nano/lib/nano_wallet.dart @@ -13,6 +13,7 @@ import 'package:cw_core/transaction_priority.dart'; import 'package:cw_core/wallet_info.dart'; import 'package:cw_nano/file.dart'; import 'package:cw_core/nano_account.dart'; +import 'package:cw_core/n2_node.dart'; import 'package:cw_nano/nano_balance.dart'; import 'package:cw_nano/nano_client.dart'; import 'package:cw_nano/nano_transaction_credentials.dart'; @@ -65,9 +66,11 @@ abstract class NanoWalletBase String? _privateKey; String? _publicAddress; String? _hexSeed; + Timer? _receiveTimer; String? _representativeAddress; - Timer? _receiveTimer; + int repScore = 100; + bool get isRepOk => repScore >= 90; late final NanoClient _client; bool _isTransactionUpdating; @@ -375,7 +378,7 @@ abstract class NanoWalletBase final data = json.decode(jsonSource) as Map; final mnemonic = data['mnemonic'] as String; - + final balance = NanoBalance.fromRawString( currentBalance: data['currentBalance'] as String? ?? "0", receivableBalance: data['receivableBalance'] as String? ?? "0", @@ -429,6 +432,8 @@ abstract class NanoWalletBase _representativeAddress = await _client.getRepFromPrefs(); throw Exception("Failed to get representative address $e"); } + + repScore = await _client.getRepScore(_representativeAddress!); } Future regenerateAddress() async { @@ -465,6 +470,10 @@ abstract class NanoWalletBase } } + Future> getN2Reps() async { + return _client.getN2Reps(); + } + Future? updateBalance() async => await _updateBalance(); @override diff --git a/lib/core/node_address_validator.dart b/lib/core/node_address_validator.dart index 0e034dabc..c1fe4ba91 100644 --- a/lib/core/node_address_validator.dart +++ b/lib/core/node_address_validator.dart @@ -8,3 +8,8 @@ class NodeAddressValidator extends TextValidator { pattern: '^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\$|^[0-9a-zA-Z.\-]+\$'); } + +class NodePathValidator extends TextValidator { + NodePathValidator() + : super(errorMessage: S.current.error_text_node_address, pattern: '^([/0-9a-zA-Z.\-]+)?\$'); +} diff --git a/lib/entities/default_settings_migration.dart b/lib/entities/default_settings_migration.dart index 9a2db56af..a0f570e95 100644 --- a/lib/entities/default_settings_migration.dart +++ b/lib/entities/default_settings_migration.dart @@ -216,6 +216,10 @@ Future defaultSettingsMigration( await disableServiceStatusFiatDisabled(sharedPreferences); break; + case 31: + await updateNanoNodeList(nodes: nodes); + break; + default: break; } @@ -230,9 +234,35 @@ Future defaultSettingsMigration( await sharedPreferences.setInt(PreferencesKey.currentDefaultSettingsMigrationVersion, version); } +Future updateNanoNodeList({required Box nodes}) async { + final nodeList = await loadDefaultNanoNodes(); + var listOfNewEndpoints = [ + "app.natrium.io", + "rainstorm.city", + "node.somenano.com", + "nanoslo.0x.no", + "www.bitrequest.app", + ]; + // add new nodes: + for (final node in nodeList) { + if (listOfNewEndpoints.contains(node.uriRaw)) { + await nodes.add(node); + } + } + + // update the nautilus node: + final nautilusNode = + nodes.values.firstWhereOrNull((element) => element.uriRaw == "node.perish.co"); + if (nautilusNode != null) { + nautilusNode.uriRaw = "node.nautilus.io"; + nautilusNode.path = "/api"; + nautilusNode.useSSL = true; + await nautilusNode.save(); + } +} + Future disableServiceStatusFiatDisabled(SharedPreferences sharedPreferences) async { - final currentFiat = - await sharedPreferences.getInt(PreferencesKey.currentFiatApiModeKey) ?? -1; + final currentFiat = await sharedPreferences.getInt(PreferencesKey.currentFiatApiModeKey) ?? -1; if (currentFiat == -1 || currentFiat == FiatApiMode.enabled.raw) { return; } diff --git a/lib/entities/preferences_key.dart b/lib/entities/preferences_key.dart index 80a7acba1..f512d6b72 100644 --- a/lib/entities/preferences_key.dart +++ b/lib/entities/preferences_key.dart @@ -45,6 +45,7 @@ class PreferencesKey { static const customBitcoinFeeRate = 'custom_electrum_fee_rate'; static const shouldShowReceiveWarning = 'should_show_receive_warning'; static const shouldShowYatPopup = 'should_show_yat_popup'; + static const shouldShowRepWarning = 'should_show_rep_warning'; static const moneroWalletPasswordUpdateV1Base = 'monero_wallet_update_v1'; static const syncModeKey = 'sync_mode'; static const syncAllKey = 'sync_all'; diff --git a/lib/main.dart b/lib/main.dart index 6868348f6..b80c9eb85 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -163,7 +163,7 @@ Future initializeAppConfigs() async { transactionDescriptions: transactionDescriptions, secureStorage: secureStorage, anonpayInvoiceInfo: anonpayInvoiceInfo, - initialMigrationVersion: 30, + initialMigrationVersion: 31, ); } diff --git a/lib/nano/cw_nano.dart b/lib/nano/cw_nano.dart index 06ebf60c2..5896f7c26 100644 --- a/lib/nano/cw_nano.dart +++ b/lib/nano/cw_nano.dart @@ -186,6 +186,16 @@ class CWNano extends Nano { String getRepresentative(Object wallet) { return (wallet as NanoWallet).representative; } + + @override + Future> getN2Reps(Object wallet) async { + return (wallet as NanoWallet).getN2Reps(); + } + + @override + bool isRepOk(Object wallet) { + return (wallet as NanoWallet).isRepOk; + } } class CWNanoUtil extends NanoUtil { diff --git a/lib/src/screens/dashboard/pages/balance_page.dart b/lib/src/screens/dashboard/pages/balance_page.dart index 0b7596469..a2ad3fb80 100644 --- a/lib/src/screens/dashboard/pages/balance_page.dart +++ b/lib/src/screens/dashboard/pages/balance_page.dart @@ -8,6 +8,7 @@ import 'package:cake_wallet/src/screens/dashboard/pages/nft_listing_page.dart'; import 'package:cake_wallet/src/screens/dashboard/widgets/home_screen_account_widget.dart'; import 'package:cake_wallet/src/widgets/cake_image_widget.dart'; import 'package:cake_wallet/src/screens/exchange_trade/information_page.dart'; +import 'package:cake_wallet/src/widgets/dashboard_card_widget.dart'; import 'package:cake_wallet/src/widgets/introducing_card.dart'; import 'package:cake_wallet/store/settings_store.dart'; import 'package:cake_wallet/themes/extensions/balance_page_theme.dart'; @@ -183,6 +184,22 @@ class CryptoBalanceWidget extends StatelessWidget { return Container(); }, ), + Observer(builder: (_) { + if (!dashboardViewModel.showRepWarning) { + return const SizedBox(); + } + return Padding( + padding: const EdgeInsets.fromLTRB(16, 0, 16, 8), + child: DashBoardRoundedCardWidget( + title: S.current.rep_warning, + subTitle: S.current.rep_warning_sub, + onTap: () => Navigator.of(context).pushNamed(Routes.changeRep), + onClose: () { + dashboardViewModel.settingsStore.shouldShowRepWarning = false; + }, + ), + ); + }), Observer( builder: (_) { return ListView.separated( diff --git a/lib/src/screens/nano/nano_change_rep_page.dart b/lib/src/screens/nano/nano_change_rep_page.dart index a625f7e29..9f71bb59c 100644 --- a/lib/src/screens/nano/nano_change_rep_page.dart +++ b/lib/src/screens/nano/nano_change_rep_page.dart @@ -5,10 +5,12 @@ import 'package:cake_wallet/src/widgets/alert_with_one_action.dart'; import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart'; import 'package:cake_wallet/store/settings_store.dart'; import 'package:cake_wallet/themes/extensions/address_theme.dart'; +import 'package:cake_wallet/themes/extensions/cake_text_theme.dart'; import 'package:cake_wallet/utils/payment_request.dart'; import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:cw_core/crypto_currency.dart'; import 'package:cw_core/wallet_base.dart'; +import 'package:cw_core/n2_node.dart'; import 'package:flutter/material.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:cake_wallet/generated/i18n.dart'; @@ -21,9 +23,7 @@ class NanoChangeRepPage extends BasePage { : _wallet = wallet, _settingsStore = settingsStore, _addressController = TextEditingController(), - _formKey = GlobalKey() { - _addressController.text = nano!.getRepresentative(wallet); - } + _formKey = GlobalKey() {} final TextEditingController _addressController; final WalletBase _wallet; @@ -34,105 +34,314 @@ class NanoChangeRepPage extends BasePage { @override String get title => S.current.change_rep; + N2Node getCurrentRepNode(List nodes) { + final currentRepAccount = nano!.getRepresentative(_wallet); + final currentNode = nodes.firstWhere( + (node) => node.account == currentRepAccount, + orElse: () => N2Node( + account: currentRepAccount, + alias: currentRepAccount, + score: 0, + uptime: "???", + weight: 0, + ), + ); + + return currentNode; + } + @override Widget body(BuildContext context) { return Form( key: _formKey, - child: Container( - padding: EdgeInsets.only(left: 24, right: 24), - child: ScrollableWithBottomSection( - contentPadding: EdgeInsets.only(bottom: 24.0), - content: Container( - child: Column( - children: [ - Row( - children: [ - Expanded( - child: AddressTextField( - controller: _addressController, - onURIScanned: (uri) { - final paymentRequest = PaymentRequest.fromUri(uri); - _addressController.text = paymentRequest.address; - }, - options: [ - AddressTextFieldOption.paste, - AddressTextFieldOption.qrCode, - ], - buttonColor: Theme.of(context).extension()!.actionButtonColor, - validator: AddressValidator(type: CryptoCurrency.nano), + child: FutureBuilder( + future: nano!.getN2Reps(_wallet), + builder: (context, snapshot) { + if (snapshot.data == null) { + return SizedBox(); + } + + return Container( + padding: EdgeInsets.only(left: 24, right: 24), + child: ScrollableWithBottomSection( + topSectionPadding: EdgeInsets.only(bottom: 24), + topSection: Column( + children: [ + Row( + children: [ + Expanded( + child: AddressTextField( + controller: _addressController, + onURIScanned: (uri) { + final paymentRequest = PaymentRequest.fromUri(uri); + _addressController.text = paymentRequest.address; + }, + options: [ + AddressTextFieldOption.paste, + AddressTextFieldOption.qrCode, + ], + buttonColor: + Theme.of(context).extension()!.actionButtonColor, + validator: AddressValidator(type: CryptoCurrency.nano), + ), + ) + ], + ), + Column( + children: [ + Container( + margin: EdgeInsets.only(top: 12), + child: Text( + S.current.nano_current_rep, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w700, + ), + ), ), - ) - ], + _buildSingleRepresentative( + context, + getCurrentRepNode(snapshot.data as List), + isList: false, + ), + Divider(height: 20), + Container( + margin: EdgeInsets.only(top: 12), + child: Text( + S.current.nano_pick_new_rep, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w700, + ), + ), + ), + ], + ), + ], + ), + contentPadding: EdgeInsets.only(bottom: 24), + content: Container( + child: Column( + children: _getRepresentativeWidgets(context, snapshot.data as List), + ), + ), + bottomSectionPadding: EdgeInsets.only(bottom: 24), + bottomSection: Observer( + builder: (_) => Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Flexible( + child: Container( + padding: EdgeInsets.only(right: 8.0), + child: LoadingPrimaryButton( + onPressed: () => _onSubmit(context), + text: S.of(context).change, + color: Theme.of(context).primaryColor, + textColor: Colors.white, + ), + )), + ], + )), + ), + ); + }, + ), + ); + } + + Future _onSubmit(BuildContext context) async { + if (_formKey.currentState != null && !_formKey.currentState!.validate()) { + return; + } + + final confirmed = await showPopUp( + context: context, + builder: (BuildContext context) { + return AlertWithTwoActions( + alertTitle: S.of(context).change_rep, + alertContent: S.of(context).change_rep_message, + rightButtonText: S.of(context).change, + leftButtonText: S.of(context).cancel, + actionRightButton: () => Navigator.pop(context, true), + actionLeftButton: () => Navigator.pop(context, false)); + }) ?? + false; + + if (confirmed) { + try { + _settingsStore.defaultNanoRep = _addressController.text; + + await nano!.changeRep(_wallet, _addressController.text); + + // reset this flag whenever we successfully change reps: + _settingsStore.shouldShowRepWarning = true; + + await showPopUp( + context: context, + builder: (BuildContext context) { + return AlertWithOneAction( + alertTitle: S.of(context).successful, + alertContent: S.of(context).change_rep_successful, + buttonText: S.of(context).ok, + buttonAction: () => Navigator.pop(context)); + }); + } catch (e) { + await showPopUp( + context: context, + builder: (BuildContext context) { + return AlertWithOneAction( + alertTitle: S.of(context).error, + alertContent: e.toString(), + buttonText: S.of(context).ok, + buttonAction: () => Navigator.pop(context)); + }); + throw e; + } + } + } + + List _getRepresentativeWidgets(BuildContext context, List? list) { + if (list == null) { + return []; + } + final List ret = []; + for (final N2Node node in list) { + if (node.alias != null && node.alias!.trim().isNotEmpty) { + ret.add(_buildSingleRepresentative(context, node)); + } + } + return ret; + } + + Widget _buildSingleRepresentative(BuildContext context, N2Node rep, {bool isList = true}) { + return Column( + children: [ + if (isList) + Divider( + height: 2, + ), + TextButton( + style: TextButton.styleFrom( + padding: EdgeInsets.zero, + ), + onPressed: () async { + if (!isList) { + return; + } + _addressController.text = rep.account!; + }, + child: Container( + margin: const EdgeInsets.symmetric(vertical: 20), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + margin: const EdgeInsetsDirectional.only(start: 24), + width: MediaQuery.of(context).size.width * 0.50, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + _sanitizeAlias(rep.alias), + style: TextStyle( + color: Theme.of(context).extension()!.titleColor, + fontWeight: FontWeight.w700, + fontSize: 18, + ), + ), + Container( + margin: const EdgeInsets.only(top: 7), + child: RichText( + text: TextSpan( + text: "${S.current.voting_weight}: ${rep.weight.toString()}%", + style: TextStyle( + color: + Theme.of(context).extension()!.secondaryTextColor, + fontWeight: FontWeight.w700, + fontSize: 14.0, + ), + ), + ), + ), + Container( + margin: const EdgeInsets.only(top: 4), + child: RichText( + text: TextSpan( + text: '', + children: [ + TextSpan( + text: "${S.current.uptime}: ", + style: TextStyle( + color: Theme.of(context) + .extension()! + .secondaryTextColor, + fontWeight: FontWeight.w700, + fontSize: 14, + ), + ), + TextSpan( + text: rep.uptime, + style: TextStyle( + color: Theme.of(context) + .extension()! + .secondaryTextColor, + fontWeight: FontWeight.w900, + fontSize: 14, + ), + ), + ], + ), + ), + ), + ], + ), + ), + Container( + margin: const EdgeInsetsDirectional.only(end: 24, start: 14), + child: Stack( + children: [ + Icon( + Icons.verified, + color: Theme.of(context).primaryColor, + size: 50, + ), + Positioned.fill( + child: Container( + margin: EdgeInsets.all(13), + color: Theme.of(context).primaryColor, + ), + ), + Container( + alignment: const AlignmentDirectional(-0.03, 0.03), + width: 50, + height: 50, + child: Text( + (rep.score).toString(), + textAlign: TextAlign.center, + style: TextStyle( + color: Theme.of(context).extension()!.titleColor, + fontSize: 13, + fontWeight: FontWeight.w800, + ), + ), + ), + ], + ), ), ], ), ), - bottomSectionPadding: EdgeInsets.only(bottom: 24), - bottomSection: Observer( - builder: (_) => Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Flexible( - child: Container( - padding: EdgeInsets.only(right: 8.0), - child: LoadingPrimaryButton( - onPressed: () async { - if (_formKey.currentState != null && - !_formKey.currentState!.validate()) { - return; - } - - final confirmed = await showPopUp( - context: context, - builder: (BuildContext context) { - return AlertWithTwoActions( - alertTitle: S.of(context).change_rep, - alertContent: S.of(context).change_rep_message, - rightButtonText: S.of(context).change, - leftButtonText: S.of(context).cancel, - actionRightButton: () => Navigator.pop(context, true), - actionLeftButton: () => Navigator.pop(context, false)); - }) ?? - false; - - if (confirmed) { - try { - _settingsStore.defaultNanoRep = _addressController.text; - - await nano!.changeRep(_wallet, _addressController.text); - - await showPopUp( - context: context, - builder: (BuildContext context) { - return AlertWithOneAction( - alertTitle: S.of(context).successful, - alertContent: S.of(context).change_rep_successful, - buttonText: S.of(context).ok, - buttonAction: () => Navigator.pop(context)); - }); - } catch (e) { - await showPopUp( - context: context, - builder: (BuildContext context) { - return AlertWithOneAction( - alertTitle: S.of(context).error, - alertContent: e.toString(), - buttonText: S.of(context).ok, - buttonAction: () => Navigator.pop(context)); - }); - throw e; - } - } - }, - text: S.of(context).change, - color: Theme.of(context).primaryColor, - textColor: Colors.white, - ), - )), - ], - )), ), - ), + ], ); } + + String _sanitizeAlias(String? alias) { + if (alias != null) { + return alias.replaceAll(RegExp(r'[^a-zA-Z_.!?_;:-]'), ''); + } + return ''; + } } diff --git a/lib/src/screens/nodes/node_create_or_edit_page.dart b/lib/src/screens/nodes/node_create_or_edit_page.dart index 50c1c3be5..53c34f302 100644 --- a/lib/src/screens/nodes/node_create_or_edit_page.dart +++ b/lib/src/screens/nodes/node_create_or_edit_page.dart @@ -18,6 +18,7 @@ class NodeCreateOrEditPage extends BasePage { NodeCreateOrEditPage({required this.nodeCreateOrEditViewModel,this.editingNode, this.isSelected}) : _formKey = GlobalKey(), _addressController = TextEditingController(), + _pathController = TextEditingController(), _portController = TextEditingController(), _loginController = TextEditingController(), _passwordController = TextEditingController() { @@ -49,6 +50,8 @@ class NodeCreateOrEditPage extends BasePage { _addressController.addListener( () => nodeCreateOrEditViewModel.address = _addressController.text); + _pathController.addListener( + () => nodeCreateOrEditViewModel.path = _pathController.text); _portController.addListener( () => nodeCreateOrEditViewModel.port = _portController.text); _loginController.addListener( @@ -59,6 +62,7 @@ class NodeCreateOrEditPage extends BasePage { final GlobalKey _formKey; final TextEditingController _addressController; + final TextEditingController _pathController; final TextEditingController _portController; final TextEditingController _loginController; final TextEditingController _passwordController; diff --git a/lib/src/screens/nodes/widgets/node_form.dart b/lib/src/screens/nodes/widgets/node_form.dart index ab8dcafdf..e8c4b0ab3 100644 --- a/lib/src/screens/nodes/widgets/node_form.dart +++ b/lib/src/screens/nodes/widgets/node_form.dart @@ -16,13 +16,15 @@ class NodeForm extends StatelessWidget { required this.formKey, this.editingNode, }) : _addressController = TextEditingController(text: editingNode?.uri.host.toString()), + _pathController = TextEditingController(text: editingNode?.path.toString()), _portController = TextEditingController(text: editingNode?.uri.port.toString()), _loginController = TextEditingController(text: editingNode?.login), _passwordController = TextEditingController(text: editingNode?.password), - _socksAddressController = TextEditingController(text: editingNode?.socksProxyAddress){ + _socksAddressController = TextEditingController(text: editingNode?.socksProxyAddress) { if (editingNode != null) { nodeViewModel ..setAddress((editingNode!.uri.host.toString())) + ..setPath((editingNode!.path.toString())) ..setPort((editingNode!.uri.port.toString())) ..setPassword((editingNode!.password ?? '')) ..setLogin((editingNode!.login ?? '')) @@ -57,10 +59,12 @@ class NodeForm extends StatelessWidget { }); _addressController.addListener(() => nodeViewModel.address = _addressController.text); + _pathController.addListener(() => nodeViewModel.path = _pathController.text); _portController.addListener(() => nodeViewModel.port = _portController.text); _loginController.addListener(() => nodeViewModel.login = _loginController.text); _passwordController.addListener(() => nodeViewModel.password = _passwordController.text); - _socksAddressController.addListener(() => nodeViewModel.socksProxyAddress = _socksAddressController.text); + _socksAddressController + .addListener(() => nodeViewModel.socksProxyAddress = _socksAddressController.text); } final NodeCreateOrEditViewModel nodeViewModel; @@ -68,6 +72,7 @@ class NodeForm extends StatelessWidget { final Node? editingNode; final TextEditingController _addressController; + final TextEditingController _pathController; final TextEditingController _portController; final TextEditingController _loginController; final TextEditingController _passwordController; @@ -91,6 +96,18 @@ class NodeForm extends StatelessWidget { ], ), SizedBox(height: 10.0), + Row( + children: [ + Expanded( + child: BaseTextFormField( + controller: _pathController, + hintText: "/path", + validator: NodePathValidator(), + ), + ) + ], + ), + SizedBox(height: 10.0), Row( children: [ Expanded( @@ -103,6 +120,26 @@ class NodeForm extends StatelessWidget { ], ), SizedBox(height: 10.0), + Padding( + padding: EdgeInsets.only(top: 20), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + mainAxisSize: MainAxisSize.max, + children: [ + Observer( + builder: (_) => StandardCheckbox( + value: nodeViewModel.useSSL, + gradientBackground: true, + borderColor: Theme.of(context).dividerColor, + iconColor: Colors.white, + onChanged: (value) => nodeViewModel.useSSL = value, + caption: S.of(context).use_ssl, + ), + ) + ], + ), + ), + SizedBox(height: 10.0), if (nodeViewModel.hasAuthCredentials) ...[ Row( children: [ @@ -123,25 +160,6 @@ class NodeForm extends StatelessWidget { )) ], ), - Padding( - padding: EdgeInsets.only(top: 20), - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - mainAxisSize: MainAxisSize.max, - children: [ - Observer( - builder: (_) => StandardCheckbox( - value: nodeViewModel.useSSL, - gradientBackground: true, - borderColor: Theme.of(context).dividerColor, - iconColor: Colors.white, - onChanged: (value) => nodeViewModel.useSSL = value, - caption: S.of(context).use_ssl, - ), - ) - ], - ), - ), Padding( padding: EdgeInsets.only(top: 20), child: Row( @@ -163,44 +181,44 @@ class NodeForm extends StatelessWidget { ), Observer( builder: (_) => Column( - children: [ - Padding( - padding: EdgeInsets.only(top: 20), - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - mainAxisSize: MainAxisSize.max, - children: [ - StandardCheckbox( - value: nodeViewModel.useSocksProxy, - gradientBackground: true, - borderColor: Theme.of(context).dividerColor, - iconColor: Colors.white, - onChanged: (value) { - if (!value) { - _socksAddressController.text = ''; - } - nodeViewModel.useSocksProxy = value; - }, - caption: 'SOCKS Proxy', - ), - ], - ), - ), - if (nodeViewModel.useSocksProxy) ...[ - SizedBox(height: 10.0), - Row( - children: [ - Expanded( - child: BaseTextFormField( + children: [ + Padding( + padding: EdgeInsets.only(top: 20), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + mainAxisSize: MainAxisSize.max, + children: [ + StandardCheckbox( + value: nodeViewModel.useSocksProxy, + gradientBackground: true, + borderColor: Theme.of(context).dividerColor, + iconColor: Colors.white, + onChanged: (value) { + if (!value) { + _socksAddressController.text = ''; + } + nodeViewModel.useSocksProxy = value; + }, + caption: 'SOCKS Proxy', + ), + ], + ), + ), + if (nodeViewModel.useSocksProxy) ...[ + SizedBox(height: 10.0), + Row( + children: [ + Expanded( + child: BaseTextFormField( controller: _socksAddressController, hintText: '[:]', validator: SocksProxyNodeAddressValidator(), )) - ], - ), - ] - ], - )), + ], + ), + ] + ], + )), ] ], ), diff --git a/lib/src/widgets/dashboard_card_widget.dart b/lib/src/widgets/dashboard_card_widget.dart index b3f92123a..74f2d598b 100644 --- a/lib/src/widgets/dashboard_card_widget.dart +++ b/lib/src/widgets/dashboard_card_widget.dart @@ -4,15 +4,15 @@ import 'package:flutter/material.dart'; import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart'; class DashBoardRoundedCardWidget extends StatelessWidget { - - DashBoardRoundedCardWidget({ required this.onTap, required this.title, required this.subTitle, + this.onClose, }); final VoidCallback onTap; + final VoidCallback? onClose; final String title; final String subTitle; @@ -26,7 +26,7 @@ class DashBoardRoundedCardWidget extends StatelessWidget { child: Stack( children: [ Container( - padding: EdgeInsets.all(20), + padding: EdgeInsets.fromLTRB(20, 20, 40, 20), width: double.infinity, decoration: BoxDecoration( color: Theme.of(context).extension()!.syncedBackgroundColor, @@ -35,32 +35,40 @@ class DashBoardRoundedCardWidget extends StatelessWidget { color: Theme.of(context).extension()!.cardBorderColor, ), ), - child: - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - title, - style: TextStyle( - color: Theme.of(context).extension()!.cardTextColor, - fontSize: 24, - fontWeight: FontWeight.w900, - ), - ), - SizedBox(height: 5), - Text( - subTitle, - style: TextStyle( - color: Theme.of(context).extension()!.cardTextColor, - fontWeight: FontWeight.w500, - fontFamily: 'Lato'), - ) - ], + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + title, + style: TextStyle( + color: Theme.of(context).extension()!.cardTextColor, + fontSize: 24, + fontWeight: FontWeight.w900, + ), ), + SizedBox(height: 5), + Text( + subTitle, + style: TextStyle( + color: Theme.of(context).extension()!.cardTextColor, + fontWeight: FontWeight.w500, + fontFamily: 'Lato'), + ) + ], + ), ), + if (onClose != null) + Positioned( + top: 10, + right: 10, + child: IconButton( + icon: Icon(Icons.close), + onPressed: onClose, + color: Theme.of(context).extension()!.cardTextColor, + ), + ), ], ), ); } } - diff --git a/lib/src/widgets/scollable_with_bottom_section.dart b/lib/src/widgets/scollable_with_bottom_section.dart index 2487e6130..e15be610e 100644 --- a/lib/src/widgets/scollable_with_bottom_section.dart +++ b/lib/src/widgets/scollable_with_bottom_section.dart @@ -2,16 +2,21 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; class ScrollableWithBottomSection extends StatefulWidget { - ScrollableWithBottomSection( - {required this.content, - required this.bottomSection, - this.contentPadding, - this.bottomSectionPadding}); + ScrollableWithBottomSection({ + required this.content, + required this.bottomSection, + this.topSection, + this.contentPadding, + this.bottomSectionPadding, + this.topSectionPadding, + }); final Widget content; final Widget bottomSection; + final Widget? topSection; final EdgeInsets? contentPadding; final EdgeInsets? bottomSectionPadding; + final EdgeInsets? topSectionPadding; @override ScrollableWithBottomSectionState createState() => ScrollableWithBottomSectionState(); @@ -22,6 +27,12 @@ class ScrollableWithBottomSectionState extends State nodes, required Map powNodes, required this.shouldShowYatPopup, + required this.shouldShowRepWarning, required this.isBitcoinBuyEnabled, required this.actionlistDisplayMode, required this.pinTimeOutDuration, @@ -225,6 +226,9 @@ abstract class SettingsStoreBase with Store { (bool shouldShowYatPopup) => sharedPreferences.setBool(PreferencesKey.shouldShowYatPopup, shouldShowYatPopup)); + reaction((_) => shouldShowRepWarning, + (bool val) => sharedPreferences.setBool(PreferencesKey.shouldShowRepWarning, val)); + defaultBuyProviders.observe((change) { final String key = 'buyProvider_${change.key.toString()}'; if (change.newValue != null) { @@ -536,6 +540,9 @@ abstract class SettingsStoreBase with Store { @observable bool shouldShowYatPopup; + @observable + bool shouldShowRepWarning; + @observable bool shouldShowMarketPlaceInDashboard; @@ -878,6 +885,8 @@ abstract class SettingsStoreBase with Store { final packageInfo = await PackageInfo.fromPlatform(); final deviceName = await _getDeviceName() ?? ''; final shouldShowYatPopup = sharedPreferences.getBool(PreferencesKey.shouldShowYatPopup) ?? true; + final shouldShowRepWarning = + sharedPreferences.getBool(PreferencesKey.shouldShowRepWarning) ?? true; final generateSubaddresses = sharedPreferences.getInt(PreferencesKey.autoGenerateSubaddressStatusKey); @@ -1034,75 +1043,77 @@ abstract class SettingsStoreBase with Store { ''; return SettingsStore( - secureStorage: secureStorage, - sharedPreferences: sharedPreferences, - initialShouldShowMarketPlaceInDashboard: shouldShowMarketPlaceInDashboard, - nodes: nodes, - powNodes: powNodes, - appVersion: packageInfo.version, - deviceName: deviceName, - isBitcoinBuyEnabled: isBitcoinBuyEnabled, - initialFiatCurrency: currentFiatCurrency, - initialBalanceDisplayMode: currentBalanceDisplayMode, - initialSaveRecipientAddress: shouldSaveRecipientAddress, - initialAutoGenerateSubaddressStatus: autoGenerateSubaddressStatus, - initialMoneroSeedType: moneroSeedType, - initialAppSecure: isAppSecure, - initialDisableBuy: disableBuy, - initialDisableSell: disableSell, - initialDisableBulletin: disableBulletin, - initialWalletListOrder: walletListOrder, - initialWalletListAscending: walletListAscending, - initialFiatMode: currentFiatApiMode, - initialAllowBiometricalAuthentication: allowBiometricalAuthentication, - initialCake2FAPresetOptions: selectedCake2FAPreset, - initialUseTOTP2FA: useTOTP2FA, - initialTotpSecretKey: totpSecretKey, - initialFailedTokenTrial: tokenTrialNumber, - initialExchangeStatus: exchangeStatus, - initialTheme: savedTheme, - actionlistDisplayMode: actionListDisplayMode, - initialPinLength: pinLength, - pinTimeOutDuration: pinCodeTimeOutDuration, - seedPhraseLength: seedPhraseWordCount, - initialLanguageCode: savedLanguageCode, - sortBalanceBy: sortBalanceBy, - pinNativeTokenAtTop: pinNativeTokenAtTop, - useEtherscan: useEtherscan, - usePolygonScan: usePolygonScan, - defaultNanoRep: defaultNanoRep, - defaultBananoRep: defaultBananoRep, - lookupsTwitter: lookupsTwitter, - lookupsMastodon: lookupsMastodon, - lookupsYatService: lookupsYatService, - lookupsUnstoppableDomains: lookupsUnstoppableDomains, - lookupsOpenAlias: lookupsOpenAlias, - lookupsENS: lookupsENS, - customBitcoinFeeRate: customBitcoinFeeRate, - initialMoneroTransactionPriority: moneroTransactionPriority, - initialBitcoinTransactionPriority: bitcoinTransactionPriority, - initialHavenTransactionPriority: havenTransactionPriority, - initialLitecoinTransactionPriority: litecoinTransactionPriority, - initialBitcoinCashTransactionPriority: bitcoinCashTransactionPriority, - initialShouldRequireTOTP2FAForAccessingWallet: shouldRequireTOTP2FAForAccessingWallet, - initialShouldRequireTOTP2FAForSendsToContact: shouldRequireTOTP2FAForSendsToContact, - initialShouldRequireTOTP2FAForSendsToNonContact: shouldRequireTOTP2FAForSendsToNonContact, - initialShouldRequireTOTP2FAForSendsToInternalWallets: - shouldRequireTOTP2FAForSendsToInternalWallets, - initialShouldRequireTOTP2FAForExchangesToInternalWallets: - shouldRequireTOTP2FAForExchangesToInternalWallets, - initialShouldRequireTOTP2FAForExchangesToExternalWallets: - shouldRequireTOTP2FAForExchangesToExternalWallets, - initialShouldRequireTOTP2FAForAddingContacts: shouldRequireTOTP2FAForAddingContacts, - initialShouldRequireTOTP2FAForCreatingNewWallets: shouldRequireTOTP2FAForCreatingNewWallets, - initialShouldRequireTOTP2FAForAllSecurityAndBackupSettings: - shouldRequireTOTP2FAForAllSecurityAndBackupSettings, - initialEthereumTransactionPriority: ethereumTransactionPriority, - initialPolygonTransactionPriority: polygonTransactionPriority, - backgroundTasks: backgroundTasks, - initialSyncMode: savedSyncMode, - initialSyncAll: savedSyncAll, - shouldShowYatPopup: shouldShowYatPopup); + secureStorage: secureStorage, + sharedPreferences: sharedPreferences, + initialShouldShowMarketPlaceInDashboard: shouldShowMarketPlaceInDashboard, + nodes: nodes, + powNodes: powNodes, + appVersion: packageInfo.version, + deviceName: deviceName, + isBitcoinBuyEnabled: isBitcoinBuyEnabled, + initialFiatCurrency: currentFiatCurrency, + initialBalanceDisplayMode: currentBalanceDisplayMode, + initialSaveRecipientAddress: shouldSaveRecipientAddress, + initialAutoGenerateSubaddressStatus: autoGenerateSubaddressStatus, + initialMoneroSeedType: moneroSeedType, + initialAppSecure: isAppSecure, + initialDisableBuy: disableBuy, + initialDisableSell: disableSell, + initialDisableBulletin: disableBulletin, + initialWalletListOrder: walletListOrder, + initialWalletListAscending: walletListAscending, + initialFiatMode: currentFiatApiMode, + initialAllowBiometricalAuthentication: allowBiometricalAuthentication, + initialCake2FAPresetOptions: selectedCake2FAPreset, + initialUseTOTP2FA: useTOTP2FA, + initialTotpSecretKey: totpSecretKey, + initialFailedTokenTrial: tokenTrialNumber, + initialExchangeStatus: exchangeStatus, + initialTheme: savedTheme, + actionlistDisplayMode: actionListDisplayMode, + initialPinLength: pinLength, + pinTimeOutDuration: pinCodeTimeOutDuration, + seedPhraseLength: seedPhraseWordCount, + initialLanguageCode: savedLanguageCode, + sortBalanceBy: sortBalanceBy, + pinNativeTokenAtTop: pinNativeTokenAtTop, + useEtherscan: useEtherscan, + usePolygonScan: usePolygonScan, + defaultNanoRep: defaultNanoRep, + defaultBananoRep: defaultBananoRep, + lookupsTwitter: lookupsTwitter, + lookupsMastodon: lookupsMastodon, + lookupsYatService: lookupsYatService, + lookupsUnstoppableDomains: lookupsUnstoppableDomains, + lookupsOpenAlias: lookupsOpenAlias, + lookupsENS: lookupsENS, + customBitcoinFeeRate: customBitcoinFeeRate, + initialMoneroTransactionPriority: moneroTransactionPriority, + initialBitcoinTransactionPriority: bitcoinTransactionPriority, + initialHavenTransactionPriority: havenTransactionPriority, + initialLitecoinTransactionPriority: litecoinTransactionPriority, + initialBitcoinCashTransactionPriority: bitcoinCashTransactionPriority, + initialShouldRequireTOTP2FAForAccessingWallet: shouldRequireTOTP2FAForAccessingWallet, + initialShouldRequireTOTP2FAForSendsToContact: shouldRequireTOTP2FAForSendsToContact, + initialShouldRequireTOTP2FAForSendsToNonContact: shouldRequireTOTP2FAForSendsToNonContact, + initialShouldRequireTOTP2FAForSendsToInternalWallets: + shouldRequireTOTP2FAForSendsToInternalWallets, + initialShouldRequireTOTP2FAForExchangesToInternalWallets: + shouldRequireTOTP2FAForExchangesToInternalWallets, + initialShouldRequireTOTP2FAForExchangesToExternalWallets: + shouldRequireTOTP2FAForExchangesToExternalWallets, + initialShouldRequireTOTP2FAForAddingContacts: shouldRequireTOTP2FAForAddingContacts, + initialShouldRequireTOTP2FAForCreatingNewWallets: shouldRequireTOTP2FAForCreatingNewWallets, + initialShouldRequireTOTP2FAForAllSecurityAndBackupSettings: + shouldRequireTOTP2FAForAllSecurityAndBackupSettings, + initialEthereumTransactionPriority: ethereumTransactionPriority, + initialPolygonTransactionPriority: polygonTransactionPriority, + backgroundTasks: backgroundTasks, + initialSyncMode: savedSyncMode, + initialSyncAll: savedSyncAll, + shouldShowYatPopup: shouldShowYatPopup, + shouldShowRepWarning: shouldShowRepWarning, + ); } Future reload({required Box nodeSource}) async { @@ -1198,6 +1209,8 @@ abstract class SettingsStoreBase with Store { languageCode = sharedPreferences.getString(PreferencesKey.currentLanguageCode) ?? languageCode; shouldShowYatPopup = sharedPreferences.getBool(PreferencesKey.shouldShowYatPopup) ?? shouldShowYatPopup; + shouldShowRepWarning = + sharedPreferences.getBool(PreferencesKey.shouldShowRepWarning) ?? shouldShowRepWarning; sortBalanceBy = SortBalanceBy .values[sharedPreferences.getInt(PreferencesKey.sortBalanceBy) ?? sortBalanceBy.index]; pinNativeTokenAtTop = sharedPreferences.getBool(PreferencesKey.pinNativeTokenAtTop) ?? true; diff --git a/lib/view_model/dashboard/dashboard_view_model.dart b/lib/view_model/dashboard/dashboard_view_model.dart index 66d179523..ef43ddf40 100644 --- a/lib/view_model/dashboard/dashboard_view_model.dart +++ b/lib/view_model/dashboard/dashboard_view_model.dart @@ -11,6 +11,7 @@ import 'package:cake_wallet/entities/service_status.dart'; import 'package:cake_wallet/exchange/exchange_provider_description.dart'; import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/monero/monero.dart'; +import 'package:cake_wallet/nano/nano.dart'; import 'package:cake_wallet/store/anonpay/anonpay_transactions_store.dart'; import 'package:cake_wallet/store/app_store.dart'; import 'package:cake_wallet/store/dashboard/orders_store.dart'; @@ -370,6 +371,18 @@ abstract class DashboardViewModelBase with Store { @computed bool get hasPowNodes => wallet.type == WalletType.nano || wallet.type == WalletType.banano; + bool get showRepWarning { + if (wallet.type != WalletType.nano) { + return false; + } + + if (!settingsStore.shouldShowRepWarning) { + return false; + } + + return !nano!.isRepOk(wallet); + } + Future reconnect() async { final node = appStore.settingsStore.getCurrentNode(wallet.type); await wallet.connectToNode(node: node); diff --git a/lib/view_model/node_list/node_create_or_edit_view_model.dart b/lib/view_model/node_list/node_create_or_edit_view_model.dart index e323268a0..283a32cbf 100644 --- a/lib/view_model/node_list/node_create_or_edit_view_model.dart +++ b/lib/view_model/node_list/node_create_or_edit_view_model.dart @@ -12,16 +12,15 @@ import 'package:permission_handler/permission_handler.dart'; part 'node_create_or_edit_view_model.g.dart'; -class NodeCreateOrEditViewModel = NodeCreateOrEditViewModelBase - with _$NodeCreateOrEditViewModel; +class NodeCreateOrEditViewModel = NodeCreateOrEditViewModelBase with _$NodeCreateOrEditViewModel; abstract class NodeCreateOrEditViewModelBase with Store { - NodeCreateOrEditViewModelBase( - this._nodeSource, this._walletType, this._settingsStore) + NodeCreateOrEditViewModelBase(this._nodeSource, this._walletType, this._settingsStore) : state = InitialExecutionState(), connectionState = InitialExecutionState(), useSSL = false, address = '', + path = '', port = '', login = '', password = '', @@ -35,6 +34,9 @@ abstract class NodeCreateOrEditViewModelBase with Store { @observable String address; + @observable + String path; + @observable String port; @@ -84,6 +86,7 @@ abstract class NodeCreateOrEditViewModelBase with Store { @action void reset() { address = ''; + path = ''; port = ''; login = ''; password = ''; @@ -99,6 +102,9 @@ abstract class NodeCreateOrEditViewModelBase with Store { @action void setAddress(String val) => address = val; + @action + void setPath(String val) => path = val; + @action void setLogin(String val) => login = val; @@ -121,6 +127,7 @@ abstract class NodeCreateOrEditViewModelBase with Store { Future save({Node? editingNode, bool saveAsCurrent = false}) async { final node = Node( uri: uri, + path: path, type: _walletType, login: login, password: password, @@ -151,6 +158,7 @@ abstract class NodeCreateOrEditViewModelBase with Store { Future connect() async { final node = Node( uri: uri, + path: path, type: _walletType, login: login, password: password, @@ -183,7 +191,7 @@ abstract class NodeCreateOrEditViewModelBase with Store { Future scanQRCodeForNewNode(BuildContext context) async { try { bool isCameraPermissionGranted = - await PermissionHandler.checkPermission(Permission.camera, context); + await PermissionHandler.checkPermission(Permission.camera, context); if (!isCameraPermissionGranted) return; String code = await presentQRScanner(); @@ -198,7 +206,7 @@ abstract class NodeCreateOrEditViewModelBase with Store { } final userInfo = uri.userInfo.split(':'); - + if (userInfo.length < 2) { throw Exception('Unexpected scan QR code value: Value is invalid'); } @@ -207,8 +215,11 @@ abstract class NodeCreateOrEditViewModelBase with Store { final rpcPassword = userInfo[1]; final ipAddress = uri.host; final port = uri.port.toString(); + final path = uri.path; + setAddress(ipAddress); + setPath(path); setPassword(rpcPassword); setLogin(rpcUser); setPort(port); diff --git a/res/values/strings_ar.arb b/res/values/strings_ar.arb index 6b3aae14e..f5b2dd5dd 100644 --- a/res/values/strings_ar.arb +++ b/res/values/strings_ar.arb @@ -357,6 +357,8 @@ "moonpay_alert_text": "يجب أن تكون قيمة المبلغ أكبر من أو تساوي ${minAmount} ${fiatCurrency}", "more_options": "المزيد من الخيارات", "name": "ﻢﺳﺍ", + "nano_current_rep": "الممثل الحالي", + "nano_pick_new_rep": "اختر ممثلًا جديدًا", "narrow": "ضيق", "new_first_wallet_text": "حافظ بسهولة على أمان العملة المشفرة", "new_node_testing": "تجربة العقدة الجديدة", @@ -465,6 +467,8 @@ "remove_node": "إزالة العقدة", "remove_node_message": "هل أنت متأكد أنك تريد إزالة العقدة المحددة؟", "rename": "إعادة تسمية", + "rep_warning": "تحذير تمثيلي", + "rep_warning_sub": "لا يبدو أن ممثلك في وضع جيد. اضغط هنا لاختيار واحدة جديدة", "require_for_adding_contacts": "تتطلب إضافة جهات اتصال", "require_for_all_security_and_backup_settings": "مطلوب لجميع إعدادات الأمان والنسخ الاحتياطي", "require_for_assessing_wallet": "تتطلب الوصول إلى المحفظة", @@ -742,6 +746,7 @@ "unspent_coins_details_title": "تفاصيل العملات الغير المنفقة", "unspent_coins_title": "العملات الغير المنفقة", "unsupported_asset": ".ﻡﻮﻋﺪﻣ ﻞﺻﺃ ﻉﻮﻧ ﻦﻣ ﺔﻈﻔﺤﻣ ﻰﻟﺇ ﻞﻳﺪﺒﺘﻟﺍ ﻭﺃ ءﺎﺸﻧﺇ ﻰﺟﺮﻳ .ﻞﺻﻷﺍ ﺍﺬﻬﻟ ءﺍﺮﺟﻹﺍ ﺍﺬﻫ ﻢﻋﺪﻧ ﻻ ﻦﺤﻧ", + "uptime": "مدة التشغيل", "upto": "حتى ${value}", "use": "التبديل إلى", "use_card_info_three": "استخدم البطاقة الرقمية عبر الإنترنت أو مع طرق الدفع غير التلامسية.", @@ -758,6 +763,7 @@ "view_key_private": "مفتاح العرض (خاص)", "view_key_public": "مفتاح العرض (عام)", "view_transaction_on": "عرض العملية على", + "voting_weight": "وزن التصويت", "waitFewSecondForTxUpdate": "ﺕﻼﻣﺎﻌﻤﻟﺍ ﻞﺠﺳ ﻲﻓ ﺔﻠﻣﺎﻌﻤﻟﺍ ﺲﻜﻌﻨﺗ ﻰﺘﺣ ﻥﺍﻮﺛ ﻊﻀﺒﻟ ﺭﺎﻈﺘﻧﻻﺍ ﻰﺟﺮﻳ", "wallet_keys": "سييد المحفظة / المفاتيح", "wallet_list_create_new_wallet": "إنشاء محفظة جديدة", diff --git a/res/values/strings_bg.arb b/res/values/strings_bg.arb index 30d9945d1..511a04e39 100644 --- a/res/values/strings_bg.arb +++ b/res/values/strings_bg.arb @@ -357,6 +357,8 @@ "moonpay_alert_text": "Сумата трябва да бъде най-малко ${minAmount} ${fiatCurrency}", "more_options": "Още настройки", "name": "Име", + "nano_current_rep": "Настоящ представител", + "nano_pick_new_rep": "Изберете нов представител", "narrow": "Тесен", "new_first_wallet_text": "Лесно пазете криптовалутата си в безопасност", "new_node_testing": "Тестване на нов node", @@ -465,6 +467,8 @@ "remove_node": "Премахни node", "remove_node_message": "Сигурни ли сте, че искате да премахнете избрания node?", "rename": "Промяна на името", + "rep_warning": "Представително предупреждение", + "rep_warning_sub": "Вашият представител изглежда не е в добро състояние. Докоснете тук, за да изберете нов", "require_for_adding_contacts": "Изисква се за добавяне на контакти", "require_for_all_security_and_backup_settings": "Изисква се за всички настройки за сигурност и архивиране", "require_for_assessing_wallet": "Изискване за достъп до портфейла", @@ -742,6 +746,7 @@ "unspent_coins_details_title": "Подробности за неизползваните монети", "unspent_coins_title": "Неизползвани монети", "unsupported_asset": "Не поддържаме това действие за този актив. Моля, създайте или преминете към портфейл от поддържан тип актив.", + "uptime": "Време за работа", "upto": "до ${value}", "use": "Смяна на ", "use_card_info_three": "Използвайте дигиталната карта онлайн или чрез безконтактен метод на плащане.", @@ -758,6 +763,7 @@ "view_key_private": "View key (таен)", "view_key_public": "View key (публичен)", "view_transaction_on": "Вижте транзакция на ", + "voting_weight": "Тегло на гласуване", "waitFewSecondForTxUpdate": "Моля, изчакайте няколко секунди, докато транзакцията се отрази в историята на транзакциите", "wallet_keys": "Seed/keys на портфейла", "wallet_list_create_new_wallet": "Създаване на нов портфейл", diff --git a/res/values/strings_cs.arb b/res/values/strings_cs.arb index 577cd9813..8457de560 100644 --- a/res/values/strings_cs.arb +++ b/res/values/strings_cs.arb @@ -357,6 +357,8 @@ "moonpay_alert_text": "Částka musí být větší nebo rovna ${minAmount} ${fiatCurrency}", "more_options": "Více možností", "name": "název", + "nano_current_rep": "Současný zástupce", + "nano_pick_new_rep": "Vyberte nového zástupce", "narrow": "Úzký", "new_first_wallet_text": "Snadno udržujte svou kryptoměnu v bezpečí", "new_node_testing": "Testování nového uzlu", @@ -465,6 +467,8 @@ "remove_node": "Odstranit uzel", "remove_node_message": "Opravdu chcete odstranit označený uzel?", "rename": "Přejmenovat", + "rep_warning": "Reprezentativní varování", + "rep_warning_sub": "Zdá se, že váš zástupce není v dobrém stavu. Klepnutím zde vyberte nový", "require_for_adding_contacts": "Vyžadovat pro přidání kontaktů", "require_for_all_security_and_backup_settings": "Vyžadovat všechna nastavení zabezpečení a zálohování", "require_for_assessing_wallet": "Vyžadovat pro přístup k peněžence", @@ -742,6 +746,7 @@ "unspent_coins_details_title": "Podrobnosti o neutracených mincích", "unspent_coins_title": "Neutracené mince", "unsupported_asset": "Tuto akci u tohoto díla nepodporujeme. Vytvořte nebo přepněte na peněženku podporovaného typu aktiv.", + "uptime": "Uptime", "upto": "až ${value}", "use": "Přepnout na ", "use_card_info_three": "Použijte tuto digitální kartu online nebo bezkontaktními platebními metodami.", @@ -758,6 +763,7 @@ "view_key_private": "Klíč pro zobrazení (soukromý)", "view_key_public": "Klíč pro zobrazení (veřejný)", "view_transaction_on": "Zobrazit transakci na ", + "voting_weight": "Hlasová váha", "waitFewSecondForTxUpdate": "Počkejte několik sekund, než se transakce projeví v historii transakcí", "wallet_keys": "Seed/klíče peněženky", "wallet_list_create_new_wallet": "Vytvořit novou peněženku", diff --git a/res/values/strings_de.arb b/res/values/strings_de.arb index f0ba70c84..7caf82efa 100644 --- a/res/values/strings_de.arb +++ b/res/values/strings_de.arb @@ -357,6 +357,8 @@ "moonpay_alert_text": "Der Wert des Betrags muss größer oder gleich ${minAmount} ${fiatCurrency} sein", "more_options": "Weitere Optionen", "name": "Name", + "nano_current_rep": "Aktueller Vertreter", + "nano_pick_new_rep": "Wählen Sie einen neuen Vertreter aus", "narrow": "Eng", "new_first_wallet_text": "Bewahren Sie Ihre Kryptowährung einfach sicher auf", "new_node_testing": "Neuen Knoten testen", @@ -466,6 +468,8 @@ "remove_node": "Knoten entfernen", "remove_node_message": "Möchten Sie den ausgewählten Knoten wirklich entfernen?", "rename": "Umbenennen", + "rep_warning": "Repräsentative Warnung", + "rep_warning_sub": "Ihr Vertreter scheint nicht gut zu sein. Tippen Sie hier, um eine neue auszuwählen", "require_for_adding_contacts": "Erforderlich zum Hinzufügen von Kontakten", "require_for_all_security_and_backup_settings": "Für alle Sicherheits- und Sicherungseinstellungen erforderlich", "require_for_assessing_wallet": "Für den Zugriff auf die Wallet erforderlich", @@ -744,6 +748,7 @@ "unspent_coins_details_title": "Details zu nicht ausgegebenen Coins", "unspent_coins_title": "Nicht ausgegebene Coins", "unsupported_asset": "Wir unterstützen diese Aktion für dieses Asset nicht. Bitte erstellen Sie eine Wallet eines unterstützten Asset-Typs oder wechseln Sie zu einer Wallet.", + "uptime": "Betriebszeit", "upto": "bis zu ${value}", "use": "Wechsel zu ", "use_card_info_three": "Verwenden Sie die digitale Karte online oder mit kontaktlosen Zahlungsmethoden.", @@ -760,6 +765,7 @@ "view_key_private": "View Key (geheim)", "view_key_public": "View Key (öffentlich)", "view_transaction_on": "Anzeigen der Transaktion auf ", + "voting_weight": "Stimmgewicht", "waitFewSecondForTxUpdate": "Bitte warten Sie einige Sekunden, bis die Transaktion im Transaktionsverlauf angezeigt wird", "waiting_payment_confirmation": "Warte auf Zahlungsbestätigung", "wallet_keys": "Wallet-Seed/-Schlüssel", diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb index f8bd6b3a2..e75bda358 100644 --- a/res/values/strings_en.arb +++ b/res/values/strings_en.arb @@ -357,6 +357,8 @@ "moonpay_alert_text": "Value of the amount must be more or equal to ${minAmount} ${fiatCurrency}", "more_options": "More Options", "name": "Name", + "nano_current_rep": "Current Representative", + "nano_pick_new_rep": "Pick a new representative", "narrow": "Narrow", "new_first_wallet_text": "Keep your crypto safe, piece of cake", "new_node_testing": "New node testing", @@ -465,6 +467,8 @@ "remove_node": "Remove node", "remove_node_message": "Are you sure that you want to remove selected node?", "rename": "Rename", + "rep_warning": "Representative Warning", + "rep_warning_sub": "Your representative does not appear to be in good standing. Tap here to select a new one", "require_for_adding_contacts": "Require for adding contacts", "require_for_all_security_and_backup_settings": "Require for all security and backup settings", "require_for_assessing_wallet": "Require for accessing wallet", @@ -742,6 +746,7 @@ "unspent_coins_details_title": "Unspent coins details", "unspent_coins_title": "Unspent coins", "unsupported_asset": "We don't support this action for this asset. Please create or switch to a wallet of a supported asset type.", + "uptime": "Uptime", "upto": "up to ${value}", "use": "Switch to ", "use_card_info_three": "Use the digital card online or with contactless payment methods.", @@ -758,6 +763,7 @@ "view_key_private": "View key (private)", "view_key_public": "View key (public)", "view_transaction_on": "View Transaction on ", + "voting_weight": "Voting Weight", "waitFewSecondForTxUpdate": "Kindly wait for a few seconds for transaction to reflect in transactions history", "wallet_keys": "Wallet seed/keys", "wallet_list_create_new_wallet": "Create New Wallet", diff --git a/res/values/strings_es.arb b/res/values/strings_es.arb index cf70a2c2d..c8a56bc66 100644 --- a/res/values/strings_es.arb +++ b/res/values/strings_es.arb @@ -357,6 +357,8 @@ "moonpay_alert_text": "El valor de la cantidad debe ser mayor o igual a ${minAmount} ${fiatCurrency}", "more_options": "Más Opciones", "name": "Nombre", + "nano_current_rep": "Representante actual", + "nano_pick_new_rep": "Elija un nuevo representante", "narrow": "Angosto", "new_first_wallet_text": "Mantenga fácilmente su criptomoneda segura", "new_node_testing": "Prueba de nuevos nodos", @@ -466,6 +468,8 @@ "remove_node": "Eliminar nodo", "remove_node_message": "¿Está seguro de que desea eliminar el nodo seleccionado?", "rename": "Rebautizar", + "rep_warning": "Advertencia representativa", + "rep_warning_sub": "Su representante no parece estar en buena posición. Toque aquí para seleccionar uno nuevo", "require_for_adding_contacts": "Requerido para agregar contactos", "require_for_all_security_and_backup_settings": "Requerido para todas las configuraciones de seguridad y copia de seguridad", "require_for_assessing_wallet": "Requerido para acceder a la billetera", @@ -743,6 +747,7 @@ "unspent_coins_details_title": "Detalles de monedas no gastadas", "unspent_coins_title": "Monedas no gastadas", "unsupported_asset": "No admitimos esta acción para este activo. Cree o cambie a una billetera de un tipo de activo admitido.", + "uptime": "Tiempo de actividad", "upto": "hasta ${value}", "use": "Utilizar a ", "use_card_info_three": "Utilice la tarjeta digital en línea o con métodos de pago sin contacto.", @@ -759,6 +764,7 @@ "view_key_private": "View clave (privado)", "view_key_public": "View clave (público)", "view_transaction_on": "View Transaction on ", + "voting_weight": "Peso de votación", "waitFewSecondForTxUpdate": "Espere unos segundos para que la transacción se refleje en el historial de transacciones.", "wallet_keys": "Billetera semilla/claves", "wallet_list_create_new_wallet": "Crear nueva billetera", diff --git a/res/values/strings_fr.arb b/res/values/strings_fr.arb index d21e21dae..bbd2bde2b 100644 --- a/res/values/strings_fr.arb +++ b/res/values/strings_fr.arb @@ -357,6 +357,8 @@ "moonpay_alert_text": "Le montant doit être au moins égal à ${minAmount} ${fiatCurrency}", "more_options": "Plus d'options", "name": "Nom", + "nano_current_rep": "Représentant actuel", + "nano_pick_new_rep": "Choisissez un nouveau représentant", "narrow": "Étroit", "new_first_wallet_text": "Gardez facilement votre crypto-monnaie en sécurité", "new_node_testing": "Test du nouveau nœud", @@ -465,6 +467,8 @@ "remove_node": "Supprimer le nœud", "remove_node_message": "Êtes vous certain de vouloir supprimer le nœud sélectionné ?", "rename": "Renommer", + "rep_warning": "Avertissement représentatif", + "rep_warning_sub": "Votre représentant ne semble pas être en règle. Appuyez ici pour en sélectionner un nouveau", "require_for_adding_contacts": "Requis pour ajouter des contacts", "require_for_all_security_and_backup_settings": "Exiger pour tous les paramètres de sécurité et de sauvegarde", "require_for_assessing_wallet": "Nécessaire pour accéder au portefeuille", @@ -742,6 +746,7 @@ "unspent_coins_details_title": "Détails des pièces (coins) non dépensées", "unspent_coins_title": "Pièces (coins) non dépensées", "unsupported_asset": "Nous ne prenons pas en charge cette action pour cet élément. Veuillez créer ou passer à un portefeuille d'un type d'actif pris en charge.", + "uptime": "Durée de la baisse", "upto": "jusqu'à ${value}", "use": "Changer vers code PIN à ", "use_card_info_three": "Utilisez la carte numérique en ligne ou avec des méthodes de paiement sans contact.", @@ -758,6 +763,7 @@ "view_key_private": "Clef d'audit (view key) (privée)", "view_key_public": "Clef d'audit (view key) (publique)", "view_transaction_on": "Voir la Transaction sur ", + "voting_weight": "Poids de vote", "waitFewSecondForTxUpdate": "Veuillez attendre quelques secondes pour que la transaction soit reflétée dans l'historique des transactions.", "wallet_keys": "Phrase secrète (seed)/Clefs du portefeuille (wallet)", "wallet_list_create_new_wallet": "Créer un Nouveau Portefeuille (Wallet)", diff --git a/res/values/strings_ha.arb b/res/values/strings_ha.arb index 35a6be1b8..a38f04fa4 100644 --- a/res/values/strings_ha.arb +++ b/res/values/strings_ha.arb @@ -357,6 +357,8 @@ "moonpay_alert_text": "Darajar adadin dole ne ya zama fiye ko daidai da ${minAmount} ${fiatCurrency}", "more_options": "Ƙarin Zaɓuɓɓuka", "name": "Suna", + "nano_current_rep": "Wakilin Yanzu", + "nano_pick_new_rep": "Dauki sabon wakili", "narrow": "kunkuntar", "new_first_wallet_text": "A sauƙaƙe kiyaye kuzarin ku", "new_node_testing": "Sabbin gwajin kumburi", @@ -467,6 +469,8 @@ "remove_node": "Cire node", "remove_node_message": "Kuna tabbatar kuna so ku cire wannan node?", "rename": "Sake suna", + "rep_warning": "Gargadi Wakilin", + "rep_warning_sub": "Wakilinku bai bayyana ya kasance cikin kyakkyawan yanayi ba. Matsa nan don zaɓar sabon", "require_for_adding_contacts": "Bukatar ƙara lambobin sadarwa", "require_for_all_security_and_backup_settings": "Bukatar duk tsaro da saitunan wariyar ajiya", "require_for_assessing_wallet": "Bukatar samun damar walat", @@ -744,6 +748,7 @@ "unspent_coins_details_title": "Bayanan tsabar kudi da ba a kashe ba", "unspent_coins_title": "Tsabar da ba a kashe ba", "unsupported_asset": "Ba mu goyi bayan wannan aikin don wannan kadara. Da fatan za a ƙirƙira ko canza zuwa walat na nau'in kadara mai tallafi.", + "uptime": "Sama", "upto": "har zuwa ${value}", "use": "Canja zuwa", "use_card_info_three": "Yi amfani da katin dijital akan layi ko tare da hanyoyin biyan kuɗi mara lamba.", @@ -760,6 +765,7 @@ "view_key_private": "Duba maɓallin (maɓallin kalmar sirri)", "view_key_public": "Maɓallin Duba (maɓallin jama'a)", "view_transaction_on": "Dubo aikace-aikacen akan", + "voting_weight": "Nauyi mai nauyi", "waitFewSecondForTxUpdate": "Da fatan za a jira ƴan daƙiƙa don ciniki don yin tunani a tarihin ma'amala", "wallet_keys": "Iri/maɓalli na walat", "wallet_list_create_new_wallet": "Ƙirƙiri Sabon Wallet", diff --git a/res/values/strings_hi.arb b/res/values/strings_hi.arb index a6bcab4ab..0131baa8b 100644 --- a/res/values/strings_hi.arb +++ b/res/values/strings_hi.arb @@ -357,6 +357,8 @@ "moonpay_alert_text": "राशि का मूल्य अधिक है या करने के लिए बराबर होना चाहिए ${minAmount} ${fiatCurrency}", "more_options": "और विकल्प", "name": "नाम", + "nano_current_rep": "वर्तमान प्रतिनिधि", + "nano_pick_new_rep": "एक नया प्रतिनिधि चुनें", "narrow": "सँकरा", "new_first_wallet_text": "आसानी से अपनी क्रिप्टोक्यूरेंसी को सुरक्षित रखें", "new_node_testing": "नई नोड परीक्षण", @@ -467,6 +469,8 @@ "remove_node": "नोड निकालें", "remove_node_message": "क्या आप वाकई चयनित नोड को निकालना चाहते हैं?", "rename": "नाम बदलें", + "rep_warning": "प्रतिनिधि चेतावनी", + "rep_warning_sub": "आपका प्रतिनिधि अच्छी स्थिति में नहीं दिखाई देता है। एक नया चयन करने के लिए यहां टैप करें", "require_for_adding_contacts": "संपर्क जोड़ने के लिए आवश्यकता है", "require_for_all_security_and_backup_settings": "सभी सुरक्षा और बैकअप सेटिंग्स की आवश्यकता है", "require_for_assessing_wallet": "वॉलेट तक पहुँचने के लिए आवश्यकता है", @@ -744,6 +748,7 @@ "unspent_coins_details_title": "अव्ययित सिक्कों का विवरण", "unspent_coins_title": "खर्च न किए गए सिक्के", "unsupported_asset": "हम इस संपत्ति के लिए इस कार्रवाई का समर्थन नहीं करते हैं. कृपया समर्थित परिसंपत्ति प्रकार का वॉलेट बनाएं या उस पर स्विच करें।", + "uptime": "अपटाइम", "upto": "${value} तक", "use": "उपयोग ", "use_card_info_three": "डिजिटल कार्ड का ऑनलाइन या संपर्क रहित भुगतान विधियों के साथ उपयोग करें।", @@ -760,6 +765,7 @@ "view_key_private": "कुंजी देखें(निजी)", "view_key_public": "कुंजी देखें (जनता)", "view_transaction_on": "View Transaction on ", + "voting_weight": "वोटिंग वेट", "waitFewSecondForTxUpdate": "लेन-देन इतिहास में लेन-देन प्रतिबिंबित होने के लिए कृपया कुछ सेकंड प्रतीक्षा करें", "wallet_keys": "बटुआ बीज / चाबियाँ", "wallet_list_create_new_wallet": "नया बटुआ बनाएँ", diff --git a/res/values/strings_hr.arb b/res/values/strings_hr.arb index e01857a94..af53376cd 100644 --- a/res/values/strings_hr.arb +++ b/res/values/strings_hr.arb @@ -357,6 +357,8 @@ "moonpay_alert_text": "Vrijednost iznosa mora biti veća ili jednaka ${minAmount} ${fiatCurrency}", "more_options": "Više opcija", "name": "Ime", + "nano_current_rep": "Trenutni predstavnik", + "nano_pick_new_rep": "Odaberite novog predstavnika", "narrow": "Usko", "new_first_wallet_text": "Jednostavno čuvajte svoju kripto valutu", "new_node_testing": "Provjera novog nodea", @@ -465,6 +467,8 @@ "remove_node": "Ukloni node", "remove_node_message": "Jeste li sigurni da želite ukloniti odabrani node?", "rename": "Preimenuj", + "rep_warning": "Reprezentativno upozorenje", + "rep_warning_sub": "Čini se da vaš predstavnik nije u dobrom stanju. Dodirnite ovdje za odabir novog", "require_for_adding_contacts": "Zahtijeva za dodavanje kontakata", "require_for_all_security_and_backup_settings": "Zahtijeva za sve postavke sigurnosti i sigurnosne kopije", "require_for_assessing_wallet": "Potreban za pristup novčaniku", @@ -742,6 +746,7 @@ "unspent_coins_details_title": "Nepotrošeni detalji o novčićima", "unspent_coins_title": "Nepotrošeni novčići", "unsupported_asset": "Ne podržavamo ovu radnju za ovaj materijal. Izradite ili prijeđite na novčanik podržane vrste sredstava.", + "uptime": "Radno vrijeme", "upto": "do ${value}", "use": "Prebaci na", "use_card_info_three": "Koristite digitalnu karticu online ili s beskontaktnim metodama plaćanja.", @@ -758,6 +763,7 @@ "view_key_private": "View key (privatni)", "view_key_public": "View key (javni)", "view_transaction_on": "View Transaction on ", + "voting_weight": "Težina glasanja", "waitFewSecondForTxUpdate": "Pričekajte nekoliko sekundi da se transakcija prikaže u povijesti transakcija", "wallet_keys": "Pristupni izraz/ključ novčanika", "wallet_list_create_new_wallet": "Izradi novi novčanik", diff --git a/res/values/strings_id.arb b/res/values/strings_id.arb index c487a6750..0e0beb57e 100644 --- a/res/values/strings_id.arb +++ b/res/values/strings_id.arb @@ -357,6 +357,8 @@ "moonpay_alert_text": "Nilai jumlah harus lebih atau sama dengan ${minAmount} ${fiatCurrency}", "more_options": "Opsi Lainnya", "name": "Nama", + "nano_current_rep": "Perwakilan saat ini", + "nano_pick_new_rep": "Pilih perwakilan baru", "narrow": "Sempit", "new_first_wallet_text": "Dengan mudah menjaga cryptocurrency Anda aman", "new_node_testing": "Pengujian node baru", @@ -467,6 +469,8 @@ "remove_node": "Hapus node", "remove_node_message": "Apakah Anda yakin ingin menghapus node yang dipilih?", "rename": "Ganti nama", + "rep_warning": "Peringatan Perwakilan", + "rep_warning_sub": "Perwakilan Anda tampaknya tidak bereputasi baik. Ketuk di sini untuk memilih yang baru", "require_for_adding_contacts": "Membutuhkan untuk menambahkan kontak", "require_for_all_security_and_backup_settings": "Memerlukan untuk semua pengaturan keamanan dan pencadangan", "require_for_assessing_wallet": "Diperlukan untuk mengakses dompet", @@ -745,6 +749,7 @@ "unspent_coins_details_title": "Rincian koin yang tidak terpakai", "unspent_coins_title": "Koin yang tidak terpakai", "unsupported_asset": "Kami tidak mendukung tindakan ini untuk aset ini. Harap buat atau alihkan ke dompet dari jenis aset yang didukung.", + "uptime": "Uptime", "upto": "hingga ${value}", "use": "Beralih ke ", "use_card_info_three": "Gunakan kartu digital secara online atau dengan metode pembayaran tanpa kontak.", @@ -761,6 +766,7 @@ "view_key_private": "Kunci tampilan (privat)", "view_key_public": "Kunci tampilan (publik)", "view_transaction_on": "Lihat Transaksi di ", + "voting_weight": "Berat voting", "waitFewSecondForTxUpdate": "Mohon tunggu beberapa detik hingga transaksi terlihat di riwayat transaksi", "wallet_keys": "Seed/kunci dompet", "wallet_list_create_new_wallet": "Buat Dompet Baru", diff --git a/res/values/strings_it.arb b/res/values/strings_it.arb index 0af315426..c73fa7080 100644 --- a/res/values/strings_it.arb +++ b/res/values/strings_it.arb @@ -358,6 +358,8 @@ "moonpay_alert_text": "Il valore dell'importo deve essere maggiore o uguale a ${minAmount} ${fiatCurrency}", "more_options": "Altre opzioni", "name": "Nome", + "nano_current_rep": "Rappresentante attuale", + "nano_pick_new_rep": "Scegli un nuovo rappresentante", "narrow": "Stretto", "new_first_wallet_text": "Mantieni facilmente la tua criptovaluta al sicuro", "new_node_testing": "Test novo nodo", @@ -467,6 +469,8 @@ "remove_node": "Rimuovi nodo", "remove_node_message": "Sei sicuro di voler rimuovere il nodo selezionato?", "rename": "Rinomina", + "rep_warning": "Avvertenza rappresentativa", + "rep_warning_sub": "Il tuo rappresentante non sembra essere in regola. Tocca qui per selezionarne uno nuovo", "require_for_adding_contacts": "Richiesto per l'aggiunta di contatti", "require_for_all_security_and_backup_settings": "Richiedi per tutte le impostazioni di sicurezza e backup", "require_for_assessing_wallet": "Richiesto per l'accesso al portafoglio", @@ -744,6 +748,7 @@ "unspent_coins_details_title": "Dettagli sulle monete non spese", "unspent_coins_title": "Monete non spese", "unsupported_asset": "Non supportiamo questa azione per questa risorsa. Crea o passa a un portafoglio di un tipo di asset supportato.", + "uptime": "Uptime", "upto": "fino a ${value}", "use": "Passa a ", "use_card_info_three": "Utilizza la carta digitale online o con metodi di pagamento contactless.", @@ -760,6 +765,7 @@ "view_key_private": "Chiave di visualizzazione (privata)", "view_key_public": "Chiave di visualizzazione (pubblica)", "view_transaction_on": "View Transaction on ", + "voting_weight": "Peso di voto", "waitFewSecondForTxUpdate": "Attendi qualche secondo affinché la transazione venga riflessa nella cronologia delle transazioni", "waiting_payment_confirmation": "In attesa di conferma del pagamento", "wallet_keys": "Seme Portafoglio /chiavi", diff --git a/res/values/strings_ja.arb b/res/values/strings_ja.arb index a0b3973b2..65f2642d7 100644 --- a/res/values/strings_ja.arb +++ b/res/values/strings_ja.arb @@ -358,6 +358,8 @@ "moonpay_alert_text": "金額の値は以上でなければなりません ${minAmount} ${fiatCurrency}", "more_options": "その他のオプション", "name": "名前", + "nano_current_rep": "現在の代表", + "nano_pick_new_rep": "新しい代表者を選びます", "narrow": "狭い", "new_first_wallet_text": "暗号通貨を簡単に安全に保ちます", "new_node_testing": "新しいノードのテスト", @@ -466,6 +468,8 @@ "remove_node": "ノードを削除", "remove_node_message": "選択したノードを削除してもよろしいですか?", "rename": "リネーム", + "rep_warning": "代表的な警告", + "rep_warning_sub": "あなたの代表者は良好な状態ではないようです。ここをタップして、新しいものを選択します", "require_for_adding_contacts": "連絡先の追加に必要", "require_for_all_security_and_backup_settings": "すべてのセキュリティおよびバックアップ設定に必須", "require_for_assessing_wallet": "ウォレットにアクセスするために必要です", @@ -743,6 +747,7 @@ "unspent_coins_details_title": "未使用のコインの詳細", "unspent_coins_title": "未使用のコイン", "unsupported_asset": "このアセットに対するこのアクションはサポートされていません。サポートされているアセットタイプのウォレットを作成するか、ウォレットに切り替えてください。", + "uptime": "稼働時間", "upto": "up up ${value}", "use": "使用する ", "use_card_info_three": "デジタルカードをオンラインまたは非接触型決済方法で使用してください。", @@ -759,6 +764,7 @@ "view_key_private": "ビューキー (プライベート)", "view_key_public": "ビューキー (パブリック)", "view_transaction_on": "View Transaction on ", + "voting_weight": "投票重み", "waitFewSecondForTxUpdate": "取引履歴に取引が反映されるまで数秒お待ちください。", "wallet_keys": "ウォレットシード/キー", "wallet_list_create_new_wallet": "新しいウォレットを作成", diff --git a/res/values/strings_ko.arb b/res/values/strings_ko.arb index 98bc40e77..e9fab7d6f 100644 --- a/res/values/strings_ko.arb +++ b/res/values/strings_ko.arb @@ -357,6 +357,8 @@ "moonpay_alert_text": "금액은 다음보다 크거나 같아야합니다 ${minAmount} ${fiatCurrency}", "more_options": "추가 옵션", "name": "이름", + "nano_current_rep": "현재 대표", + "nano_pick_new_rep": "새로운 담당자를 선택하십시오", "narrow": "좁은", "new_first_wallet_text": "cryptocurrency를 쉽게 안전하게 유지하십시오", "new_node_testing": "새로운 노드 테스트", @@ -423,8 +425,8 @@ "placeholder_transactions": "거래가 여기에 표시됩니다", "please_fill_totp": "다른 기기에 있는 8자리 코드를 입력하세요.", "please_make_selection": "아래에서 선택하십시오 지갑 만들기 또는 복구.", - "Please_reference_document": "자세한 내용은 아래 문서를 참조하십시오.", "please_reference_document": "자세한 내용은 아래 문서를 참조하십시오.", + "Please_reference_document": "자세한 내용은 아래 문서를 참조하십시오.", "please_select": "선택 해주세요:", "please_select_backup_file": "백업 파일을 선택하고 백업 암호를 입력하십시오.", "please_try_to_connect_to_another_node": "다른 노드에 연결을 시도하십시오", @@ -466,6 +468,8 @@ "remove_node": "노드 제거", "remove_node_message": "선택한 노드를 제거 하시겠습니까?", "rename": "이름 바꾸기", + "rep_warning": "대표 경고", + "rep_warning_sub": "귀하의 대표는 양호한 상태가 아닌 것 같습니다. 새 것을 선택하려면 여기를 탭하십시오", "require_for_adding_contacts": "연락처 추가에 필요", "require_for_all_security_and_backup_settings": "모든 보안 및 백업 설정에 필요", "require_for_assessing_wallet": "지갑 접근을 위해 필요", @@ -743,6 +747,7 @@ "unspent_coins_details_title": "사용하지 않은 동전 세부 정보", "unspent_coins_title": "사용하지 않은 동전", "unsupported_asset": "이 저작물에 대해 이 작업을 지원하지 않습니다. 지원되는 자산 유형의 지갑을 생성하거나 전환하십시오.", + "uptime": "가동 시간", "upto": "최대 ${value}", "use": "사용하다 ", "use_card_info_three": "디지털 카드를 온라인 또는 비접촉식 결제 수단으로 사용하십시오.", @@ -759,6 +764,7 @@ "view_key_private": "키보기(은밀한)", "view_key_public": "키보기 (공공의)", "view_transaction_on": "View Transaction on ", + "voting_weight": "투표 중량", "waitFewSecondForTxUpdate": "거래 내역에 거래가 반영될 때까지 몇 초 정도 기다려 주세요.", "wallet_keys": "지갑 시드 / 키", "wallet_list_create_new_wallet": "새 월렛 만들기", diff --git a/res/values/strings_my.arb b/res/values/strings_my.arb index 8d846f3d6..fb3832f05 100644 --- a/res/values/strings_my.arb +++ b/res/values/strings_my.arb @@ -357,6 +357,8 @@ "moonpay_alert_text": "ပမာဏ၏တန်ဖိုးသည် ${minAmount} ${fiatCurrency} နှင့် ပိုနေရမည်", "more_options": "နောက်ထပ် ရွေးချယ်စရာများ", "name": "နာမည်", + "nano_current_rep": "လက်ရှိကိုယ်စားလှယ်", + "nano_pick_new_rep": "အသစ်တစ်ခုကိုရွေးပါ", "narrow": "ကျဉ်းသော", "new_first_wallet_text": "သင့်ရဲ့ cryptocurrencrencres ကိုအလွယ်တကူလုံခြုံစွာထားရှိပါ", "new_node_testing": "နှာခေါင်း အသစ်စမ်းသပ်ခြင်း။", @@ -465,6 +467,8 @@ "remove_node": "နှာခေါင်း ကို ဖယ်ရှားပါ။", "remove_node_message": "ရွေးချယ်ထားသော ကုဒ်ကို ဖယ်ရှားလိုသည်မှာ သေချာပါသလား။", "rename": "အမည်ပြောင်းပါ။", + "rep_warning": "ကိုယ်စားလှယ်သတိပေးချက်", + "rep_warning_sub": "သင်၏ကိုယ်စားလှယ်သည်ကောင်းမွန်သောရပ်တည်မှုတွင်မဖြစ်သင့်ပါ။ အသစ်တစ်ခုကိုရွေးချယ်ရန်ဤနေရာတွင်အသာပုတ်ပါ", "require_for_adding_contacts": "အဆက်အသွယ်များထည့်ရန် လိုအပ်သည်။", "require_for_all_security_and_backup_settings": "လုံခြုံရေးနှင့် အရန်ဆက်တင်များအားလုံးအတွက် လိုအပ်ပါသည်။", "require_for_assessing_wallet": "ပိုက်ဆံအိတ်ကို ဝင်သုံးရန် လိုအပ်သည်။", @@ -742,6 +746,7 @@ "unspent_coins_details_title": "အသုံးမဝင်သော အကြွေစေ့အသေးစိတ်များ", "unspent_coins_title": "အသုံးမဝင်သော အကြွေစေ့များ", "unsupported_asset": "ဤပိုင်ဆိုင်မှုအတွက် ဤလုပ်ဆောင်ချက်ကို ကျွန်ုပ်တို့ မပံ့ပိုးပါ။ ကျေးဇူးပြု၍ ပံ့ပိုးပေးထားသော ပိုင်ဆိုင်မှုအမျိုးအစား၏ ပိုက်ဆံအိတ်ကို ဖန်တီးပါ သို့မဟုတ် ပြောင်းပါ။", + "uptime": "အထက်က", "upto": "${value} အထိ", "use": "သို့ပြောင်းပါ။", "use_card_info_three": "ဒစ်ဂျစ်တယ်ကတ်ကို အွန်လိုင်း သို့မဟုတ် ထိတွေ့မှုမဲ့ ငွေပေးချေမှုနည်းလမ်းများဖြင့် အသုံးပြုပါ။", @@ -758,6 +763,7 @@ "view_key_private": "သော့ကိုကြည့်ရန် (သီးသန့်)", "view_key_public": "သော့ကိုကြည့်ရန် (အများပြည်သူ)", "view_transaction_on": "ငွေလွှဲခြင်းကို ဖွင့်ကြည့်ပါ။", + "voting_weight": "မဲပေးအလေးချိန်", "waitFewSecondForTxUpdate": "ငွေပေးငွေယူ မှတ်တမ်းတွင် ရောင်ပြန်ဟပ်ရန် စက္ကန့်အနည်းငယ်စောင့်ပါ။", "wallet_keys": "ပိုက်ဆံအိတ် အစေ့/သော့များ", "wallet_list_create_new_wallet": "Wallet အသစ်ဖန်တီးပါ။", diff --git a/res/values/strings_nl.arb b/res/values/strings_nl.arb index 8b3edee4b..0db2f4ebf 100644 --- a/res/values/strings_nl.arb +++ b/res/values/strings_nl.arb @@ -357,6 +357,8 @@ "moonpay_alert_text": "Waarde van het bedrag moet meer of gelijk zijn aan ${minAmount} ${fiatCurrency}", "more_options": "Meer opties", "name": "Naam", + "nano_current_rep": "Huidige vertegenwoordiger", + "nano_pick_new_rep": "Kies een nieuwe vertegenwoordiger", "narrow": "Smal", "new_first_wallet_text": "Houd uw cryptocurrency gemakkelijk veilig", "new_node_testing": "Nieuwe knooppunttest", @@ -465,6 +467,8 @@ "remove_node": "Knoop verwijderen", "remove_node_message": "Weet u zeker dat u het geselecteerde knooppunt wilt verwijderen?", "rename": "Hernoemen", + "rep_warning": "Representatieve waarschuwing", + "rep_warning_sub": "Uw vertegenwoordiger lijkt niet goed te staan. Tik hier om een ​​nieuwe te selecteren", "require_for_adding_contacts": "Vereist voor het toevoegen van contacten", "require_for_all_security_and_backup_settings": "Vereist voor alle beveiligings- en back-upinstellingen", "require_for_assessing_wallet": "Vereist voor toegang tot portemonnee", @@ -742,6 +746,7 @@ "unspent_coins_details_title": "Details van niet-uitgegeven munten", "unspent_coins_title": "Ongebruikte munten", "unsupported_asset": "We ondersteunen deze actie niet voor dit item. Maak of schakel over naar een portemonnee van een ondersteund activatype.", + "uptime": "Uptime", "upto": "tot ${value}", "use": "Gebruik ", "use_card_info_three": "Gebruik de digitale kaart online of met contactloze betaalmethoden.", @@ -758,6 +763,7 @@ "view_key_private": "Bekijk sleutel (privaat)", "view_key_public": "Bekijk sleutel (openbaar)", "view_transaction_on": "View Transaction on ", + "voting_weight": "Stemgewicht", "waitFewSecondForTxUpdate": "Wacht een paar seconden totdat de transactie wordt weergegeven in de transactiegeschiedenis", "waiting_payment_confirmation": "In afwachting van betalingsbevestiging", "wallet_keys": "Portemonnee zaad/sleutels", diff --git a/res/values/strings_pl.arb b/res/values/strings_pl.arb index 93dafa352..3c5e9024e 100644 --- a/res/values/strings_pl.arb +++ b/res/values/strings_pl.arb @@ -357,6 +357,8 @@ "moonpay_alert_text": "Wartość kwoty musi być większa lub równa ${minAmount} ${fiatCurrency}", "more_options": "Więcej opcji", "name": "Nazwa", + "nano_current_rep": "Obecny przedstawiciel", + "nano_pick_new_rep": "Wybierz nowego przedstawiciela", "narrow": "Wąski", "new_first_wallet_text": "Łatwo zapewnić bezpieczeństwo kryptowalut", "new_node_testing": "Testowanie nowych węzłów", @@ -465,6 +467,8 @@ "remove_node": "Usuń węzeł", "remove_node_message": "Czy na pewno chcesz usunąć wybrany węzeł?", "rename": "Zmień nazwę", + "rep_warning": "Przedstawicielskie ostrzeżenie", + "rep_warning_sub": "Twój przedstawiciel nie wydaje się mieć dobrej opinii. Stuknij tutaj, aby wybrać nowy", "require_for_adding_contacts": "Wymagane do dodania kontaktów", "require_for_all_security_and_backup_settings": "Wymagaj dla wszystkich ustawień zabezpieczeń i kopii zapasowych", "require_for_assessing_wallet": "Wymagaj dostępu do portfela", @@ -742,6 +746,7 @@ "unspent_coins_details_title": "Szczegóły niewydanych monet", "unspent_coins_title": "Niewydane monety", "unsupported_asset": "Nie obsługujemy tego działania w przypadku tego zasobu. Utwórz lub przełącz się na portfel obsługiwanego typu aktywów.", + "uptime": "Czas aktu", "upto": "do ${value}", "use": "Użyj ", "use_card_info_three": "Użyj cyfrowej karty online lub za pomocą zbliżeniowych metod płatności.", @@ -758,6 +763,7 @@ "view_key_private": "Prywatny Klucz Wglądu", "view_key_public": "Publiczny Klucz Wglądu", "view_transaction_on": "Zobacz transakcje na ", + "voting_weight": "Waga głosu", "waitFewSecondForTxUpdate": "Poczekaj kilka sekund, aż transakcja zostanie odzwierciedlona w historii transakcji", "wallet_keys": "Klucze portfela", "wallet_list_create_new_wallet": "Utwórz nowy portfel", diff --git a/res/values/strings_pt.arb b/res/values/strings_pt.arb index ae07bb177..e8ac0af2e 100644 --- a/res/values/strings_pt.arb +++ b/res/values/strings_pt.arb @@ -358,6 +358,8 @@ "moonpay_alert_text": "O valor do montante deve ser maior ou igual a ${minAmount} ${fiatCurrency}", "more_options": "Mais opções", "name": "Nome", + "nano_current_rep": "Representante atual", + "nano_pick_new_rep": "Escolha um novo representante", "narrow": "Estreito", "new_first_wallet_text": "Mantenha sua criptomoeda facilmente segura", "new_node_testing": "Teste de novo nó", @@ -467,6 +469,8 @@ "remove_node": "Remover nó", "remove_node_message": "Você realmente deseja remover o nó selecionado?", "rename": "Renomear", + "rep_warning": "Aviso representativo", + "rep_warning_sub": "Seu representante não parece estar em boa posição. Toque aqui para selecionar um novo", "require_for_adding_contacts": "Requer para adicionar contatos", "require_for_all_security_and_backup_settings": "Exigir todas as configurações de segurança e backup", "require_for_assessing_wallet": "Requer para acessar a carteira", @@ -744,6 +748,7 @@ "unspent_coins_details_title": "Detalhes de moedas não gastas", "unspent_coins_title": "Moedas não gastas", "unsupported_asset": "Não oferecemos suporte a esta ação para este recurso. Crie ou mude para uma carteira de um tipo de ativo compatível.", + "uptime": "Tempo de atividade", "upto": "até ${value}", "use": "Use PIN de ", "use_card_info_three": "Use o cartão digital online ou com métodos de pagamento sem contato.", @@ -760,6 +765,7 @@ "view_key_private": "Chave de visualização (privada)", "view_key_public": "Chave de visualização (pública)", "view_transaction_on": "View Transaction on ", + "voting_weight": "Peso de votação", "waitFewSecondForTxUpdate": "Aguarde alguns segundos para que a transação seja refletida no histórico de transações", "waiting_payment_confirmation": "Aguardando confirmação de pagamento", "wallet_keys": "Semente/chaves da carteira", diff --git a/res/values/strings_ru.arb b/res/values/strings_ru.arb index 5e75631c6..b049ab843 100644 --- a/res/values/strings_ru.arb +++ b/res/values/strings_ru.arb @@ -357,6 +357,8 @@ "moonpay_alert_text": "Сумма должна быть больше или равна ${minAmount} ${fiatCurrency}", "more_options": "Дополнительные параметры", "name": "Имя", + "nano_current_rep": "Нынешний представитель", + "nano_pick_new_rep": "Выберите нового представителя", "narrow": "Узкий", "new_first_wallet_text": "Легко сохранить свою криптовалюту в безопасности", "new_node_testing": "Тестирование новой ноды", @@ -466,6 +468,8 @@ "remove_node": "Удалить ноду", "remove_node_message": "Вы уверены, что хотите удалить текущую ноду?", "rename": "Переименовать", + "rep_warning": "Представительное предупреждение", + "rep_warning_sub": "Ваш представитель, похоже, не в хорошей репутации. Нажмите здесь, чтобы выбрать новый", "require_for_adding_contacts": "Требовать добавления контактов", "require_for_all_security_and_backup_settings": "Требовать все настройки безопасности и резервного копирования", "require_for_assessing_wallet": "Требовать для доступа к кошельку", @@ -743,6 +747,7 @@ "unspent_coins_details_title": "Сведения о неизрасходованных монетах", "unspent_coins_title": "Неизрасходованные монеты", "unsupported_asset": "Мы не поддерживаем это действие для этого объекта. Пожалуйста, создайте или переключитесь на кошелек поддерживаемого типа активов.", + "uptime": "Время безотказной работы", "upto": "до ${value}", "use": "Использовать ", "use_card_info_three": "Используйте цифровую карту онлайн или с помощью бесконтактных способов оплаты.", @@ -759,6 +764,7 @@ "view_key_private": "Приватный ключ просмотра", "view_key_public": "Публичный ключ просмотра", "view_transaction_on": "View Transaction on ", + "voting_weight": "Вес голоса", "waitFewSecondForTxUpdate": "Пожалуйста, подождите несколько секунд, чтобы транзакция отразилась в истории транзакций.", "wallet_keys": "Мнемоническая фраза/ключи кошелька", "wallet_list_create_new_wallet": "Создать новый кошелёк", diff --git a/res/values/strings_th.arb b/res/values/strings_th.arb index c8183c031..eebcaf4e5 100644 --- a/res/values/strings_th.arb +++ b/res/values/strings_th.arb @@ -357,6 +357,8 @@ "moonpay_alert_text": "มูลค่าของจำนวนต้องมากกว่าหรือเท่ากับ ${minAmount} ${fiatCurrency}", "more_options": "ตัวเลือกเพิ่มเติม", "name": "ชื่อ", + "nano_current_rep": "ตัวแทนปัจจุบัน", + "nano_pick_new_rep": "เลือกตัวแทนใหม่", "narrow": "แคบ", "new_first_wallet_text": "ทำให้สกุลเงินดิจิตอลของคุณปลอดภัยได้อย่างง่ายดาย", "new_node_testing": "การทดสอบโหนดใหม่", @@ -465,6 +467,8 @@ "remove_node": "ลบโหนด", "remove_node_message": "คุณแน่ใจหรือว่าต้องการลบโหนดที่เลือก?", "rename": "เปลี่ยนชื่อ", + "rep_warning": "คำเตือนตัวแทน", + "rep_warning_sub": "ตัวแทนของคุณดูเหมือนจะไม่อยู่ในสถานะที่ดี แตะที่นี่เพื่อเลือกอันใหม่", "require_for_adding_contacts": "ต้องการสำหรับการเพิ่มผู้ติดต่อ", "require_for_all_security_and_backup_settings": "จำเป็นสำหรับการตั้งค่าความปลอดภัยและการสำรองข้อมูลทั้งหมด", "require_for_assessing_wallet": "จำเป็นสำหรับการเข้าถึงกระเป๋าเงิน", @@ -742,6 +746,7 @@ "unspent_coins_details_title": "รายละเอียดเหรียญที่ไม่ได้ใช้", "unspent_coins_title": "เหรียญที่ไม่ได้ใช้", "unsupported_asset": "เราไม่สนับสนุนการกระทำนี้สำหรับเนื้อหานี้ โปรดสร้างหรือเปลี่ยนเป็นกระเป๋าเงินประเภทสินทรัพย์ที่รองรับ", + "uptime": "เวลาทำงาน", "upto": "สูงสุด ${value}", "use": "สลับไปที่ ", "use_card_info_three": "ใช้บัตรดิจิตอลออนไลน์หรือผ่านวิธีการชำระเงินแบบไม่ต้องใช้บัตรกระดาษ", @@ -758,6 +763,7 @@ "view_key_private": "คีย์มุมมอง (ส่วนตัว)", "view_key_public": "คีย์มุมมอง (สาธารณะ)", "view_transaction_on": "ดูการทำธุรกรรมบน ", + "voting_weight": "น้ำหนักโหวต", "waitFewSecondForTxUpdate": "กรุณารอสักครู่เพื่อให้ธุรกรรมปรากฏในประวัติการทำธุรกรรม", "wallet_keys": "ซีดของกระเป๋า/คีย์", "wallet_list_create_new_wallet": "สร้างกระเป๋าใหม่", diff --git a/res/values/strings_tl.arb b/res/values/strings_tl.arb index def38820c..1e85e5fb9 100644 --- a/res/values/strings_tl.arb +++ b/res/values/strings_tl.arb @@ -357,6 +357,8 @@ "moonpay_alert_text": "Ang halaga ng halaga ay dapat na higit pa o katumbas ng ${minAmount} ${fiatCurrency}", "more_options": "Higit pang mga pagpipilian", "name": "Pangalan", + "nano_current_rep": "Kasalukuyang kinatawan", + "nano_pick_new_rep": "Pumili ng isang bagong kinatawan", "narrow": "Makitid", "new_first_wallet_text": "Panatilihing ligtas ang iyong crypto, piraso ng cake", "new_node_testing": "Bagong pagsubok sa node", @@ -465,6 +467,8 @@ "remove_node": "Alisin ang node", "remove_node_message": "Sigurado ka bang nais mong alisin ang napiling node?", "rename": "Palitan ang pangalan", + "rep_warning": "Babala ng kinatawan", + "rep_warning_sub": "Ang iyong kinatawan ay hindi lilitaw na nasa mabuting kalagayan. Tapikin dito upang pumili ng bago", "require_for_adding_contacts": "Nangangailangan para sa pagdaragdag ng mga contact", "require_for_all_security_and_backup_settings": "Nangangailangan para sa lahat ng mga setting ng seguridad at backup", "require_for_assessing_wallet": "Nangangailangan para sa pag -access ng pitaka", @@ -742,6 +746,7 @@ "unspent_coins_details_title": "Mga Detalye ng Unspent Coins", "unspent_coins_title": "Unspent barya", "unsupported_asset": "Hindi namin sinusuportahan ang pagkilos na ito para sa asset na ito. Mangyaring lumikha o lumipat sa isang pitaka ng isang suportadong uri ng pag -aari.", + "uptime": "Uptime", "upto": "Hanggang sa ${value}", "use": "Lumipat sa", "use_card_info_three": "Gamitin ang digital card online o sa mga pamamaraan ng pagbabayad na walang contact.", @@ -758,6 +763,7 @@ "view_key_private": "Tingnan ang Key (Pribado)", "view_key_public": "Tingnan ang Key (Publiko)", "view_transaction_on": "Tingnan ang transaksyon sa", + "voting_weight": "Bigat ng pagboto", "waitFewSecondForTxUpdate": "Mangyaring maghintay ng ilang segundo para makita ang transaksyon sa history ng mga transaksyon", "wallet_keys": "Mga buto/susi ng pitaka", "wallet_list_create_new_wallet": "Lumikha ng bagong pitaka", diff --git a/res/values/strings_tr.arb b/res/values/strings_tr.arb index 111ff91f4..73a911671 100644 --- a/res/values/strings_tr.arb +++ b/res/values/strings_tr.arb @@ -357,6 +357,8 @@ "moonpay_alert_text": "Tutar ${minAmount} ${fiatCurrency} miktarına eşit veya daha fazla olmalıdır", "more_options": "Daha Fazla Seçenek", "name": "İsim", + "nano_current_rep": "Mevcut temsilci", + "nano_pick_new_rep": "Yeni bir temsilci seçin", "narrow": "Dar", "new_first_wallet_text": "Kripto para biriminizi kolayca güvende tutun", "new_node_testing": "Yeni düğüm test ediliyor", @@ -465,6 +467,8 @@ "remove_node": "Düğümü kaldır", "remove_node_message": "Seçili düğümü kaldırmak istediğinden emin misin?", "rename": "Yeniden adlandır", + "rep_warning": "Temsilci uyarı", + "rep_warning_sub": "Temsilciniz iyi durumda görünmüyor. Yeni bir tane seçmek için buraya dokunun", "require_for_adding_contacts": "Kişi eklemek için gerekli", "require_for_all_security_and_backup_settings": "Tüm güvenlik ve yedekleme ayarları için iste", "require_for_assessing_wallet": "Cüzdana erişmek için gerekli", @@ -742,6 +746,7 @@ "unspent_coins_details_title": "Harcanmamış koin detayları", "unspent_coins_title": "Harcanmamış koinler", "unsupported_asset": "Bu öğe için bu eylemi desteklemiyoruz. Lütfen desteklenen bir varlık türünde bir cüzdan oluşturun veya cüzdana geçiş yapın.", + "uptime": "Çalışma süresi", "upto": "Şu miktara kadar: ${value}", "use": "Şuna geç: ", "use_card_info_three": "Dijital kartı çevrimiçi olarak veya temassız ödeme yöntemleriyle kullanın.", @@ -758,6 +763,7 @@ "view_key_private": "İzleme anahtarı (özel)", "view_key_public": "İzleme anahtarı (genel)", "view_transaction_on": "İşlemi şurada görüntüle ", + "voting_weight": "Oy kullanma", "waitFewSecondForTxUpdate": "İşlemin işlem geçmişine yansıması için lütfen birkaç saniye bekleyin", "wallet_keys": "Cüzdan tohumu/anahtarları", "wallet_list_create_new_wallet": "Yeni Cüzdan Oluştur", diff --git a/res/values/strings_uk.arb b/res/values/strings_uk.arb index a0000418d..c38d2918a 100644 --- a/res/values/strings_uk.arb +++ b/res/values/strings_uk.arb @@ -357,6 +357,8 @@ "moonpay_alert_text": "Значення суми має бути більшим або дорівнювати ${minAmount} ${fiatCurrency}", "more_options": "Більше параметрів", "name": "Ім'я", + "nano_current_rep": "Поточний представник", + "nano_pick_new_rep": "Виберіть нового представника", "narrow": "вузькі", "new_first_wallet_text": "Легко зберігайте свою криптовалюту в безпеці", "new_node_testing": "Тестування нового вузла", @@ -466,6 +468,8 @@ "remove_node": "Видалити вузол", "remove_node_message": "Ви впевнені, що хочете видалити поточний вузол?", "rename": "Перейменувати", + "rep_warning": "Представницьке попередження", + "rep_warning_sub": "Ваш представник, схоже, не має доброго становища. Торкніться тут, щоб вибрати новий", "require_for_adding_contacts": "Потрібен для додавання контактів", "require_for_all_security_and_backup_settings": "Вимагати всіх налаштувань безпеки та резервного копіювання", "require_for_assessing_wallet": "Потрібен доступ до гаманця", @@ -743,6 +747,7 @@ "unspent_coins_details_title": "Відомості про невитрачені монети", "unspent_coins_title": "Невитрачені монети", "unsupported_asset": "Ми не підтримуємо цю дію для цього ресурсу. Створіть або перейдіть на гаманець підтримуваного типу активів.", + "uptime": "Час роботи", "upto": "до ${value}", "use": "Використати ", "use_card_info_three": "Використовуйте цифрову картку онлайн або за допомогою безконтактних методів оплати.", @@ -759,6 +764,7 @@ "view_key_private": "Приватний ключ перегляду", "view_key_public": "Публічний ключ перегляду", "view_transaction_on": "View Transaction on ", + "voting_weight": "Вага голосування", "waitFewSecondForTxUpdate": "Будь ласка, зачекайте кілька секунд, поки транзакція відобразиться в історії транзакцій", "wallet_keys": "Мнемонічна фраза/ключі гаманця", "wallet_list_create_new_wallet": "Створити новий гаманець", diff --git a/res/values/strings_ur.arb b/res/values/strings_ur.arb index a7d4b896d..de9a4eb4c 100644 --- a/res/values/strings_ur.arb +++ b/res/values/strings_ur.arb @@ -357,6 +357,8 @@ "moonpay_alert_text": "رقم کی قدر ${minAmount} ${fiatCurrency} کے برابر یا زیادہ ہونی چاہیے۔", "more_options": "مزید زرائے", "name": "ﻡﺎﻧ", + "nano_current_rep": "موجودہ نمائندہ", + "nano_pick_new_rep": "ایک نیا نمائندہ منتخب کریں", "narrow": "تنگ", "new_first_wallet_text": "آسانی سے اپنے cryptocurrency محفوظ رکھیں", "new_node_testing": "نیا نوڈ ٹیسٹنگ", @@ -467,6 +469,8 @@ "remove_node": "نوڈ کو ہٹا دیں۔", "remove_node_message": "کیا آپ واقعی منتخب نوڈ کو ہٹانا چاہتے ہیں؟", "rename": "نام تبدیل کریں۔", + "rep_warning": "نمائندہ انتباہ", + "rep_warning_sub": "آپ کا نمائندہ اچھ standing ے مقام پر نہیں دکھائی دیتا ہے۔ نیا منتخب کرنے کے لئے یہاں ٹیپ کریں", "require_for_adding_contacts": "رابطوں کو شامل کرنے کی ضرورت ہے۔", "require_for_all_security_and_backup_settings": "تمام سیکورٹی اور بیک اپ کی ترتیبات کے لیے درکار ہے۔", "require_for_assessing_wallet": "بٹوے تک رسائی کے لیے درکار ہے۔", @@ -744,6 +748,7 @@ "unspent_coins_details_title": "غیر خرچ شدہ سککوں کی تفصیلات", "unspent_coins_title": "غیر خرچ شدہ سکے ۔", "unsupported_asset": "۔ﮟﯾﺮﮐ ﭻﺋﻮﺳ ﺮﭘ ﺱﺍ ﺎﯾ ﮟﯿﺋﺎﻨﺑ ﺱﺮﭘ ﺎﮐ ﻢﺴﻗ ﯽﮐ ﮧﺛﺎﺛﺍ ﮧﺘﻓﺎﯾ ﻥﻭﺎﻌﺗ ﻡﺮﮐ ﮦﺍﺮﺑ ۔ﮟﯿﮨ ﮯﺗﺮﮐ ﮟﯿﮩﻧ ﺖﯾﺎﻤﺣ ﯽﮐ ﯽﺋﺍﻭﺭﺭﺎﮐ ﺱﺍ ﮯﯿﻟ ﮯﮐ ﮧﺛﺎﺛﺍ ﺱﺍ ﻢﮨ", + "uptime": "اپ ٹائم", "upto": "${value} تک", "use": "تبدیل کرنا", "use_card_info_three": "ڈیجیٹل کارڈ آن لائن یا کنٹیکٹ لیس ادائیگی کے طریقوں کے ساتھ استعمال کریں۔", @@ -760,6 +765,7 @@ "view_key_private": "کلید دیکھیں (نجی)", "view_key_public": "کلید دیکھیں (عوامی)", "view_transaction_on": "لین دین دیکھیں آن", + "voting_weight": "ووٹ کا وزن", "waitFewSecondForTxUpdate": "۔ﮟﯾﺮﮐ ﺭﺎﻈﺘﻧﺍ ﺎﮐ ﮉﻨﮑﯿﺳ ﺪﻨﭼ ﻡﺮﮐ ﮦﺍﺮﺑ ﮯﯿﻟ ﮯﮐ ﮯﻧﺮﮐ ﯽﺳﺎﮑﻋ ﯽﮐ ﻦﯾﺩ ﻦﯿﻟ ﮟﯿﻣ ﺦﯾﺭﺎﺗ ﯽﮐ ﻦ", "wallet_keys": "بٹوے کے بیج / چابیاں", "wallet_list_create_new_wallet": "نیا والیٹ بنائیں", diff --git a/res/values/strings_yo.arb b/res/values/strings_yo.arb index 9ac033917..9a84c86c4 100644 --- a/res/values/strings_yo.arb +++ b/res/values/strings_yo.arb @@ -358,6 +358,8 @@ "moonpay_alert_text": "Iye owó kò gbọ́dọ̀ kéré ju ${minAmount} ${fiatCurrency}", "more_options": "Ìyàn àfikún", "name": "Oruko", + "nano_current_rep": "Aṣoju lọwọlọwọ", + "nano_pick_new_rep": "Mu aṣoju tuntun kan", "narrow": "Taara", "new_first_wallet_text": "Ni rọọrun jẹ ki o jẹ ki o jẹ ki o jẹ ki a mu", "new_node_testing": "A ń dán apẹka títun wò", @@ -466,6 +468,8 @@ "remove_node": "Yọ apẹka kúrò", "remove_node_message": "Ṣé ó da yín lójú pé ẹ fẹ́ yọ apẹka lọwọ́ kúrò?", "rename": "Pààrọ̀ orúkọ", + "rep_warning": "Ikilọ aṣoju", + "rep_warning_sub": "Aṣoju rẹ ko han lati wa ni iduro to dara. Fọwọ ba ibi lati yan ọkan titun kan", "require_for_adding_contacts": "Beere fun fifi awọn olubasọrọ kun", "require_for_all_security_and_backup_settings": "Beere fun gbogbo aabo ati awọn eto afẹyinti", "require_for_assessing_wallet": "Beere fun wiwọle si apamọwọ", @@ -743,6 +747,7 @@ "unspent_coins_details_title": "Àwọn owó ẹyọ t'á kò tí ì san", "unspent_coins_title": "Àwọn owó ẹyọ t'á kò tí ì san", "unsupported_asset": "A ko ṣe atilẹyin iṣẹ yii fun dukia yii. Jọwọ ṣẹda tabi yipada si apamọwọ iru dukia atilẹyin.", + "uptime": "Iduro", "upto": "kò tóbi ju ${value}", "use": "Lo", "use_card_info_three": "Ẹ lo káàdí ayélujára lórí wẹ́ẹ̀bù tàbí ẹ lò ó lórí àwọn ẹ̀rọ̀ ìrajà tíwọn kò kò.", @@ -759,6 +764,7 @@ "view_key_private": "Kọ́kọ́rọ́ ìwò (àdáni)", "view_key_public": "Kọ́kọ́rọ́ ìwò (kò àdáni)", "view_transaction_on": "Wo pàṣípààrọ̀ lórí ", + "voting_weight": "Idibo iwuwo", "waitFewSecondForTxUpdate": "Fi inurere duro fun awọn iṣeju diẹ fun idunadura lati ṣe afihan ninu itan-akọọlẹ iṣowo", "wallet_keys": "Hóró/kọ́kọ́rọ́ àpamọ́wọ́", "wallet_list_create_new_wallet": "Ṣe àpamọ́wọ́ títun", diff --git a/res/values/strings_zh.arb b/res/values/strings_zh.arb index 26bb1b286..1c568174d 100644 --- a/res/values/strings_zh.arb +++ b/res/values/strings_zh.arb @@ -357,6 +357,8 @@ "moonpay_alert_text": "金额的价值必须大于或等于 ${minAmount} ${fiatCurrency}", "more_options": "更多选项", "name": "姓名", + "nano_current_rep": "当前代表", + "nano_pick_new_rep": "选择新代表", "narrow": "狭窄的", "new_first_wallet_text": "轻松确保您的加密货币安全", "new_node_testing": "新节点测试", @@ -465,6 +467,8 @@ "remove_node": "删除节点", "remove_node_message": "您确定要删除所选节点吗?", "rename": "重命名", + "rep_warning": "代表性警告", + "rep_warning_sub": "您的代表似乎并不信誉良好。点击这里选择一个新的", "require_for_adding_contacts": "需要添加联系人", "require_for_all_security_and_backup_settings": "需要所有安全和备份设置", "require_for_assessing_wallet": "需要访问钱包", @@ -742,6 +746,7 @@ "unspent_coins_details_title": "未使用代幣詳情", "unspent_coins_title": "未使用的硬幣", "unsupported_asset": "我们不支持针对该资产采取此操作。请创建或切换到支持的资产类型的钱包。", + "uptime": "正常运行时间", "upto": "最高 ${value}", "use": "切换使用", "use_card_info_three": "在线使用电子卡或使用非接触式支付方式。", @@ -758,6 +763,7 @@ "view_key_private": "View 密钥(私钥)", "view_key_public": "View 密钥(公钥)", "view_transaction_on": "View Transaction on ", + "voting_weight": "投票权重", "waitFewSecondForTxUpdate": "请等待几秒钟,交易才会反映在交易历史记录中", "wallet_keys": "钱包种子/密钥", "wallet_list_create_new_wallet": "创建新钱包", diff --git a/tool/configure.dart b/tool/configure.dart index 06243e8ab..6ee84d63a 100644 --- a/tool/configure.dart +++ b/tool/configure.dart @@ -795,6 +795,7 @@ import 'package:cw_core/transaction_history.dart'; import 'package:cw_core/wallet_service.dart'; import 'package:cw_core/output_info.dart'; import 'package:cw_core/nano_account_info_response.dart'; +import 'package:cw_core/n2_node.dart'; import 'package:mobx/mobx.dart'; import 'package:hive/hive.dart'; import 'package:cake_wallet/view_model/send/output.dart'; @@ -853,6 +854,8 @@ abstract class Nano { Future updateTransactions(Object wallet); BigInt getTransactionAmountRaw(TransactionInfo transactionInfo); String getRepresentative(Object wallet); + Future> getN2Reps(Object wallet); + bool isRepOk(Object wallet); } abstract class NanoAccountList {