Cw 602 nano bad rep (#1356)

* add support for paths in node settings * update translations and fixes * fix node path * add rep warning flag * update translations * code cleanup [skip ci] * add additional node options * add migration * update transaction history rpc to be under the limit * review fixes [skip ci] * [skip ci] updates * move n2_node.dart * minor code improvements * more minor code cleanup

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