Nano rep fixes (#1145)

* add preference keys for default nano/banano rep * updates to change rep page, add success message * forgot to save this file * nano_client cleanup * first pass * refactor to use sharedprefs in nano_client * review fixes

Matthew Fosse committed Nov 17, 2023 at 13:35 UTC f4e71c72ef9c509dffa95bb46cb3ba3d5f0aa52e
37 files changed +314 -142
cw_nano/lib/nano_client.dart
+98 -92
@@ -8,18 +8,28 @@ import 'package:cw_nano/nano_util.dart';
8 import 'package:http/http.dart' as http;
9 import 'package:nanodart/nanodart.dart';
10 import 'package:cw_core/node.dart';
11 +import 'package:shared_preferences/shared_preferences.dart';
12
13 class NanoClient {
13 - static const String DEFAULT_REPRESENTATIVE =
14 - "nano_38713x95zyjsqzx6nm1dsom1jmm668owkeb9913ax6nfgj15az3nu8xkx579";
15 -
14 static const Map<String, String> CAKE_HEADERS = {
15 "Content-Type": "application/json",
16 "nano-app": "cake-wallet"
17 };
18
19 + NanoClient() {
20 + SharedPreferences.getInstance().then((value) => prefs = value);
21 + }
22 +
23 + late SharedPreferences prefs;
24 Node? _node;
25 Node? _powNode;
26 + static const String _defaultDefaultRepresentative =
27 + "nano_38713x95zyjsqzx6nm1dsom1jmm668owkeb9913ax6nfgj15az3nu8xkx579";
28 +
29 + String getRepFromPrefs() {
30 + // from preferences_key.dart "defaultNanoRep" key:
31 + return prefs.getString("default_nano_representative") ?? _defaultDefaultRepresentative;
32 + }
33
34 bool connect(Node node) {
35 try {
@@ -84,44 +94,45 @@ class NanoClient {
94 required String repAddress,
95 required String ourAddress,
96 }) async {
87 - try {
88 - AccountInfoResponse? accountInfo = await getAccountInfo(ourAddress);
97 + AccountInfoResponse? accountInfo = await getAccountInfo(ourAddress);
98
90 - if (accountInfo == null) {
91 - throw Exception("error while getting account info");
92 - }
99 + if (accountInfo == null) {
100 + throw Exception(
101 + "error while getting account info, you can't change the rep of an unopened account");
102 + }
103
94 - // construct the change block:
95 - Map<String, String> changeBlock = {
96 - "type": "state",
97 - "account": ourAddress,
98 - "previous": accountInfo.frontier,
99 - "representative": repAddress,
100 - "balance": accountInfo.balance,
101 - "link": "0000000000000000000000000000000000000000000000000000000000000000",
102 - "link_as_account": "nano_1111111111111111111111111111111111111111111111111111hifc8npp",
103 - };
104 -
105 - // sign the change block:
106 - final String hash = NanoBlocks.computeStateHash(
107 - NanoAccountType.NANO,
108 - changeBlock["account"]!,
109 - changeBlock["previous"]!,
110 - changeBlock["representative"]!,
111 - BigInt.parse(changeBlock["balance"]!),
112 - changeBlock["link"]!,
113 - );
114 - final String signature = NanoSignatures.signBlock(hash, privateKey);
104 + // construct the change block:
105 + Map<String, String> changeBlock = {
106 + "type": "state",
107 + "account": ourAddress,
108 + "previous": accountInfo.frontier,
109 + "representative": repAddress,
110 + "balance": accountInfo.balance,
111 + "link": "0000000000000000000000000000000000000000000000000000000000000000",
112 + "link_as_account": "nano_1111111111111111111111111111111111111111111111111111hifc8npp",
113 + };
114
116 - // get PoW for the send block:
117 - final String work = await requestWork(accountInfo.frontier);
115 + // sign the change block:
116 + final String hash = NanoBlocks.computeStateHash(
117 + NanoAccountType.NANO,
118 + changeBlock["account"]!,
119 + changeBlock["previous"]!,
120 + changeBlock["representative"]!,
121 + BigInt.parse(changeBlock["balance"]!),
122 + changeBlock["link"]!,
123 + );
124 + final String signature = NanoSignatures.signBlock(hash, privateKey);
125
119 - changeBlock["signature"] = signature;
120 - changeBlock["work"] = work;
126 + // get PoW for the send block:
127 + final String work = await requestWork(accountInfo.frontier);
128
129 + changeBlock["signature"] = signature;
130 + changeBlock["work"] = work;
131 +
132 + try {
133 return await processBlock(changeBlock, "change");
134 } catch (e) {
124 - throw Exception("error while changing representative");
135 + throw Exception("error while changing representative: $e");
136 }
137 }
138
@@ -191,68 +202,63 @@ class NanoClient {
202 BigInt? balanceAfterTx,
203 String? previousHash,
204 }) async {
194 - try {
195 - // our address:
196 - final String publicAddress = NanoUtil.privateKeyToAddress(privateKey);
197 -
198 - // first get the current account balance:
199 - if (balanceAfterTx == null) {
200 - final BigInt currentBalance = (await getBalance(publicAddress)).currentBalance;
201 - final BigInt txAmount = BigInt.parse(amountRaw);
202 - balanceAfterTx = currentBalance - txAmount;
203 - }
205 + // our address:
206 + final String publicAddress = NanoUtil.privateKeyToAddress(privateKey);
207 +
208 + // first get the current account balance:
209 + if (balanceAfterTx == null) {
210 + final BigInt currentBalance = (await getBalance(publicAddress)).currentBalance;
211 + final BigInt txAmount = BigInt.parse(amountRaw);
212 + balanceAfterTx = currentBalance - txAmount;
213 + }
214
205 - // get the account info (we need the frontier and representative):
206 - AccountInfoResponse? infoResponse = await getAccountInfo(publicAddress);
207 - if (infoResponse == null) {
208 - throw Exception(
209 - "error while getting account info! (we probably don't have an open account yet)");
210 - }
215 + // get the account info (we need the frontier and representative):
216 + AccountInfoResponse? infoResponse = await getAccountInfo(publicAddress);
217 + if (infoResponse == null) {
218 + throw Exception(
219 + "error while getting account info! (we probably don't have an open account yet)");
220 + }
221
212 - String frontier = infoResponse.frontier;
213 - // override if provided:
214 - if (previousHash != null) {
215 - frontier = previousHash;
216 - }
217 - final String representative = infoResponse.representative;
218 - // link = destination address:
219 - final String link = NanoAccounts.extractPublicKey(destinationAddress);
220 - final String linkAsAccount = destinationAddress;
221 -
222 - // construct the send block:
223 - Map<String, String> sendBlock = {
224 - "type": "state",
225 - "account": publicAddress,
226 - "previous": frontier,
227 - "representative": representative,
228 - "balance": balanceAfterTx.toString(),
229 - "link": link,
230 - };
231 -
232 - // sign the send block:
233 - final String hash = NanoBlocks.computeStateHash(
234 - NanoAccountType.NANO,
235 - sendBlock["account"]!,
236 - sendBlock["previous"]!,
237 - sendBlock["representative"]!,
238 - BigInt.parse(sendBlock["balance"]!),
239 - sendBlock["link"]!,
240 - );
241 - final String signature = NanoSignatures.signBlock(hash, privateKey);
222 + String frontier = infoResponse.frontier;
223 + // override if provided:
224 + if (previousHash != null) {
225 + frontier = previousHash;
226 + }
227 + final String representative = infoResponse.representative;
228 + // link = destination address:
229 + final String link = NanoAccounts.extractPublicKey(destinationAddress);
230 + final String linkAsAccount = destinationAddress;
231
243 - // get PoW for the send block:
244 - final String work = await requestWork(frontier);
232 + // construct the send block:
233 + Map<String, String> sendBlock = {
234 + "type": "state",
235 + "account": publicAddress,
236 + "previous": frontier,
237 + "representative": representative,
238 + "balance": balanceAfterTx.toString(),
239 + "link": link,
240 + };
241 +
242 + // sign the send block:
243 + final String hash = NanoBlocks.computeStateHash(
244 + NanoAccountType.NANO,
245 + sendBlock["account"]!,
246 + sendBlock["previous"]!,
247 + sendBlock["representative"]!,
248 + BigInt.parse(sendBlock["balance"]!),
249 + sendBlock["link"]!,
250 + );
251 + final String signature = NanoSignatures.signBlock(hash, privateKey);
252
246 - sendBlock["link_as_account"] = linkAsAccount;
247 - sendBlock["signature"] = signature;
248 - sendBlock["work"] = work;
253 + // get PoW for the send block:
254 + final String work = await requestWork(frontier);
255
250 - // ready to post send block:
251 - return sendBlock;
252 - } catch (e) {
253 - print(e);
254 - rethrow;
255 - }
256 + sendBlock["link_as_account"] = linkAsAccount;
257 + sendBlock["signature"] = signature;
258 + sendBlock["work"] = work;
259 +
260 + // ready to post send block:
261 + return sendBlock;
262 }
263
264 Future<void> receiveBlock({
@@ -274,7 +280,7 @@ class NanoClient {
280 // account is not open yet, we need to create an open block:
281 openBlock = true;
282 // we don't have a representative set yet:
277 - representative = DEFAULT_REPRESENTATIVE;
283 + representative = await getRepFromPrefs();
284 // we don't have a frontier yet:
285 frontier = "0000000000000000000000000000000000000000000000000000000000000000";
286 } else {
cw_nano/lib/nano_wallet.dart
+1 -1
@@ -382,7 +382,7 @@ abstract class NanoWalletBase
382 _representativeAddress = accountInfo.representative;
383 } catch (e) {
384 // account not found:
385 - _representativeAddress = NanoClient.DEFAULT_REPRESENTATIVE;
385 + _representativeAddress = await _client.getRepFromPrefs();
386 throw Exception("Failed to get representative address $e");
387 }
388 }
cw_nano/pubspec.lock
+62 -1
@@ -290,6 +290,11 @@ packages:
290 description: flutter
291 source: sdk
292 version: "0.0.0"
293 + flutter_web_plugins:
294 + dependency: transitive
295 + description: flutter
296 + source: sdk
297 + version: "0.0.0"
298 frontend_server_client:
299 dependency: transitive
300 description:
@@ -594,6 +599,62 @@ packages:
599 url: "https://pub.dev"
600 source: hosted
601 version: "2.2.2"
602 + shared_preferences:
603 + dependency: "direct main"
604 + description:
605 + name: shared_preferences
606 + sha256: "81429e4481e1ccfb51ede496e916348668fd0921627779233bd24cc3ff6abd02"
607 + url: "https://pub.dev"
608 + source: hosted
609 + version: "2.2.2"
610 + shared_preferences_android:
611 + dependency: transitive
612 + description:
613 + name: shared_preferences_android
614 + sha256: "8568a389334b6e83415b6aae55378e158fbc2314e074983362d20c562780fb06"
615 + url: "https://pub.dev"
616 + source: hosted
617 + version: "2.2.1"
618 + shared_preferences_foundation:
619 + dependency: transitive
620 + description:
621 + name: shared_preferences_foundation
622 + sha256: "7bf53a9f2d007329ee6f3df7268fd498f8373602f943c975598bbb34649b62a7"
623 + url: "https://pub.dev"
624 + source: hosted
625 + version: "2.3.4"
626 + shared_preferences_linux:
627 + dependency: transitive
628 + description:
629 + name: shared_preferences_linux
630 + sha256: "9f2cbcf46d4270ea8be39fa156d86379077c8a5228d9dfdb1164ae0bb93f1faa"
631 + url: "https://pub.dev"
632 + source: hosted
633 + version: "2.3.2"
634 + shared_preferences_platform_interface:
635 + dependency: transitive
636 + description:
637 + name: shared_preferences_platform_interface
638 + sha256: d4ec5fc9ebb2f2e056c617112aa75dcf92fc2e4faaf2ae999caa297473f75d8a
639 + url: "https://pub.dev"
640 + source: hosted
641 + version: "2.3.1"
642 + shared_preferences_web:
643 + dependency: transitive
644 + description:
645 + name: shared_preferences_web
646 + sha256: d762709c2bbe80626ecc819143013cc820fa49ca5e363620ee20a8b15a3e3daf
647 + url: "https://pub.dev"
648 + source: hosted
649 + version: "2.2.1"
650 + shared_preferences_windows:
651 + dependency: transitive
652 + description:
653 + name: shared_preferences_windows
654 + sha256: "841ad54f3c8381c480d0c9b508b89a34036f512482c407e6df7a9c4aa2ef8f59"
655 + url: "https://pub.dev"
656 + source: hosted
657 + version: "2.3.2"
658 shelf:
659 dependency: transitive
660 description:
@@ -753,4 +814,4 @@ packages:
814 version: "3.1.2"
815 sdks:
816 dart: ">=3.0.0 <4.0.0"
756 - flutter: ">=3.3.0"
817 + flutter: ">=3.7.0"
cw_nano/pubspec.yaml
+1
@@ -21,6 +21,7 @@ dependencies:
21 ed25519_hd_key: ^2.2.0
22 hex: ^0.2.0
23 http: ^1.1.0
24 + shared_preferences: ^2.0.15
25 cw_core:
26 path: ../cw_core
27
lib/core/backup_service.dart
+13 -2
@@ -247,6 +247,8 @@ class BackupService {
247 final sortBalanceTokensBy = data[PreferencesKey.sortBalanceBy] as int?;
248 final pinNativeTokenAtTop = data[PreferencesKey.pinNativeTokenAtTop] as bool?;
249 final useEtherscan = data[PreferencesKey.useEtherscan] as bool?;
250 + final defaultNanoRep = data[PreferencesKey.defaultNanoRep] as String?;
251 + final defaultBananoRep = data[PreferencesKey.defaultBananoRep] as String?;
252 final lookupsTwitter = data[PreferencesKey.lookupsTwitter] as bool?;
253 final lookupsMastodon = data[PreferencesKey.lookupsMastodon] as bool?;
254 final lookupsYatService = data[PreferencesKey.lookupsYatService] as bool?;
@@ -322,11 +324,10 @@ class BackupService {
324
325 if (currentTheme != null && DeviceInfo.instance.isMobile) {
326 await _sharedPreferences.setInt(PreferencesKey.currentTheme, currentTheme);
325 - // enforce dark theme on desktop platforms until the design is ready:
327 + // enforce dark theme on desktop platforms until the design is ready:
328 } else if (DeviceInfo.instance.isDesktop) {
329 await _sharedPreferences.setInt(PreferencesKey.currentTheme, ThemeList.darkTheme.raw);
330 }
329 -
331
332 if (exchangeStatus != null)
333 await _sharedPreferences.setInt(PreferencesKey.exchangeStatusKey, exchangeStatus);
@@ -389,6 +390,13 @@ class BackupService {
390 if (useEtherscan != null)
391 await _sharedPreferences.setBool(PreferencesKey.useEtherscan, useEtherscan);
392
393 + if (defaultNanoRep != null)
394 + await _sharedPreferences.setString(PreferencesKey.defaultNanoRep, defaultNanoRep);
395 +
396 + if (defaultBananoRep != null)
397 + await _sharedPreferences.setString(PreferencesKey.defaultBananoRep, defaultBananoRep);
398 +
399 + if (syncAll != null) await _sharedPreferences.setBool(PreferencesKey.syncAllKey, syncAll);
400 if (lookupsTwitter != null)
401 await _sharedPreferences.setBool(PreferencesKey.lookupsTwitter, lookupsTwitter);
402
@@ -560,6 +568,9 @@ class BackupService {
568 PreferencesKey.pinNativeTokenAtTop:
569 _sharedPreferences.getBool(PreferencesKey.pinNativeTokenAtTop),
570 PreferencesKey.useEtherscan: _sharedPreferences.getBool(PreferencesKey.useEtherscan),
571 + PreferencesKey.defaultNanoRep: _sharedPreferences.getString(PreferencesKey.defaultNanoRep),
572 + PreferencesKey.defaultBananoRep:
573 + _sharedPreferences.getString(PreferencesKey.defaultBananoRep),
574 PreferencesKey.lookupsTwitter: _sharedPreferences.getBool(PreferencesKey.lookupsTwitter),
575 PreferencesKey.lookupsMastodon: _sharedPreferences.getBool(PreferencesKey.lookupsMastodon),
576 PreferencesKey.lookupsYatService:
lib/di.dart
+7 -4
@@ -522,8 +522,7 @@ Future<void> setup({
522 getIt.registerFactory<Modify2FAPage>(
523 () => Modify2FAPage(setup2FAViewModel: getIt.get<Setup2FAViewModel>()));
524
525 - getIt.registerFactory<DesktopSettingsPage>(
526 - () => DesktopSettingsPage());
525 + getIt.registerFactory<DesktopSettingsPage>(() => DesktopSettingsPage());
526
527 getIt.registerFactoryParam<ReceiveOptionViewModel, ReceivePageOption?, void>(
528 (pageOption, _) => ReceiveOptionViewModel(getIt.get<AppStore>().wallet!, pageOption));
@@ -766,7 +765,10 @@ Future<void> setup({
765
766 getIt.registerFactory(() => OtherSettingsPage(getIt.get<OtherSettingsViewModel>()));
767
769 - getIt.registerFactory(() => NanoChangeRepPage(getIt.get<AppStore>().wallet!));
768 + getIt.registerFactory(() => NanoChangeRepPage(
769 + settingsStore: getIt.get<AppStore>().settingsStore,
770 + wallet: getIt.get<AppStore>().wallet!,
771 + ));
772
773 getIt.registerFactoryParam<NodeCreateOrEditViewModel, WalletType?, bool?>(
774 (WalletType? type, bool? isPow) => NodeCreateOrEditViewModel(
@@ -839,7 +841,8 @@ Future<void> setup({
841 case WalletType.ethereum:
842 return ethereum!.createEthereumWalletService(_walletInfoSource);
843 case WalletType.bitcoinCash:
842 - return bitcoinCash!.createBitcoinCashWalletService(_walletInfoSource, _unspentCoinsInfoSource!);
844 + return bitcoinCash!
845 + .createBitcoinCashWalletService(_walletInfoSource, _unspentCoinsInfoSource!);
846 case WalletType.nano:
847 return nano!.createNanoWalletService(_walletInfoSource);
848 default:
lib/entities/preferences_key.dart
+2
@@ -50,6 +50,8 @@ class PreferencesKey {
50 static const sortBalanceBy = 'sort_balance_by';
51 static const pinNativeTokenAtTop = 'pin_native_token_at_top';
52 static const useEtherscan = 'use_etherscan';
53 + static const defaultNanoRep = 'default_nano_representative';
54 + static const defaultBananoRep = 'default_banano_representative';
55 static const lookupsTwitter = 'looks_up_twitter';
56 static const lookupsMastodon = 'looks_up_mastodon';
57 static const lookupsYatService = 'looks_up_mastodon';
lib/nano/cw_nano.dart
+4 -1
@@ -166,7 +166,10 @@ class CWNano extends Nano {
166
167 @override
168 Future<void> changeRep(Object wallet, String address) async {
169 - return (wallet as NanoWallet).changeRep(address);
169 + if ((wallet as NanoWallet).transactionHistory.transactions.isEmpty) {
170 + throw Exception("Can't change representative without an existing transaction history");
171 + }
172 + return wallet.changeRep(address);
173 }
174
175 @override
lib/reactions/on_current_wallet_change.dart
+1
@@ -2,6 +2,7 @@ import 'package:cake_wallet/entities/auto_generate_subaddress_status.dart';
2 import 'package:cake_wallet/entities/fiat_api_mode.dart';
3 import 'package:cake_wallet/entities/update_haven_rate.dart';
4 import 'package:cake_wallet/ethereum/ethereum.dart';
5 +import 'package:cake_wallet/nano/nano.dart';
6 import 'package:cw_core/transaction_history.dart';
7 import 'package:cw_core/balance.dart';
8 import 'package:cw_core/transaction_info.dart';
lib/src/screens/nano/nano_change_rep_page.dart
+44 -8
@@ -1,8 +1,11 @@
1 import 'package:cake_wallet/core/address_validator.dart';
2 import 'package:cake_wallet/nano/nano.dart';
3 +import 'package:cake_wallet/src/widgets/address_text_field.dart';
4 import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
5 import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
5 -import 'package:cake_wallet/src/widgets/base_text_form_field.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/utils/payment_request.dart';
9 import 'package:cake_wallet/utils/show_pop_up.dart';
10 import 'package:cw_core/crypto_currency.dart';
11 import 'package:cw_core/wallet_base.dart';
@@ -14,21 +17,28 @@ import 'package:cake_wallet/src/screens/base_page.dart';
17 import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
18
19 class NanoChangeRepPage extends BasePage {
17 - NanoChangeRepPage(WalletBase wallet)
20 + NanoChangeRepPage({required SettingsStore settingsStore, required WalletBase wallet})
21 : _wallet = wallet,
19 - _addressController = TextEditingController() {
22 + _settingsStore = settingsStore,
23 + _addressController = TextEditingController(),
24 + _formKey = GlobalKey<FormState>() {
25 _addressController.text = nano!.getRepresentative(wallet);
26 }
27
28 final TextEditingController _addressController;
29 final WalletBase _wallet;
30 + final SettingsStore _settingsStore;
31 +
32 + final GlobalKey<FormState> _formKey;
33
34 @override
35 String get title => S.current.change_rep;
36
37 @override
38 Widget body(BuildContext context) {
31 - return Container(
39 + return Form(
40 + key: _formKey,
41 + child: Container(
42 padding: EdgeInsets.only(left: 24, right: 24),
43 child: ScrollableWithBottomSection(
44 contentPadding: EdgeInsets.only(bottom: 24.0),
@@ -38,9 +48,17 @@ class NanoChangeRepPage extends BasePage {
48 Row(
49 children: <Widget>[
50 Expanded(
41 - child: BaseTextFormField(
51 + child: AddressTextField(
52 controller: _addressController,
43 - hintText: S.of(context).node_address,
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),
63 ),
64 )
@@ -59,6 +77,11 @@ class NanoChangeRepPage extends BasePage {
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) {
@@ -74,8 +97,19 @@ class NanoChangeRepPage extends BasePage {
97
98 if (confirmed) {
99 try {
100 + _settingsStore.defaultNanoRep = _addressController.text;
101 +
102 await nano!.changeRep(_wallet, _addressController.text);
78 - Navigator.of(context).pop();
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,
@@ -97,6 +131,8 @@ class NanoChangeRepPage extends BasePage {
131 )),
132 ],
133 )),
100 - ));
134 + ),
135 + ),
136 + );
137 }
138 }
lib/store/settings_store.dart
+51 -29
@@ -86,6 +86,8 @@ abstract class SettingsStoreBase with Store {
86 required this.sortBalanceBy,
87 required this.pinNativeTokenAtTop,
88 required this.useEtherscan,
89 + required this.defaultNanoRep,
90 + required this.defaultBananoRep,
91 required this.lookupsTwitter,
92 required this.lookupsMastodon,
93 required this.lookupsYatService,
@@ -378,6 +380,13 @@ abstract class SettingsStoreBase with Store {
380 (bool useEtherscan) =>
381 _sharedPreferences.setBool(PreferencesKey.useEtherscan, useEtherscan));
382
383 + reaction((_) => defaultNanoRep,
384 + (String nanoRep) => _sharedPreferences.setString(PreferencesKey.defaultNanoRep, nanoRep));
385 +
386 + reaction(
387 + (_) => defaultBananoRep,
388 + (String bananoRep) =>
389 + _sharedPreferences.setString(PreferencesKey.defaultBananoRep, bananoRep));
390 reaction(
391 (_) => lookupsTwitter,
392 (bool looksUpTwitter) =>
@@ -541,6 +550,12 @@ abstract class SettingsStoreBase with Store {
550 @observable
551 bool useEtherscan;
552
553 + @observable
554 + String defaultNanoRep;
555 +
556 + @observable
557 + String defaultBananoRep;
558 +
559 @observable
560 bool lookupsTwitter;
561
@@ -618,8 +633,8 @@ abstract class SettingsStoreBase with Store {
633 TransactionPriority? moneroTransactionPriority = monero?.deserializeMoneroTransactionPriority(
634 raw: sharedPreferences.getInt(PreferencesKey.moneroTransactionPriority)!);
635 TransactionPriority? bitcoinTransactionPriority =
621 - bitcoin?.deserializeBitcoinTransactionPriority(
622 - sharedPreferences.getInt(PreferencesKey.bitcoinTransactionPriority)!);
636 + bitcoin?.deserializeBitcoinTransactionPriority(
637 + sharedPreferences.getInt(PreferencesKey.bitcoinTransactionPriority)!);
638
639 TransactionPriority? havenTransactionPriority;
640 TransactionPriority? litecoinTransactionPriority;
@@ -658,8 +673,8 @@ abstract class SettingsStoreBase with Store {
673 final isAppSecure = sharedPreferences.getBool(PreferencesKey.isAppSecureKey) ?? false;
674 final disableBuy = sharedPreferences.getBool(PreferencesKey.disableBuyKey) ?? false;
675 final disableSell = sharedPreferences.getBool(PreferencesKey.disableSellKey) ?? false;
661 - final defaultBuyProvider = BuyProviderType.values[sharedPreferences.getInt(
662 - PreferencesKey.defaultBuyProvider) ?? 0];
676 + final defaultBuyProvider =
677 + BuyProviderType.values[sharedPreferences.getInt(PreferencesKey.defaultBuyProvider) ?? 0];
678 final currentFiatApiMode = FiatApiMode.deserialize(
679 raw: sharedPreferences.getInt(PreferencesKey.currentFiatApiModeKey) ??
680 FiatApiMode.enabled.raw);
@@ -678,7 +693,7 @@ abstract class SettingsStoreBase with Store {
693 sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForSendsToInternalWallets) ??
694 false;
695 final shouldRequireTOTP2FAForExchangesToInternalWallets = sharedPreferences
681 - .getBool(PreferencesKey.shouldRequireTOTP2FAForExchangesToInternalWallets) ??
696 + .getBool(PreferencesKey.shouldRequireTOTP2FAForExchangesToInternalWallets) ??
697 false;
698 final shouldRequireTOTP2FAForExchangesToExternalWallets = sharedPreferences
699 .getBool(PreferencesKey.shouldRequireTOTP2FAForExchangesToExternalWallets) ??
@@ -689,7 +704,7 @@ abstract class SettingsStoreBase with Store {
704 sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForCreatingNewWallets) ??
705 false;
706 final shouldRequireTOTP2FAForAllSecurityAndBackupSettings = sharedPreferences
692 - .getBool(PreferencesKey.shouldRequireTOTP2FAForAllSecurityAndBackupSettings) ??
707 + .getBool(PreferencesKey.shouldRequireTOTP2FAForAllSecurityAndBackupSettings) ??
708 false;
709 final useTOTP2FA = sharedPreferences.getBool(PreferencesKey.useTOTP2FA) ?? false;
710 final totpSecretKey = sharedPreferences.getString(PreferencesKey.totpSecretKey) ?? '';
@@ -718,10 +733,12 @@ abstract class SettingsStoreBase with Store {
733 ? SeedPhraseLength.deserialize(raw: seedPhraseCount)
734 : defaultSeedPhraseLength;
735 final sortBalanceBy =
721 - SortBalanceBy.values[sharedPreferences.getInt(PreferencesKey.sortBalanceBy) ?? 0];
736 + SortBalanceBy.values[sharedPreferences.getInt(PreferencesKey.sortBalanceBy) ?? 0];
737 final pinNativeTokenAtTop =
738 sharedPreferences.getBool(PreferencesKey.pinNativeTokenAtTop) ?? true;
739 final useEtherscan = sharedPreferences.getBool(PreferencesKey.useEtherscan) ?? true;
740 + final defaultNanoRep = sharedPreferences.getString(PreferencesKey.defaultNanoRep) ?? "";
741 + final defaultBananoRep = sharedPreferences.getString(PreferencesKey.defaultBananoRep) ?? "";
742 final lookupsTwitter = sharedPreferences.getBool(PreferencesKey.lookupsTwitter) ?? true;
743 final lookupsMastodon = sharedPreferences.getBool(PreferencesKey.lookupsMastodon) ?? true;
744 final lookupsYatService = sharedPreferences.getBool(PreferencesKey.lookupsYatService) ?? true;
@@ -738,11 +755,11 @@ abstract class SettingsStoreBase with Store {
755 await LanguageService.localeDetection();
756 final nodeId = sharedPreferences.getInt(PreferencesKey.currentNodeIdKey);
757 final bitcoinElectrumServerId =
741 - sharedPreferences.getInt(PreferencesKey.currentBitcoinElectrumSererIdKey);
758 + sharedPreferences.getInt(PreferencesKey.currentBitcoinElectrumSererIdKey);
759 final litecoinElectrumServerId =
743 - sharedPreferences.getInt(PreferencesKey.currentLitecoinElectrumSererIdKey);
760 + sharedPreferences.getInt(PreferencesKey.currentLitecoinElectrumSererIdKey);
761 final bitcoinCashElectrumServerId =
745 - sharedPreferences.getInt(PreferencesKey.currentBitcoinCashNodeIdKey);
762 + sharedPreferences.getInt(PreferencesKey.currentBitcoinCashNodeIdKey);
763 final havenNodeId = sharedPreferences.getInt(PreferencesKey.currentHavenNodeIdKey);
764 final ethereumNodeId = sharedPreferences.getInt(PreferencesKey.currentEthereumNodeIdKey);
765 final nanoNodeId = sharedPreferences.getInt(PreferencesKey.currentNanoNodeIdKey);
@@ -759,7 +776,7 @@ abstract class SettingsStoreBase with Store {
776 final deviceName = await _getDeviceName() ?? '';
777 final shouldShowYatPopup = sharedPreferences.getBool(PreferencesKey.shouldShowYatPopup) ?? true;
778 final generateSubaddresses =
762 - sharedPreferences.getInt(PreferencesKey.autoGenerateSubaddressStatusKey);
779 + sharedPreferences.getInt(PreferencesKey.autoGenerateSubaddressStatusKey);
780
781 final autoGenerateSubaddressStatus = generateSubaddresses != null
782 ? AutoGenerateSubaddressStatus.deserialize(raw: generateSubaddresses)
@@ -799,10 +816,10 @@ abstract class SettingsStoreBase with Store {
816 powNodes[WalletType.nano] = nanoPowNode;
817 }
818
802 - final savedSyncMode = SyncMode.all.firstWhere((element) {
803 - return element.type.index == (sharedPreferences.getInt(PreferencesKey.syncModeKey) ?? 1);
804 - });
805 - final savedSyncAll = sharedPreferences.getBool(PreferencesKey.syncAllKey) ?? true;
819 + final savedSyncMode = SyncMode.all.firstWhere((element) {
820 + return element.type.index == (sharedPreferences.getInt(PreferencesKey.syncModeKey) ?? 1);
821 + });
822 + final savedSyncAll = sharedPreferences.getBool(PreferencesKey.syncAllKey) ?? true;
823
824 return SettingsStore(
825 sharedPreferences: sharedPreferences,
@@ -836,6 +853,8 @@ abstract class SettingsStoreBase with Store {
853 sortBalanceBy: sortBalanceBy,
854 pinNativeTokenAtTop: pinNativeTokenAtTop,
855 useEtherscan: useEtherscan,
856 + defaultNanoRep: defaultNanoRep,
857 + defaultBananoRep: defaultBananoRep,
858 lookupsTwitter: lookupsTwitter,
859 lookupsMastodon: lookupsMastodon,
860 lookupsYatService: lookupsYatService,
@@ -874,35 +893,35 @@ abstract class SettingsStoreBase with Store {
893 raw: sharedPreferences.getString(PreferencesKey.currentFiatCurrencyKey)!);
894
895 priority[WalletType.monero] = monero?.deserializeMoneroTransactionPriority(
877 - raw: sharedPreferences.getInt(PreferencesKey.moneroTransactionPriority)!) ??
896 + raw: sharedPreferences.getInt(PreferencesKey.moneroTransactionPriority)!) ??
897 priority[WalletType.monero]!;
898 priority[WalletType.bitcoin] = bitcoin?.deserializeBitcoinTransactionPriority(
880 - sharedPreferences.getInt(PreferencesKey.moneroTransactionPriority)!) ??
899 + sharedPreferences.getInt(PreferencesKey.moneroTransactionPriority)!) ??
900 priority[WalletType.bitcoin]!;
901
902 if (sharedPreferences.getInt(PreferencesKey.havenTransactionPriority) != null) {
903 priority[WalletType.haven] = monero?.deserializeMoneroTransactionPriority(
885 - raw: sharedPreferences.getInt(PreferencesKey.havenTransactionPriority)!) ??
904 + raw: sharedPreferences.getInt(PreferencesKey.havenTransactionPriority)!) ??
905 priority[WalletType.haven]!;
906 }
907 if (sharedPreferences.getInt(PreferencesKey.litecoinTransactionPriority) != null) {
908 priority[WalletType.litecoin] = bitcoin?.deserializeLitecoinTransactionPriority(
890 - sharedPreferences.getInt(PreferencesKey.litecoinTransactionPriority)!) ??
909 + sharedPreferences.getInt(PreferencesKey.litecoinTransactionPriority)!) ??
910 priority[WalletType.litecoin]!;
911 }
912 if (sharedPreferences.getInt(PreferencesKey.ethereumTransactionPriority) != null) {
913 priority[WalletType.ethereum] = ethereum?.deserializeEthereumTransactionPriority(
895 - sharedPreferences.getInt(PreferencesKey.ethereumTransactionPriority)!) ??
914 + sharedPreferences.getInt(PreferencesKey.ethereumTransactionPriority)!) ??
915 priority[WalletType.ethereum]!;
916 }
917 if (sharedPreferences.getInt(PreferencesKey.bitcoinCashTransactionPriority) != null) {
918 priority[WalletType.bitcoinCash] = bitcoinCash?.deserializeBitcoinCashTransactionPriority(
900 - sharedPreferences.getInt(PreferencesKey.bitcoinCashTransactionPriority)!) ??
919 + sharedPreferences.getInt(PreferencesKey.bitcoinCashTransactionPriority)!) ??
920 priority[WalletType.bitcoinCash]!;
921 }
922
923 final generateSubaddresses =
905 - sharedPreferences.getInt(PreferencesKey.autoGenerateSubaddressStatusKey);
924 + sharedPreferences.getInt(PreferencesKey.autoGenerateSubaddressStatusKey);
925
926 autoGenerateSubaddressStatus = generateSubaddresses != null
927 ? AutoGenerateSubaddressStatus.deserialize(raw: generateSubaddresses)
@@ -921,7 +940,7 @@ abstract class SettingsStoreBase with Store {
940 disableBuy = sharedPreferences.getBool(PreferencesKey.disableBuyKey) ?? disableBuy;
941 disableSell = sharedPreferences.getBool(PreferencesKey.disableSellKey) ?? disableSell;
942 defaultBuyProvider =
924 - BuyProviderType.values[sharedPreferences.getInt(PreferencesKey.defaultBuyProvider) ?? 0];
943 + BuyProviderType.values[sharedPreferences.getInt(PreferencesKey.defaultBuyProvider) ?? 0];
944 allowBiometricalAuthentication =
945 sharedPreferences.getBool(PreferencesKey.allowBiometricalAuthenticationKey) ??
946 allowBiometricalAuthentication;
@@ -938,7 +957,7 @@ abstract class SettingsStoreBase with Store {
957 sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForSendsToInternalWallets) ??
958 false;
959 shouldRequireTOTP2FAForExchangesToInternalWallets = sharedPreferences
941 - .getBool(PreferencesKey.shouldRequireTOTP2FAForExchangesToInternalWallets) ??
960 + .getBool(PreferencesKey.shouldRequireTOTP2FAForExchangesToInternalWallets) ??
961 false;
962 shouldRequireTOTP2FAForExchangesToExternalWallets = sharedPreferences
963 .getBool(PreferencesKey.shouldRequireTOTP2FAForExchangesToExternalWallets) ??
@@ -949,7 +968,7 @@ abstract class SettingsStoreBase with Store {
968 sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForCreatingNewWallets) ??
969 false;
970 shouldRequireTOTP2FAForAllSecurityAndBackupSettings = sharedPreferences
952 - .getBool(PreferencesKey.shouldRequireTOTP2FAForAllSecurityAndBackupSettings) ??
971 + .getBool(PreferencesKey.shouldRequireTOTP2FAForAllSecurityAndBackupSettings) ??
972 false;
973 shouldShowMarketPlaceInDashboard =
974 sharedPreferences.getBool(PreferencesKey.shouldShowMarketPlaceInDashboard) ??
@@ -982,6 +1001,8 @@ abstract class SettingsStoreBase with Store {
1001 .values[sharedPreferences.getInt(PreferencesKey.sortBalanceBy) ?? sortBalanceBy.index];
1002 pinNativeTokenAtTop = sharedPreferences.getBool(PreferencesKey.pinNativeTokenAtTop) ?? true;
1003 useEtherscan = sharedPreferences.getBool(PreferencesKey.useEtherscan) ?? true;
1004 + defaultNanoRep = sharedPreferences.getString(PreferencesKey.defaultNanoRep) ?? "";
1005 + defaultBananoRep = sharedPreferences.getString(PreferencesKey.defaultBananoRep) ?? "";
1006 lookupsTwitter = sharedPreferences.getBool(PreferencesKey.lookupsTwitter) ?? true;
1007 lookupsMastodon = sharedPreferences.getBool(PreferencesKey.lookupsMastodon) ?? true;
1008 lookupsYatService = sharedPreferences.getBool(PreferencesKey.lookupsYatService) ?? true;
@@ -991,11 +1012,11 @@ abstract class SettingsStoreBase with Store {
1012
1013 final nodeId = sharedPreferences.getInt(PreferencesKey.currentNodeIdKey);
1014 final bitcoinElectrumServerId =
994 - sharedPreferences.getInt(PreferencesKey.currentBitcoinElectrumSererIdKey);
1015 + sharedPreferences.getInt(PreferencesKey.currentBitcoinElectrumSererIdKey);
1016 final litecoinElectrumServerId =
996 - sharedPreferences.getInt(PreferencesKey.currentLitecoinElectrumSererIdKey);
1017 + sharedPreferences.getInt(PreferencesKey.currentLitecoinElectrumSererIdKey);
1018 final bitcoinCashElectrumServerId =
998 - sharedPreferences.getInt(PreferencesKey.currentBitcoinCashNodeIdKey);
1019 + sharedPreferences.getInt(PreferencesKey.currentBitcoinCashNodeIdKey);
1020 final havenNodeId = sharedPreferences.getInt(PreferencesKey.currentHavenNodeIdKey);
1021 final ethereumNodeId = sharedPreferences.getInt(PreferencesKey.currentEthereumNodeIdKey);
1022 final nanoNodeId = sharedPreferences.getInt(PreferencesKey.currentNanoNodeIdKey);
@@ -1057,7 +1078,8 @@ abstract class SettingsStoreBase with Store {
1078 await _sharedPreferences.setInt(PreferencesKey.currentEthereumNodeIdKey, node.key as int);
1079 break;
1080 case WalletType.bitcoinCash:
1060 - await _sharedPreferences.setInt(PreferencesKey.currentBitcoinCashNodeIdKey, node.key as int);
1081 + await _sharedPreferences.setInt(
1082 + PreferencesKey.currentBitcoinCashNodeIdKey, node.key as int);
1083 break;
1084 case WalletType.nano:
1085 await _sharedPreferences.setInt(PreferencesKey.currentNanoNodeIdKey, node.key as int);
res/values/strings_ar.arb
+1
@@ -720,6 +720,7 @@
720 "enterWalletConnectURI": "WalletConnect ـﻟ URI ﻞﺧﺩﺃ",
721 "seed_key": "مفتاح البذور",
722 "enter_seed_phrase": "أدخل عبارة البذور الخاصة بك",
723 + "change_rep_successful": "تم تغيير ممثل بنجاح",
724 "add_contact": "ﻝﺎﺼﺗﺍ ﺔﻬﺟ ﺔﻓﺎﺿﺇ",
725 "exchange_provider_unsupported": "${providerName} لم يعد مدعومًا!",
726 "domain_looks_up": "ﻝﺎﺠﻤﻟﺍ ﺚﺤﺑ ﺕﺎﻴﻠﻤﻋ",
res/values/strings_bg.arb
+1
@@ -716,6 +716,7 @@
716 "enterWalletConnectURI": "Въведете URI на WalletConnect",
717 "seed_key": "Ключ за семена",
718 "enter_seed_phrase": "Въведете вашата фраза за семена",
719 + "change_rep_successful": "Успешно промени представител",
720 "add_contact": "Добави контакт",
721 "exchange_provider_unsupported": "${providerName} вече не се поддържа!",
722 "domain_looks_up": "Търсене на домейни",
res/values/strings_cs.arb
+1
@@ -716,6 +716,7 @@
716 "enterWalletConnectURI": "Zadejte identifikátor URI WalletConnect",
717 "seed_key": "Klíč semen",
718 "enter_seed_phrase": "Zadejte svou frázi semen",
719 + "change_rep_successful": "Úspěšně změnil zástupce",
720 "add_contact": "Přidat kontakt",
721 "exchange_provider_unsupported": "${providerName} již není podporováno!",
722 "domain_looks_up": "Vyhledávání domén",
res/values/strings_de.arb
+3 -2
@@ -722,8 +722,9 @@
722 "awaitDAppProcessing": "Bitte warten Sie, bis die dApp die Verarbeitung abgeschlossen hat.",
723 "copyWalletConnectLink": "Kopieren Sie den WalletConnect-Link von dApp und fügen Sie ihn hier ein",
724 "enterWalletConnectURI": "Geben Sie den WalletConnect-URI ein",
725 - "seed_key": "Seed-Schlüssel",
726 - "enter_seed_phrase": "Geben Sie Ihre Seed-Phrase ein",
725 + "seed_key": "Samenschlüssel",
726 + "enter_seed_phrase": "Geben Sie Ihre Samenphrase ein",
727 + "change_rep_successful": "Erfolgreich veränderte Vertreter",
728 "add_contact": "Kontakt hinzufügen",
729 "exchange_provider_unsupported": "${providerName} wird nicht mehr unterstützt!",
730 "domain_looks_up": "Domain-Suchen",
res/values/strings_en.arb
+1
@@ -725,6 +725,7 @@
725 "enterWalletConnectURI": "Enter WalletConnect URI",
726 "seed_key": "Seed key",
727 "enter_seed_phrase": "Enter your seed phrase",
728 + "change_rep_successful": "Successfully changed representative",
729 "add_contact": "Add contact",
730 "exchange_provider_unsupported": "${providerName} is no longer supported!",
731 "domain_looks_up": "Domain lookups",
res/values/strings_es.arb
+1
@@ -724,6 +724,7 @@
724 "enterWalletConnectURI": "Ingrese el URI de WalletConnect",
725 "seed_key": "Llave de semilla",
726 "enter_seed_phrase": "Ingrese su frase de semillas",
727 + "change_rep_successful": "Representante cambiado con éxito",
728 "add_contact": "Agregar contacto",
729 "exchange_provider_unsupported": "¡${providerName} ya no es compatible!",
730 "domain_looks_up": "Búsquedas de dominio",
res/values/strings_fr.arb
+3 -2
@@ -722,8 +722,9 @@
722 "awaitDAppProcessing": "Veuillez attendre que l'application décentralisée (dApp) termine le traitement.",
723 "copyWalletConnectLink": "Copiez le lien WalletConnect depuis l'application décentralisée (dApp) et collez-le ici",
724 "enterWalletConnectURI": "Saisissez l'URI de WalletConnect.",
725 - "seed_key": "Clé secrète (seed key)",
726 - "enter_seed_phrase": "Entrez votre phrase secrète (seed)",
725 + "seed_key": "Clé de graines",
726 + "enter_seed_phrase": "Entrez votre phrase de semence",
727 + "change_rep_successful": "Représentant changé avec succès",
728 "add_contact": "Ajouter le contact",
729 "exchange_provider_unsupported": "${providerName} n'est plus pris en charge !",
730 "domain_looks_up": "Résolution de nom",
res/values/strings_ha.arb
+1
@@ -702,6 +702,7 @@
702 "enterWalletConnectURI": "Shigar da WalletConnect URI",
703 "seed_key": "Maɓallin iri",
704 "enter_seed_phrase": "Shigar da Sert Sentarku",
705 + "change_rep_successful": "An samu nasarar canzawa wakilin",
706 "add_contact": "Ƙara lamba",
707 "exchange_provider_unsupported": "${providerName}",
708 "domain_looks_up": "Binciken yanki",
res/values/strings_hi.arb
+1
@@ -724,6 +724,7 @@
724 "enterWalletConnectURI": "वॉलेटकनेक्ट यूआरआई दर्ज करें",
725 "seed_key": "बीज कुंजी",
726 "enter_seed_phrase": "अपना बीज वाक्यांश दर्ज करें",
727 + "change_rep_successful": "सफलतापूर्वक बदलकर प्रतिनिधि",
728 "add_contact": "संपर्क जोड़ें",
729 "exchange_provider_unsupported": "${providerName} अब समर्थित नहीं है!",
730 "domain_looks_up": "डोमेन लुकअप",
res/values/strings_hr.arb
+1
@@ -722,6 +722,7 @@
722 "enterWalletConnectURI": "Unesite WalletConnect URI",
723 "seed_key": "Sjemenski ključ",
724 "enter_seed_phrase": "Unesite svoju sjemensku frazu",
725 + "change_rep_successful": "Uspješno promijenjena reprezentativna",
726 "add_contact": "Dodaj kontakt",
727 "exchange_provider_unsupported": "${providerName} više nije podržan!",
728 "domain_looks_up": "Pretraga domena",
res/values/strings_id.arb
+1
@@ -712,6 +712,7 @@
712 "enterWalletConnectURI": "Masukkan URI WalletConnect",
713 "seed_key": "Kunci benih",
714 "enter_seed_phrase": "Masukkan frasa benih Anda",
715 + "change_rep_successful": "Berhasil mengubah perwakilan",
716 "add_contact": "Tambah kontak",
717 "exchange_provider_unsupported": "${providerName} tidak lagi didukung!",
718 "domain_looks_up": "Pencarian domain",
res/values/strings_it.arb
+1
@@ -724,6 +724,7 @@
724 "enterWalletConnectURI": "Inserisci l'URI di WalletConnect",
725 "seed_key": "Chiave di semi",
726 "enter_seed_phrase": "Inserisci la tua frase di semi",
727 + "change_rep_successful": "Rappresentante modificato con successo",
728 "add_contact": "Aggiungi contatto",
729 "exchange_provider_unsupported": "${providerName} non è più supportato!",
730 "domain_looks_up": "Ricerche di domini",
res/values/strings_ja.arb
+1
@@ -724,6 +724,7 @@
724 "enterWalletConnectURI": "WalletConnect URI を入力してください",
725 "seed_key": "シードキー",
726 "enter_seed_phrase": "シードフレーズを入力してください",
727 + "change_rep_successful": "代表者の変更に成功しました",
728 "add_contact": "連絡先を追加",
729 "exchange_provider_unsupported": "${providerName}はサポートされなくなりました!",
730 "domain_looks_up": "ドメイン検索",
res/values/strings_ko.arb
+1
@@ -722,6 +722,7 @@
722 "enterWalletConnectURI": "WalletConnect URI를 입력하세요.",
723 "seed_key": "시드 키",
724 "enter_seed_phrase": "시드 문구를 입력하십시오",
725 + "change_rep_successful": "대리인이 성공적으로 변경되었습니다",
726 "add_contact": "주소록에 추가",
727 "exchange_provider_unsupported": "${providerName}은 더 이상 지원되지 않습니다!",
728 "domain_looks_up": "도메인 조회",
res/values/strings_my.arb
+1
@@ -722,6 +722,7 @@
722 "enterWalletConnectURI": "WalletConnect URI ကိုရိုက်ထည့်ပါ။",
723 "seed_key": "မျိုးစေ့သော့",
724 "enter_seed_phrase": "သင့်ရဲ့မျိုးစေ့စကားစုကိုရိုက်ထည့်ပါ",
725 + "change_rep_successful": "အောင်မြင်စွာကိုယ်စားလှယ်ပြောင်းလဲသွားတယ်",
726 "add_contact": "အဆက်အသွယ်ထည့်ပါ။",
727 "exchange_provider_unsupported": "${providerName} မရှိတော့ပါ!",
728 "domain_looks_up": "ဒိုမိန်းရှာဖွေမှုများ",
res/values/strings_nl.arb
+1
@@ -724,6 +724,7 @@
724 "enterWalletConnectURI": "Voer WalletConnect-URI in",
725 "seed_key": "Zaadsleutel",
726 "enter_seed_phrase": "Voer uw zaadzin in",
727 + "change_rep_successful": "Met succes veranderde vertegenwoordiger",
728 "add_contact": "Contactpersoon toevoegen",
729 "exchange_provider_unsupported": "${providerName} wordt niet langer ondersteund!",
730 "domain_looks_up": "Domein opzoeken",
res/values/strings_pl.arb
+1
@@ -724,6 +724,7 @@
724 "enterWalletConnectURI": "Wprowadź identyfikator URI WalletConnect",
725 "seed_key": "Klucz nasion",
726 "enter_seed_phrase": "Wprowadź swoją frazę nasienną",
727 + "change_rep_successful": "Pomyślnie zmienił przedstawiciela",
728 "add_contact": "Dodaj kontakt",
729 "exchange_provider_unsupported": "${providerName} nie jest już obsługiwany!",
730 "domain_looks_up": "Wyszukiwanie domen",
res/values/strings_pt.arb
+1
@@ -723,6 +723,7 @@
723 "enterWalletConnectURI": "Insira o URI do WalletConnect",
724 "seed_key": "Chave de semente",
725 "enter_seed_phrase": "Digite sua frase de semente",
726 + "change_rep_successful": "Mudou com sucesso o representante",
727 "add_contact": "Adicionar contato",
728 "exchange_provider_unsupported": "${providerName} não é mais suportado!",
729 "domain_looks_up": "Pesquisas de domínio",
res/values/strings_ru.arb
+1
@@ -724,6 +724,7 @@
724 "enterWalletConnectURI": "Введите URI WalletConnect",
725 "seed_key": "Ключ семян",
726 "enter_seed_phrase": "Введите свою семенную фразу",
727 + "change_rep_successful": "Успешно изменил представитель",
728 "add_contact": "Добавить контакт",
729 "exchange_provider_unsupported": "${providerName} больше не поддерживается!",
730 "domain_looks_up": "Поиск доменов",
res/values/strings_th.arb
+1
@@ -722,6 +722,7 @@
722 "enterWalletConnectURI": "เข้าสู่ WalletConnect URI",
723 "seed_key": "คีย์เมล็ดพันธุ์",
724 "enter_seed_phrase": "ป้อนวลีเมล็ดพันธุ์ของคุณ",
725 + "change_rep_successful": "เปลี่ยนตัวแทนสำเร็จ",
726 "add_contact": "เพิ่มผู้ติดต่อ",
727 "exchange_provider_unsupported": "${providerName} ไม่ได้รับการสนับสนุนอีกต่อไป!",
728 "domain_looks_up": "การค้นหาโดเมน",
res/values/strings_tl.arb
+1
@@ -719,6 +719,7 @@
719 "enterWalletConnectURI": "Ilagay ang WalletConnect URI",
720 "seed_key": "Seed Key",
721 "enter_seed_phrase": "Ipasok ang iyong pariralang binhi",
722 + "change_rep_successful": "Matagumpay na nagbago ng kinatawan",
723 "add_contact": "Magdagdag ng contact",
724 "exchange_provider_unsupported": "Ang ${providerName} ay hindi na suportado!",
725 "domain_looks_up": "Mga paghahanap ng domain",
res/values/strings_tr.arb
+1
@@ -722,6 +722,7 @@
722 "enterWalletConnectURI": "WalletConnect URI'sini girin",
723 "seed_key": "Tohum",
724 "enter_seed_phrase": "Tohum ifadenizi girin",
725 + "change_rep_successful": "Temsilciyi başarıyla değiştirdi",
726 "add_contact": "Kişi ekle",
727 "exchange_provider_unsupported": "${providerName} artık desteklenmiyor!",
728 "domain_looks_up": "Etki alanı aramaları",
res/values/strings_uk.arb
+1
@@ -724,6 +724,7 @@
724 "enterWalletConnectURI": "Введіть URI WalletConnect",
725 "seed_key": "Насіннєвий ключ",
726 "enter_seed_phrase": "Введіть свою насіннєву фразу",
727 + "change_rep_successful": "Успішно змінив представник",
728 "add_contact": "Додати контакт",
729 "exchange_provider_unsupported": "${providerName} більше не підтримується!",
730 "domain_looks_up": "Пошук доменів",
res/values/strings_ur.arb
+1
@@ -716,6 +716,7 @@
716 "enterWalletConnectURI": "WalletConnect URI ۔ﮟﯾﺮﮐ ﺝﺭﺩ",
717 "seed_key": "بیج کی کلید",
718 "enter_seed_phrase": "اپنے بیج کا جملہ درج کریں",
719 + "change_rep_successful": "نمائندہ کو کامیابی کے ساتھ تبدیل کیا",
720 "add_contact": "۔ﮟﯾﺮﮐ ﻞﻣﺎﺷ ﮧﻄﺑﺍﺭ",
721 "exchange_provider_unsupported": "${providerName} اب تعاون نہیں کیا جاتا ہے!",
722 "domain_looks_up": "ڈومین تلاش کرنا",
res/values/strings_yo.arb
+1
@@ -718,6 +718,7 @@
718 "enterWalletConnectURI": "Tẹ WalletConnect URI sii",
719 "seed_key": "Bọtini Ose",
720 "enter_seed_phrase": "Tẹ ọrọ-iru irugbin rẹ",
721 + "change_rep_successful": "Ni ifijišẹ yipada aṣoju",
722 "add_contact": "Fi olubasọrọ kun",
723 "exchange_provider_unsupported": "${providerName} ko ni atilẹyin mọ!",
724 "domain_looks_up": "Awọn wiwa agbegbe",
res/values/strings_zh.arb
+1
@@ -723,6 +723,7 @@
723 "enterWalletConnectURI": "输入 WalletConnect URI",
724 "seed_key": "种子钥匙",
725 "enter_seed_phrase": "输入您的种子短语",
726 + "change_rep_successful": "成功改变了代表",
727 "add_contact": "增加联系人",
728 "exchange_provider_unsupported": "${providerName}不再支持!",
729 "domain_looks_up": "域名查找",