Cw 534 monero wallet generic enhancements (#1225)

* Fix word count for polyseed on pre_seed_page * Fix naming of advanced setting * Set default Seed Type to Polyseed and disable bg-sync by default * Fix inconsistency between seed type field in restore screen and the one in advanced settings * Use pub.dev release of polyseed * Add Legacy Seed to wallet_keys-Page in case of Polyseed

Konstantin Ullrich committed Dec 9, 2023 at 02:37 UTC 72777fbf2c33086d21c74bff45e684ed4973e594
42 files changed +203 -99
cw_monero/lib/monero_wallet_service.dart
+1 -2
@@ -13,7 +13,6 @@ import 'package:cw_monero/api/wallet_manager.dart' as monero_wallet_manager;
13 import 'package:cw_monero/monero_wallet.dart';
14 import 'package:hive/hive.dart';
15 import 'package:polyseed/polyseed.dart';
16 -import 'package:polyseed/src/utils/key_utils.dart';
16
17 class MoneroNewWalletCredentials extends WalletCredentials {
18 MoneroNewWalletCredentials({required String name, required this.language, required this.isPolyseed, String? password})
@@ -275,7 +274,7 @@ class MoneroWalletService extends WalletService<
274 {PolyseedCoin coin = PolyseedCoin.POLYSEED_MONERO, int? overrideHeight}) async {
275 final height = overrideHeight ?? getMoneroHeigthByDate(
276 date: DateTime.fromMillisecondsSinceEpoch(polyseed.birthday * 1000));
278 - final spendKey = keyToHexString(polyseed.generateKey(coin, 32));
277 + final spendKey = polyseed.generateKey(coin, 32).toHexString();
278 final seed = polyseed.encode(lang, coin);
279
280 walletInfo.isRecovery = true;
cw_monero/pubspec.lock
+21 -15
@@ -266,6 +266,22 @@ packages:
266 url: "https://pub.dev"
267 source: hosted
268 version: "2.2.0"
269 + hashlib:
270 + dependency: transitive
271 + description:
272 + name: hashlib
273 + sha256: "71bf102329ddb8e50c8a995ee4645ae7f1728bb65e575c17196b4d8262121a96"
274 + url: "https://pub.dev"
275 + source: hosted
276 + version: "1.12.0"
277 + hashlib_codecs:
278 + dependency: transitive
279 + description:
280 + name: hashlib_codecs
281 + sha256: "49e2a471f74b15f1854263e58c2ac11f2b631b5b12c836f9708a35397d36d626"
282 + url: "https://pub.dev"
283 + source: hosted
284 + version: "2.2.0"
285 hive:
286 dependency: transitive
287 description:
@@ -485,12 +501,11 @@ packages:
501 polyseed:
502 dependency: "direct main"
503 description:
488 - path: "."
489 - ref: HEAD
490 - resolved-ref: "504d58a5b147fccd3bc85a25f2e72fb32771ddd7"
491 - url: "https://github.com/cake-tech/polyseed_dart.git"
492 - source: git
493 - version: "0.0.1"
504 + name: polyseed
505 + sha256: "9b48ec535b10863f78f6354ec983b4cc0c88ca69ff48fee469d0fd1954b01d4f"
506 + url: "https://pub.dev"
507 + source: hosted
508 + version: "0.0.2"
509 pool:
510 dependency: transitive
511 description:
@@ -632,15 +647,6 @@ packages:
647 url: "https://pub.dev"
648 source: hosted
649 version: "1.0.1"
635 - tor:
636 - dependency: transitive
637 - description:
638 - path: "."
639 - ref: main
640 - resolved-ref: "09ba92cb11d4e3cacf97256e57863b805f79f2e5"
641 - url: "https://github.com/cake-tech/tor.git"
642 - source: git
643 - version: "0.0.1"
650 typed_data:
651 dependency: transitive
652 description:
cw_monero/pubspec.yaml
+1 -3
@@ -19,9 +19,7 @@ dependencies:
19 flutter_mobx: ^2.0.6+1
20 intl: ^0.18.0
21 encrypt: ^5.0.1
22 - polyseed:
23 - git:
24 - url: https://github.com/cake-tech/polyseed_dart.git
22 + polyseed: ^0.0.2
23 cw_core:
24 path: ../cw_core
25
lib/di.dart
+7 -4
@@ -90,6 +90,7 @@ import 'package:cake_wallet/view_model/ionia/ionia_purchase_merch_view_model.dar
90 import 'package:cake_wallet/view_model/nano_account_list/nano_account_edit_or_create_view_model.dart';
91 import 'package:cake_wallet/view_model/nano_account_list/nano_account_list_view_model.dart';
92 import 'package:cake_wallet/view_model/node_list/pow_node_list_view_model.dart';
93 +import 'package:cake_wallet/view_model/seed_type_view_model.dart';
94 import 'package:cake_wallet/view_model/set_up_2fa_viewmodel.dart';
95 import 'package:cake_wallet/view_model/restore/restore_from_qr_vm.dart';
96 import 'package:cake_wallet/view_model/settings/display_settings_view_model.dart';
@@ -719,6 +720,8 @@ Future<void> setup({
720
721 getIt.registerFactory(() => WalletSeedViewModel(getIt.get<AppStore>().wallet!));
722
723 + getIt.registerFactory<SeedTypeViewModel>(() => SeedTypeViewModel(getIt.get<AppStore>()));
724 +
725 getIt.registerFactoryParam<WalletSeedPage, bool, void>((bool isWalletCreated, _) =>
726 WalletSeedPage(getIt.get<WalletSeedViewModel>(), isNewWalletCreated: isWalletCreated));
727
@@ -850,7 +853,7 @@ Future<void> setup({
853 return ethereum!.createEthereumWalletService(_walletInfoSource);
854 case WalletType.bitcoinCash:
855 return bitcoinCash!
853 - .createBitcoinCashWalletService(_walletInfoSource, _unspentCoinsInfoSource!);
856 + .createBitcoinCashWalletService(_walletInfoSource, _unspentCoinsInfoSource);
857 case WalletType.nano:
858 return nano!.createNanoWalletService(_walletInfoSource);
859 case WalletType.polygon:
@@ -879,8 +882,8 @@ Future<void> setup({
882 getIt.get<AppStore>(), getIt.get<WalletCreationService>(param1: type), _walletInfoSource,
883 type: type));
884
882 - getIt.registerFactoryParam<WalletRestorePage, WalletType, void>(
883 - (type, _) => WalletRestorePage(getIt.get<WalletRestoreViewModel>(param1: type)));
885 + getIt.registerFactoryParam<WalletRestorePage, WalletType, void>((type, _) => WalletRestorePage(
886 + getIt.get<WalletRestoreViewModel>(param1: type), getIt.get<SeedTypeViewModel>()));
887
888 getIt.registerFactoryParam<WalletRestoreChooseDerivationViewModel, List<DerivationInfo>, void>(
889 (derivations, _) => WalletRestoreChooseDerivationViewModel(derivationInfos: derivations));
@@ -911,7 +914,7 @@ Future<void> setup({
914
915 getIt.registerFactoryParam<PreSeedPage, WalletType, AdvancedPrivacySettingsViewModel>(
916 (WalletType type, AdvancedPrivacySettingsViewModel advancedPrivacySettingsViewModel) =>
914 - PreSeedPage(type, advancedPrivacySettingsViewModel));
917 + PreSeedPage(type, advancedPrivacySettingsViewModel, getIt.get<SeedTypeViewModel>()));
918
919 getIt.registerFactoryParam<TradeDetailsViewModel, Trade, void>((trade, _) =>
920 TradeDetailsViewModel(
lib/entities/seed_type.dart
+1 -1
@@ -6,7 +6,7 @@ class SeedType extends EnumerableItem<int> with Serializable<int> {
6
7 static const all = [SeedType.legacy, SeedType.polyseed];
8
9 - static const defaultSeedType = legacy;
9 + static const defaultSeedType = polyseed;
10
11 static const legacy = SeedType(raw: 0, title: 'Legacy (25 words)');
12 static const polyseed = SeedType(raw: 1, title: 'Polyseed (16 words)');
lib/router.dart
+6 -6
@@ -56,13 +56,13 @@ import 'package:cake_wallet/src/screens/support_other_links/support_other_links_
56 import 'package:cake_wallet/src/screens/unspent_coins/unspent_coins_details_page.dart';
57 import 'package:cake_wallet/src/screens/unspent_coins/unspent_coins_list_page.dart';
58 import 'package:cake_wallet/src/screens/wallet_connect/wc_connections_listing_view.dart';
59 -import 'package:cake_wallet/store/settings_store.dart';
59 import 'package:cake_wallet/utils/payment_request.dart';
60 import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
61 import 'package:cake_wallet/view_model/dashboard/nft_view_model.dart';
62 import 'package:cake_wallet/view_model/monero_account_list/account_list_item.dart';
63 import 'package:cake_wallet/view_model/node_list/node_create_or_edit_view_model.dart';
64 import 'package:cake_wallet/view_model/advanced_privacy_settings_view_model.dart';
65 +import 'package:cake_wallet/view_model/seed_type_view_model.dart';
66 import 'package:cake_wallet/wallet_type_utils.dart';
67 import 'package:cw_core/nano_account.dart';
68 import 'package:cw_core/wallet_info.dart';
@@ -147,9 +147,9 @@ Route<dynamic> createRoute(RouteSettings settings) {
147 case Routes.newWallet:
148 final type = settings.arguments as WalletType;
149 final walletNewVM = getIt.get<WalletNewVM>(param1: type);
150 - final settingsStore = getIt.get<SettingsStore>();
150 + final seedTypeViewModel = getIt.get<SeedTypeViewModel>();
151
152 - return CupertinoPageRoute<void>(builder: (_) => NewWalletPage(walletNewVM, settingsStore));
152 + return CupertinoPageRoute<void>(builder: (_) => NewWalletPage(walletNewVM, seedTypeViewModel));
153
154 case Routes.setupPin:
155 Function(PinCodeState<PinCodeWidget>, String)? callback;
@@ -535,9 +535,9 @@ Route<dynamic> createRoute(RouteSettings settings) {
535
536 return CupertinoPageRoute<void>(
537 builder: (_) => AdvancedPrivacySettingsPage(
538 - getIt.get<AdvancedPrivacySettingsViewModel>(param1: type),
539 - getIt.get<NodeCreateOrEditViewModel>(param1: type, param2: false),
540 - ));
538 + getIt.get<AdvancedPrivacySettingsViewModel>(param1: type),
539 + getIt.get<NodeCreateOrEditViewModel>(param1: type, param2: false),
540 + getIt.get<SeedTypeViewModel>()));
541
542 case Routes.anonPayInvoicePage:
543 final args = settings.arguments as List;
lib/src/screens/new_wallet/advanced_privacy_settings_page.dart
+13 -7
@@ -9,6 +9,7 @@ import 'package:cake_wallet/src/screens/settings/widgets/settings_switcher_cell.
9 import 'package:cake_wallet/themes/extensions/new_wallet_theme.dart';
10 import 'package:cake_wallet/view_model/node_list/node_create_or_edit_view_model.dart';
11 import 'package:cake_wallet/view_model/advanced_privacy_settings_view_model.dart';
12 +import 'package:cake_wallet/view_model/seed_type_view_model.dart';
13 import 'package:cake_wallet/view_model/settings/choices_list_item.dart';
14 import 'package:flutter_mobx/flutter_mobx.dart';
15 import 'package:flutter/material.dart';
@@ -18,25 +19,30 @@ import 'package:cake_wallet/src/widgets/primary_button.dart';
19 import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
20
21 class AdvancedPrivacySettingsPage extends BasePage {
21 - AdvancedPrivacySettingsPage(this.advancedPrivacySettingsViewModel, this.nodeViewModel);
22 + AdvancedPrivacySettingsPage(
23 + this.advancedPrivacySettingsViewModel, this.nodeViewModel, this.seedTypeViewModel);
24
25 final AdvancedPrivacySettingsViewModel advancedPrivacySettingsViewModel;
26 final NodeCreateOrEditViewModel nodeViewModel;
27 + final SeedTypeViewModel seedTypeViewModel;
28
29 @override
30 String get title => S.current.privacy_settings;
31
32 @override
30 - Widget body(BuildContext context) =>
31 - AdvancedPrivacySettingsBody(advancedPrivacySettingsViewModel, nodeViewModel);
33 + Widget body(BuildContext context) => AdvancedPrivacySettingsBody(
34 + advancedPrivacySettingsViewModel, nodeViewModel, seedTypeViewModel);
35 }
36
37 class AdvancedPrivacySettingsBody extends StatefulWidget {
35 - const AdvancedPrivacySettingsBody(this.privacySettingsViewModel, this.nodeViewModel, {Key? key})
38 + const AdvancedPrivacySettingsBody(
39 + this.privacySettingsViewModel, this.nodeViewModel, this.seedTypeViewModel,
40 + {Key? key})
41 : super(key: key);
42
43 final AdvancedPrivacySettingsViewModel privacySettingsViewModel;
44 final NodeCreateOrEditViewModel nodeViewModel;
45 + final SeedTypeViewModel seedTypeViewModel;
46
47 @override
48 _AdvancedPrivacySettingsBodyState createState() => _AdvancedPrivacySettingsBodyState();
@@ -59,7 +65,7 @@ class _AdvancedPrivacySettingsBodyState extends State<AdvancedPrivacySettingsBod
65 Observer(builder: (_) {
66 return SettingsChoicesCell(
67 ChoicesListItem<FiatApiMode>(
62 - title: S.current.disable_fiat,
68 + title: S.current.fiat_api,
69 items: FiatApiMode.all,
70 selectedItem: widget.privacySettingsViewModel.fiatApiMode,
71 onItemSelected: (FiatApiMode mode) =>
@@ -114,8 +120,8 @@ class _AdvancedPrivacySettingsBodyState extends State<AdvancedPrivacySettingsBod
120 ChoicesListItem<SeedType>(
121 title: S.current.seedtype,
122 items: SeedType.all,
117 - selectedItem: widget.privacySettingsViewModel.seedType,
118 - onItemSelected: widget.privacySettingsViewModel.setSeedType,
123 + selectedItem: widget.seedTypeViewModel.moneroSeedType,
124 + onItemSelected: widget.seedTypeViewModel.setMoneroSeedType,
125 ),
126 );
127 }),
lib/src/screens/new_wallet/new_wallet_page.dart
+10 -10
@@ -7,6 +7,7 @@ import 'package:cake_wallet/routes.dart';
7 import 'package:cake_wallet/themes/theme_base.dart';
8 import 'package:cake_wallet/utils/responsive_layout_util.dart';
9 import 'package:cake_wallet/utils/show_pop_up.dart';
10 +import 'package:cake_wallet/view_model/seed_type_view_model.dart';
11 import 'package:mobx/mobx.dart';
12 import 'package:flutter_mobx/flutter_mobx.dart';
13 import 'package:flutter/material.dart';
@@ -23,13 +24,12 @@ import 'package:cake_wallet/view_model/wallet_new_vm.dart';
24 import 'package:cake_wallet/themes/extensions/new_wallet_theme.dart';
25 import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
26 import 'package:cake_wallet/entities/seed_type.dart';
26 -import 'package:cake_wallet/store/settings_store.dart';
27
28 class NewWalletPage extends BasePage {
29 - NewWalletPage(this._walletNewVM, this._settingsStore);
29 + NewWalletPage(this._walletNewVM, this._seedTypeViewModel);
30
31 final WalletNewVM _walletNewVM;
32 - final SettingsStore _settingsStore;
32 + final SeedTypeViewModel _seedTypeViewModel;
33
34 final walletNameImage = Image.asset('assets/images/wallet_name.png');
35
@@ -40,15 +40,15 @@ class NewWalletPage extends BasePage {
40
41 @override
42 Widget body(BuildContext context) => WalletNameForm(
43 - _walletNewVM, currentTheme.type == ThemeType.dark ? walletNameImage : walletNameLightImage, _settingsStore);
43 + _walletNewVM, currentTheme.type == ThemeType.dark ? walletNameImage : walletNameLightImage, _seedTypeViewModel);
44 }
45
46 class WalletNameForm extends StatefulWidget {
47 - WalletNameForm(this._walletNewVM, this.walletImage, this._settingsStore);
47 + WalletNameForm(this._walletNewVM, this.walletImage, this._seedTypeViewModel);
48
49 final WalletNewVM _walletNewVM;
50 final Image walletImage;
51 - final SettingsStore _settingsStore;
51 + final SeedTypeViewModel _seedTypeViewModel;
52
53 @override
54 _WalletNameFormState createState() => _WalletNameFormState(_walletNewVM);
@@ -194,7 +194,7 @@ class _WalletNameFormState extends State<WalletNameForm> {
194 builder: (BuildContext build) => Padding(
195 padding: EdgeInsets.only(top: 24),
196 child: SelectButton(
197 - text: widget._settingsStore.moneroSeedType.title,
197 + text: widget._seedTypeViewModel.moneroSeedType.title,
198 onTap: () async {
199 await showPopUp<void>(
200 context: context,
@@ -217,7 +217,7 @@ class _WalletNameFormState extends State<WalletNameForm> {
217 key: _languageSelectorKey,
218 initialSelected: defaultSeedLanguage,
219 seedType: _walletNewVM.hasSeedType
220 - ? widget._settingsStore.moneroSeedType
220 + ? widget._seedTypeViewModel.moneroSeedType
221 : SeedType.legacy,
222 ),
223 ),
@@ -277,10 +277,10 @@ class _WalletNameFormState extends State<WalletNameForm> {
277 }
278 }
279
280 - bool get isPolyseed => widget._settingsStore.moneroSeedType == SeedType.polyseed;
280 + bool get isPolyseed => widget._seedTypeViewModel.moneroSeedType == SeedType.polyseed;
281
282 void _setSeedType(SeedType item) {
283 - widget._settingsStore.moneroSeedType = item;
283 + widget._seedTypeViewModel.setMoneroSeedType(item);
284 _languageSelectorKey.currentState?.selected = defaultSeedLanguage; // Reset Seed language
285 }
286 }
lib/src/screens/restore/wallet_restore_from_seed_form.dart
+21 -3
@@ -9,8 +9,10 @@ import 'package:cake_wallet/src/widgets/seed_language_picker.dart';
9 import 'package:cake_wallet/src/widgets/seed_widget.dart';
10 import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
11 import 'package:cake_wallet/utils/show_pop_up.dart';
12 +import 'package:cake_wallet/view_model/seed_type_view_model.dart';
13 import 'package:cw_core/wallet_type.dart';
14 import 'package:flutter/material.dart';
15 +import 'package:mobx/mobx.dart';
16 import 'package:polyseed/polyseed.dart';
17
18 class WalletRestoreFromSeedForm extends StatefulWidget {
@@ -19,6 +21,7 @@ class WalletRestoreFromSeedForm extends StatefulWidget {
21 required this.displayLanguageSelector,
22 required this.displayBlockHeightSelector,
23 required this.type,
24 + required this.seedTypeViewModel,
25 this.blockHeightFocusNode,
26 this.onHeightOrDateEntered,
27 this.onSeedChange,
@@ -28,6 +31,7 @@ class WalletRestoreFromSeedForm extends StatefulWidget {
31 final WalletType type;
32 final bool displayLanguageSelector;
33 final bool displayBlockHeightSelector;
34 + final SeedTypeViewModel seedTypeViewModel;
35 final FocusNode? blockHeightFocusNode;
36 final Function(bool)? onHeightOrDateEntered;
37 final void Function(String)? onSeedChange;
@@ -52,16 +56,28 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
56 final TextEditingController nameTextEditingController;
57 final TextEditingController seedTypeController;
58 final GlobalKey<FormState> formKey;
59 + late ReactionDisposer moneroSeedTypeReaction;
60 String language;
56 - bool isPolyseed = false;
61
62 @override
63 void initState() {
64 + _setSeedType(widget.seedTypeViewModel.moneroSeedType);
65 _setLanguageLabel(language);
61 - _setSeedType(SeedType.defaultSeedType);
66 + moneroSeedTypeReaction =
67 + reaction((_) => widget.seedTypeViewModel.moneroSeedType, (SeedType item) {
68 + _setSeedType(item);
69 + _changeLanguage('English');
70 + });
71 +
72 super.initState();
73 }
74
75 + @override
76 + void dispose() {
77 + super.dispose();
78 + moneroSeedTypeReaction();
79 + }
80 +
81 void onSeedChange(String seed) {
82 if (widget.type == WalletType.monero && Polyseed.isValidSeed(seed)) {
83 final lang = PolyseedLang.getByPhrase(seed);
@@ -181,6 +197,8 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
197 ]));
198 }
199
200 + bool get isPolyseed => widget.seedTypeViewModel.moneroSeedType == SeedType.polyseed;
201 +
202 Widget get expandIcon => Container(
203 padding: EdgeInsets.all(18),
204 width: 24,
@@ -208,10 +226,10 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
226 void _changeSeedType(SeedType item) {
227 _setSeedType(item);
228 _changeLanguage('English');
229 + widget.seedTypeViewModel.setMoneroSeedType(item);
230 }
231
232 void _setSeedType(SeedType item) {
214 - setState(() => isPolyseed = item == SeedType.polyseed);
233 seedTypeController.text = item.toString();
234 }
235 }
lib/src/screens/restore/wallet_restore_page.dart
+4 -1
@@ -15,6 +15,7 @@ import 'package:cake_wallet/themes/extensions/wallet_list_theme.dart';
15 import 'package:cake_wallet/utils/responsive_layout_util.dart';
16 import 'package:cake_wallet/utils/show_pop_up.dart';
17 import 'package:cake_wallet/view_model/restore/restore_mode.dart';
18 +import 'package:cake_wallet/view_model/seed_type_view_model.dart';
19 import 'package:cake_wallet/view_model/wallet_restore_view_model.dart';
20 import 'package:cw_core/nano_account_info_response.dart';
21 import 'package:cw_core/wallet_info.dart';
@@ -27,7 +28,7 @@ import 'package:polyseed/polyseed.dart';
28 import 'package:smooth_page_indicator/smooth_page_indicator.dart';
29
30 class WalletRestorePage extends BasePage {
30 - WalletRestorePage(this.walletRestoreViewModel)
31 + WalletRestorePage(this.walletRestoreViewModel, this.seedTypeViewModel)
32 : walletRestoreFromSeedFormKey = GlobalKey<WalletRestoreFromSeedFormState>(),
33 walletRestoreFromKeysFormKey = GlobalKey<WalletRestoreFromKeysFromState>(),
34 _pages = [],
@@ -37,6 +38,7 @@ class WalletRestorePage extends BasePage {
38 switch (mode) {
39 case WalletRestoreMode.seed:
40 _pages.add(WalletRestoreFromSeedForm(
41 + seedTypeViewModel: seedTypeViewModel,
42 displayBlockHeightSelector:
43 walletRestoreViewModel.hasBlockchainHeightLanguageSelector,
44 displayLanguageSelector: walletRestoreViewModel.hasSeedLanguageSelector,
@@ -91,6 +93,7 @@ class WalletRestorePage extends BasePage {
93 ));
94
95 final WalletRestoreViewModel walletRestoreViewModel;
96 + final SeedTypeViewModel seedTypeViewModel;
97 final PageController _controller;
98 final List<Widget> _pages;
99 final GlobalKey<WalletRestoreFromSeedFormState> walletRestoreFromSeedFormKey;
lib/src/screens/seed/pre_seed_page.dart
+11 -5
@@ -1,6 +1,8 @@
1 +import 'package:cake_wallet/entities/seed_type.dart';
2 import 'package:cake_wallet/utils/responsive_layout_util.dart';
3 import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
4 import 'package:cake_wallet/view_model/advanced_privacy_settings_view_model.dart';
5 +import 'package:cake_wallet/view_model/seed_type_view_model.dart';
6 import 'package:cw_core/wallet_type.dart';
7 import 'package:cake_wallet/src/screens/base_page.dart';
8 import 'package:cake_wallet/src/widgets/primary_button.dart';
@@ -10,19 +12,21 @@ import 'package:cake_wallet/themes/theme_base.dart';
12 import 'package:flutter/material.dart';
13
14 class PreSeedPage extends BasePage {
13 - PreSeedPage(this.type, this.advancedPrivacySettingsViewModel)
15 + PreSeedPage(this.type, this.advancedPrivacySettingsViewModel, this.seedTypeViewModel)
16 : imageLight = Image.asset('assets/images/pre_seed_light.png'),
17 imageDark = Image.asset('assets/images/pre_seed_dark.png'),
16 - seedPhraseLength =
17 - advancedPrivacySettingsViewModel.seedPhraseLength.value {
18 - wordsCount = _wordsCount(type, seedPhraseLength);
18 + seedPhraseLength = advancedPrivacySettingsViewModel.seedPhraseLength.value,
19 + moneroSeedType = seedTypeViewModel.moneroSeedType {
20 + wordsCount = _wordsCount(type, seedPhraseLength, moneroSeedType);
21 }
22
23 final Image imageDark;
24 final Image imageLight;
25 final WalletType type;
26 final AdvancedPrivacySettingsViewModel advancedPrivacySettingsViewModel;
27 + final SeedTypeViewModel seedTypeViewModel;
28 final int seedPhraseLength;
29 + final SeedType moneroSeedType;
30 late final int wordsCount;
31
32 @override
@@ -76,9 +80,11 @@ class PreSeedPage extends BasePage {
80 ));
81 }
82
79 - static int _wordsCount(WalletType type, int seedPhraseLength) {
83 + static int _wordsCount(WalletType type, int seedPhraseLength, SeedType moneroSeedType) {
84 switch (type) {
85 case WalletType.monero:
86 + if (moneroSeedType == SeedType.polyseed)
87 + return 16;
88 return 25;
89 case WalletType.ethereum:
90 case WalletType.bitcoinCash:
lib/store/settings_store.dart
+1 -1
@@ -877,7 +877,7 @@ abstract class SettingsStoreBase with Store {
877 }
878
879 final savedSyncMode = SyncMode.all.firstWhere((element) {
880 - return element.type.index == (sharedPreferences.getInt(PreferencesKey.syncModeKey) ?? 1);
880 + return element.type.index == (sharedPreferences.getInt(PreferencesKey.syncModeKey) ?? 0);
881 });
882 final savedSyncAll = sharedPreferences.getBool(PreferencesKey.syncAllKey) ?? true;
883
lib/view_model/advanced_privacy_settings_view_model.dart
-7
@@ -1,7 +1,6 @@
1 import 'package:cake_wallet/entities/exchange_api_mode.dart';
2 import 'package:cake_wallet/entities/fiat_api_mode.dart';
3 import 'package:cake_wallet/entities/seed_phrase_length.dart';
4 -import 'package:cake_wallet/entities/seed_type.dart';
4 import 'package:cake_wallet/store/settings_store.dart';
5 import 'package:cw_core/wallet_type.dart';
6 import 'package:mobx/mobx.dart';
@@ -20,9 +19,6 @@ abstract class AdvancedPrivacySettingsViewModelBase with Store {
19 @computed
20 FiatApiMode get fiatApiMode => _settingsStore.fiatApiMode;
21
23 - @computed
24 - SeedType get seedType => _settingsStore.moneroSeedType;
25 -
22 @observable
23 bool _addCustomNode = false;
24
@@ -44,9 +40,6 @@ abstract class AdvancedPrivacySettingsViewModelBase with Store {
40 @action
41 void setFiatApiMode(FiatApiMode fiatApiMode) => _settingsStore.fiatApiMode = fiatApiMode;
42
47 - @action
48 - void setSeedType(SeedType seedType) => _settingsStore.moneroSeedType = seedType;
49 -
43 @action
44 void setExchangeApiMode(ExchangeApiMode value) => _settingsStore.exchangeStatus = value;
45
lib/view_model/seed_type_view_model.dart new
+19
@@ -0,0 +1,19 @@
1 +import 'package:cake_wallet/entities/seed_type.dart';
2 +import 'package:cake_wallet/store/app_store.dart';
3 +import 'package:mobx/mobx.dart';
4 +
5 +part 'seed_type_view_model.g.dart';
6 +
7 +class SeedTypeViewModel = SeedTypeViewModelBase with _$SeedTypeViewModel;
8 +
9 +abstract class SeedTypeViewModelBase with Store {
10 + SeedTypeViewModelBase(this._appStore);
11 +
12 + @computed
13 + SeedType get moneroSeedType => _appStore.settingsStore.moneroSeedType;
14 +
15 + @action
16 + void setMoneroSeedType(SeedType seedType) => _appStore.settingsStore.moneroSeedType = seedType;
17 +
18 + final AppStore _appStore;
19 +}
lib/view_model/wallet_keys_view_model.dart
+29
@@ -10,6 +10,7 @@ import 'package:cake_wallet/src/screens/transaction_details/standart_list_item.d
10 import 'package:cake_wallet/monero/monero.dart';
11 import 'package:cake_wallet/haven/haven.dart';
12 import 'package:cw_monero/api/wallet.dart' as monero_wallet;
13 +import 'package:polyseed/polyseed.dart';
14
15 part 'wallet_keys_view_model.g.dart';
16
@@ -74,6 +75,15 @@ abstract class WalletKeysViewModelBase with Store {
75 StandartListItem(title: S.current.view_key_private, value: keys['privateViewKey']!),
76 StandartListItem(title: S.current.wallet_seed, value: _appStore.wallet!.seed!),
77 ]);
78 +
79 + if (_appStore.wallet?.seed != null && Polyseed.isValidSeed(_appStore.wallet!.seed!)) {
80 + final lang = PolyseedLang.getByPhrase(_appStore.wallet!.seed!);
81 + final legacyLang = _getLegacySeedLang(lang);
82 + final legacySeed =
83 + Polyseed.decode(_appStore.wallet!.seed!, lang, PolyseedCoin.POLYSEED_MONERO)
84 + .toLegacySeed(legacyLang);
85 + items.add(StandartListItem(title: S.current.wallet_seed_legacy, value: legacySeed));
86 + }
87 }
88
89 if (_appStore.wallet!.type == WalletType.haven) {
@@ -207,4 +217,23 @@ abstract class WalletKeysViewModelBase with Store {
217 }
218
219 String getRoundedRestoreHeight(int height) => ((height / 1000).floor() * 1000).toString();
220 +
221 + LegacySeedLang _getLegacySeedLang(PolyseedLang lang) {
222 + switch (lang.nameEnglish) {
223 + case "Spanish":
224 + return LegacySeedLang.getByEnglishName("Spanish");
225 + case "French":
226 + return LegacySeedLang.getByEnglishName("French");
227 + case "Italian":
228 + return LegacySeedLang.getByEnglishName("Italian");
229 + case "Japanese":
230 + return LegacySeedLang.getByEnglishName("Japanese");
231 + case "Portuguese":
232 + return LegacySeedLang.getByEnglishName("Portuguese");
233 + case "Chinese (Simplified)":
234 + return LegacySeedLang.getByEnglishName("Chinese (simplified)");
235 + default:
236 + return LegacySeedLang.getByEnglishName("English");
237 + }
238 + }
239 }
pubspec_base.yaml
+1 -3
@@ -104,9 +104,7 @@ dependencies:
104 # ref: main
105 socks5_proxy: ^1.0.4
106 flutter_svg: ^2.0.9
107 - polyseed:
108 - git:
109 - url: https://github.com/cake-tech/polyseed_dart.git
107 + polyseed: ^0.0.2
108
109 dev_dependencies:
110 flutter_test:
res/values/strings_ar.arb
+2 -1
@@ -747,5 +747,6 @@
747 "seed_language_korean": "الكورية",
748 "seed_language_chinese_traditional": "تقاليد صينية)",
749 "dfx_option_description": "ﺎﺑﻭﺭﻭﺃ ﻲﻓ ﺕﺎﻛﺮﺸﻟﺍﻭ ﺔﺋﺰﺠﺘﻟﺍ ءﻼﻤﻌﻟ .ﻲﻓﺎﺿﺇ KYC ﻥﻭﺪﺑ ﻭﺭﻮﻳ 990 ﻰﻟﺇ ﻞﺼﻳ ﺎﻣ .ﻱﺮﺴﻳﻮﺴﻟﺍ",
750 - "polygonscan_history": "ﻥﺎﻜﺴﻧﻮﺠﻴﻟﻮﺑ ﺦﻳﺭﺎﺗ"
750 + "polygonscan_history": "ﻥﺎﻜﺴﻧﻮﺠﻴﻟﻮﺑ ﺦﻳﺭﺎﺗ",
751 + "wallet_seed_legacy": "بذرة محفظة قديمة"
752 }
res/values/strings_bg.arb
+2 -1
@@ -743,5 +743,6 @@
743 "seed_language_korean": "Корейски",
744 "seed_language_chinese_traditional": "Традиционен китайски)",
745 "dfx_option_description": "Купете крипто с EUR и CHF. До 990 € без допълнителен KYC. За клиенти на дребно и корпоративни клиенти в Европа",
746 - "polygonscan_history": "История на PolygonScan"
746 + "polygonscan_history": "История на PolygonScan",
747 + "wallet_seed_legacy": "Наследено портфейл семе"
748 }
res/values/strings_cs.arb
+2 -1
@@ -743,5 +743,6 @@
743 "seed_language_korean": "korejština",
744 "seed_language_chinese_traditional": "Číňan (tradiční)",
745 "dfx_option_description": "Nakupujte kryptoměny za EUR a CHF. Až 990 € bez dalších KYC. Pro maloobchodní a firemní zákazníky v Evropě",
746 - "polygonscan_history": "Historie PolygonScan"
746 + "polygonscan_history": "Historie PolygonScan",
747 + "wallet_seed_legacy": "Starší semeno peněženky"
748 }
res/values/strings_de.arb
+2 -1
@@ -751,5 +751,6 @@
751 "seed_language_korean": "Koreanisch",
752 "seed_language_chinese_traditional": "Chinesisch (Traditionell)",
753 "dfx_option_description": "Krypto mit EUR und CHF kaufen. Bis zu 990€ ohne zusätzliches KYC. Für Privat- und Firmenkunden in Europa",
754 - "polygonscan_history": "PolygonScan-Verlauf"
754 + "polygonscan_history": "PolygonScan-Verlauf",
755 + "wallet_seed_legacy": "Legacy Wallet Seed"
756 }
res/values/strings_en.arb
+2 -1
@@ -752,5 +752,6 @@
752 "seed_language_korean": "Korean",
753 "seed_language_chinese_traditional": "Chinese (Traditional)",
754 "dfx_option_description": "Buy crypto with EUR & CHF. Up to 990€ without additional KYC. For retail and corporate customers in Europe",
755 - "polygonscan_history": "PolygonScan history"
755 + "polygonscan_history": "PolygonScan history",
756 + "wallet_seed_legacy": "Legacy wallet seed"
757 }
res/values/strings_es.arb
+3 -2
@@ -752,5 +752,6 @@
752 "seed_language_chinese_traditional": "Chino tradicional)",
753 "dfx_option_description": "Compre criptomonedas con EUR y CHF. Hasta 990€ sin KYC adicional. Para clientes minoristas y corporativos en Europa",
754 "seed_language_chinese_traditional": "Chino (tradicional)",
755 - "polygonscan_history": "Historial de PolygonScan"
756 -}
755 + "polygonscan_history": "Historial de PolygonScan",
756 + "wallet_seed_legacy": "Semilla de billetera heredada"
757 +}
\ No newline at end of file
res/values/strings_fr.arb
+2 -1
@@ -751,5 +751,6 @@
751 "seed_language_korean": "coréen",
752 "seed_language_chinese_traditional": "Chinois (Traditionnel)",
753 "dfx_option_description": "Achetez des crypto-monnaies avec EUR et CHF. Jusqu'à 990€ sans KYC supplémentaire. Pour les clients particuliers et entreprises en Europe",
754 - "polygonscan_history": "Historique de PolygonScan"
754 + "polygonscan_history": "Historique de PolygonScan",
755 + "wallet_seed_legacy": "Graine de portefeuille hérité"
756 }
res/values/strings_ha.arb
+2 -1
@@ -729,5 +729,6 @@
729 "seed_language_korean": "Yaren Koriya",
730 "seed_language_chinese_traditional": "Sinanci (na gargajiya)",
731 "dfx_option_description": "Sayi crypto tare da EUR & CHF. Har zuwa € 990 ba tare da ƙarin KYC ba. Don 'yan kasuwa da abokan ciniki na kamfanoni a Turai",
732 - "polygonscan_history": "PolygonScan tarihin kowane zamani"
732 + "polygonscan_history": "PolygonScan tarihin kowane zamani",
733 + "wallet_seed_legacy": "Tallarin walat walat"
734 }
res/values/strings_hi.arb
+2 -1
@@ -751,5 +751,6 @@
751 "seed_language_korean": "कोरियाई",
752 "seed_language_chinese_traditional": "चीनी पारंपरिक)",
753 "dfx_option_description": "EUR और CHF के साथ क्रिप्टो खरीदें। अतिरिक्त केवाईसी के बिना 990€ तक। यूरोप में खुदरा और कॉर्पोरेट ग्राहकों के लिए",
754 - "polygonscan_history": "पॉलीगॉनस्कैन इतिहास"
754 + "polygonscan_history": "पॉलीगॉनस्कैन इतिहास",
755 + "wallet_seed_legacy": "विरासत बटुए बीज"
756 }
res/values/strings_hr.arb
+3 -2
@@ -750,5 +750,6 @@
750 "seed_language_chinese_traditional": "Kinesko tradicionalno)",
751 "dfx_option_description": "Kupujte kripto s EUR i CHF. Do 990 € bez dodatnog KYC-a. Za maloprodajne i poslovne korisnike u Europi",
752 "seed_language_chinese_traditional": "Kinesko (tradicionalno)",
753 - "polygonscan_history": "Povijest PolygonScan"
754 -}
753 + "polygonscan_history": "Povijest PolygonScan",
754 + "wallet_seed_legacy": "Sjeme naslijeđenog novčanika"
755 +}
\ No newline at end of file
res/values/strings_id.arb
+3 -2
@@ -740,5 +740,6 @@
740 "seed_language_chinese_traditional": "Cina tradisional)",
741 "dfx_option_description": "Beli kripto dengan EUR & CHF. Hingga 990€ tanpa KYC tambahan. Untuk pelanggan ritel dan korporat di Eropa",
742 "seed_language_chinese_traditional": "Cina (tradisional)",
743 - "polygonscan_history": "Sejarah PolygonScan"
744 -}
743 + "polygonscan_history": "Sejarah PolygonScan",
744 + "wallet_seed_legacy": "Biji dompet warisan"
745 +}
\ No newline at end of file
res/values/strings_it.arb
+2 -1
@@ -751,5 +751,6 @@
751 "seed_language_korean": "coreano",
752 "seed_language_chinese_traditional": "Cinese tradizionale)",
753 "dfx_option_description": "Acquista criptovalute con EUR e CHF. Fino a 990€ senza KYC aggiuntivi. Per clienti al dettaglio e aziendali in Europa",
754 - "polygonscan_history": "Cronologia PolygonScan"
754 + "polygonscan_history": "Cronologia PolygonScan",
755 + "wallet_seed_legacy": "Seme di portafoglio legacy"
756 }
res/values/strings_ja.arb
+2 -1
@@ -751,5 +751,6 @@
751 "seed_language_korean": "韓国語",
752 "seed_language_chinese_traditional": "中国の伝統的な)",
753 "dfx_option_description": "EUR と CHF で暗号通貨を購入します。追加のKYCなしで最大990ユーロ。ヨーロッパの小売および法人顧客向け",
754 - "polygonscan_history": "ポリゴンスキャン履歴"
754 + "polygonscan_history": "ポリゴンスキャン履歴",
755 + "wallet_seed_legacy": "レガシーウォレットシード"
756 }
res/values/strings_ko.arb
+2 -1
@@ -749,5 +749,6 @@
749 "seed_language_korean": "한국인",
750 "seed_language_chinese_traditional": "중국 전통)",
751 "dfx_option_description": "EUR 및 CHF로 암호화폐를 구매하세요. 추가 KYC 없이 최대 990€. 유럽의 소매 및 기업 고객용",
752 - "polygonscan_history": "다각형 스캔 기록"
752 + "polygonscan_history": "다각형 스캔 기록",
753 + "wallet_seed_legacy": "레거시 지갑 시드"
754 }
res/values/strings_my.arb
+2 -1
@@ -749,5 +749,6 @@
749 "seed_language_korean": "ကိုးရီးယား",
750 "seed_language_chinese_traditional": "တရုတ်ရိုးရာ)",
751 "dfx_option_description": "EUR & CHF ဖြင့် crypto ကိုဝယ်ပါ။ အပို KYC မပါဘဲ 990€ အထိ။ ဥရောပရှိ လက်လီရောင်းချသူများနှင့် ကော်ပိုရိတ်ဖောက်သည်များအတွက်",
752 - "polygonscan_history": "PolygonScan မှတ်တမ်း"
752 + "polygonscan_history": "PolygonScan မှတ်တမ်း",
753 + "wallet_seed_legacy": "အမွေအနှစ်ပိုက်ဆံအိတ်မျိုးစေ့"
754 }
res/values/strings_nl.arb
+3 -2
@@ -752,5 +752,6 @@
752 "seed_language_chinese_traditional": "Chinese traditionele)",
753 "dfx_option_description": "Koop crypto met EUR & CHF. Tot 990€ zonder extra KYC. Voor particuliere en zakelijke klanten in Europa",
754 "seed_language_chinese_traditional": "Chinese (traditionele)",
755 - "polygonscan_history": "PolygonScan-geschiedenis"
756 -}
755 + "polygonscan_history": "PolygonScan-geschiedenis",
756 + "wallet_seed_legacy": "Legacy portemonnee zaad"
757 +}
\ No newline at end of file
res/values/strings_pl.arb
+2 -1
@@ -751,5 +751,6 @@
751 "seed_language_korean": "koreański",
752 "seed_language_chinese_traditional": "Chiński tradycyjny)",
753 "dfx_option_description": "Kupuj kryptowaluty za EUR i CHF. Do 990 € bez dodatkowego KYC. Dla klientów detalicznych i korporacyjnych w Europie",
754 - "polygonscan_history": "Historia PolygonScan"
754 + "polygonscan_history": "Historia PolygonScan",
755 + "wallet_seed_legacy": "Dziedziczne ziarno portfela"
756 }
res/values/strings_pt.arb
+2 -1
@@ -750,5 +750,6 @@
750 "seed_language_korean": "coreano",
751 "seed_language_chinese_traditional": "Chinês tradicional)",
752 "dfx_option_description": "Compre criptografia com EUR e CHF. Até 990€ sem KYC adicional. Para clientes de varejo e corporativos na Europa",
753 - "polygonscan_history": "História do PolygonScan"
753 + "polygonscan_history": "História do PolygonScan",
754 + "wallet_seed_legacy": "Semente de carteira herdada"
755 }
res/values/strings_ru.arb
+2 -1
@@ -751,5 +751,6 @@
751 "seed_language_korean": "Корейский",
752 "seed_language_chinese_traditional": "Китайский традиционный)",
753 "dfx_option_description": "Покупайте криптовалюту за EUR и CHF. До 990€ без дополнительного KYC. Для розничных и корпоративных клиентов в Европе",
754 - "polygonscan_history": "История PolygonScan"
754 + "polygonscan_history": "История PolygonScan",
755 + "wallet_seed_legacy": "Наследие семя кошелька"
756 }
res/values/strings_th.arb
+2 -1
@@ -749,5 +749,6 @@
749 "seed_language_korean": "เกาหลี",
750 "seed_language_chinese_traditional": "จีน (ดั้งเดิม)",
751 "dfx_option_description": "ซื้อ crypto ด้วย EUR และ CHF สูงถึง 990€ โดยไม่มี KYC เพิ่มเติม สำหรับลูกค้ารายย่อยและลูกค้าองค์กรในยุโรป",
752 - "polygonscan_history": "ประวัติ PolygonScan"
752 + "polygonscan_history": "ประวัติ PolygonScan",
753 + "wallet_seed_legacy": "เมล็ดกระเป๋าเงินมรดก"
754 }
res/values/strings_tl.arb
+2 -1
@@ -745,5 +745,6 @@
745 "seed_language_korean": "Korean",
746 "seed_language_chinese_traditional": "Intsik (tradisyonal)",
747 "dfx_option_description": "Bumili ng crypto gamit ang EUR at CHF. Hanggang 990€ nang walang karagdagang KYC. Para sa retail at corporate na mga customer sa Europe",
748 - "polygonscan_history": "Kasaysayan ng PolygonScan"
748 + "polygonscan_history": "Kasaysayan ng PolygonScan",
749 + "wallet_seed_legacy": "Legacy wallet seed"
750 }
res/values/strings_tr.arb
+2 -1
@@ -749,5 +749,6 @@
749 "seed_language_korean": "Koreli",
750 "seed_language_chinese_traditional": "Çin geleneği)",
751 "dfx_option_description": "EUR ve CHF ile kripto satın alın. Ek KYC olmadan 990 €'ya kadar. Avrupa'daki perakende ve kurumsal müşteriler için",
752 - "polygonscan_history": "PolygonScan geçmişi"
752 + "polygonscan_history": "PolygonScan geçmişi",
753 + "wallet_seed_legacy": "Eski cüzdan tohumu"
754 }
res/values/strings_uk.arb
+3 -2
@@ -751,5 +751,6 @@
751 "seed_language_korean": "Корейський",
752 "dfx_option_description": "Купуйте криптовалюту за EUR і CHF. До 990 євро без додаткового KYC. Для роздрібних і корпоративних клієнтів у Європі",
753 "seed_language_chinese_traditional": "Китайський (традиційний)",
754 - "polygonscan_history": "Історія PolygonScan"
755 -}
754 + "polygonscan_history": "Історія PolygonScan",
755 + "wallet_seed_legacy": "Спадець насіння гаманця"
756 +}
\ No newline at end of file
res/values/strings_ur.arb
+2 -1
@@ -743,5 +743,6 @@
743 "seed_language_korean": "کورین",
744 "seed_language_chinese_traditional": "چینی (روایتی)",
745 "dfx_option_description": "EUR ﺭﻭﺍ CHF ﯽﻓﺎﺿﺍ ۔ﮟﯾﺪﯾﺮﺧ ﻮﭩﭘﺮﮐ ﮫﺗﺎﺳ ﮯﮐ KYC ﮯﯿﻟ ﮯﮐ ﻦﯿﻓﺭﺎﺻ ﭧﯾﺭﻮﭘﺭﺎﮐ ﺭﻭﺍ ﮦﺩﺭﻮﺧ ﮟ",
746 - "polygonscan_history": "ﺦﯾﺭﺎﺗ ﯽﮐ ﻦﯿﮑﺳﺍ ﻥﻮﮔ ﯽﻟﻮﭘ"
746 + "polygonscan_history": "ﺦﯾﺭﺎﺗ ﯽﮐ ﻦﯿﮑﺳﺍ ﻥﻮﮔ ﯽﻟﻮﭘ",
747 + "wallet_seed_legacy": "میراثی پرس کا بیج"
748 }
res/values/strings_yo.arb
+2 -1
@@ -745,5 +745,6 @@
745 "seed_language_korean": "Ara ẹni",
746 "seed_language_chinese_traditional": "Kannada (ibile)",
747 "dfx_option_description": "Ra crypto pẹlu EUR & CHF. Titi di 990 € laisi afikun KYC. Fun soobu ati awọn onibara ile-iṣẹ ni Yuroopu",
748 - "polygonscan_history": "PolygonScan itan"
748 + "polygonscan_history": "PolygonScan itan",
749 + "wallet_seed_legacy": "Irugbin akole"
750 }
res/values/strings_zh.arb
+2 -1
@@ -750,5 +750,6 @@
750 "seed_language_korean": "韩国人",
751 "seed_language_chinese_traditional": "中国传统的)",
752 "dfx_option_description": "用欧元和瑞士法郎购买加密货币。高达 990 欧元,无需额外 KYC。对于欧洲的零售和企业客户",
753 - "polygonscan_history": "多边形扫描历史"
753 + "polygonscan_history": "多边形扫描历史",
754 + "wallet_seed_legacy": "旧的钱包种子"
755 }