Cw 488 seed offset (#1631)

* CW-488 minor code cleanup

* Add Derivation Path selector for BTC and LTC

* CW-488 Initial Passphrase Impl

* CW-488 Final Passphrase Impl

* Quick Fix of language Service

* CW-488 Implement PR Suggestions

* CW-488 Implement PR Suggestions

* CW-488 Implement Passphrase for Bitcoin Cash

* CW-488 Implement Passphrase for Bitcoin Cash

* CW-488 Implement Passphrase for Bitcoin Cash

* remove monero and wownero support for passphrase until merged [skip ci]

* CW-488 Apply requested change

* CW-488 Add Passphrase to QR

* CW-488 Fix Seed generation

* CW-488 Implement Electrum Passphrases

* CW-488 Add Seed Length Selector to BIP39 Seeds

* CW-488 Minor fix [skip ci]

---------

Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>
This commit is contained in:
Konstantin Ullrich
2024-08-26 20:06:54 +03:00
committed by GitHub
co-authored by Omar Hatem
parent 40f85d215b
commit ce21098e98
67 changed files with 741 additions and 438 deletions
@@ -1,23 +1,7 @@
import 'package:cake_wallet/core/wallet_name_validator.dart';
import 'package:cake_wallet/entities/generate_name.dart';
import 'package:cake_wallet/entities/seed_type.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/widgets/address_text_field.dart';
import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
import 'package:cake_wallet/src/widgets/blockchain_height_widget.dart';
import 'package:cake_wallet/src/widgets/picker.dart';
import 'package:cake_wallet/src/widgets/seed_language_picker.dart';
import 'package:cake_wallet/src/widgets/seed_widget.dart';
import 'package:cake_wallet/themes/extensions/address_theme.dart';
import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
import 'package:cake_wallet/utils/show_bar.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/view_model/seed_type_view_model.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:mobx/mobx.dart';
import 'package:polyseed/polyseed.dart';
class VerifyForm extends StatefulWidget {
VerifyForm({
@@ -3,52 +3,61 @@ import 'package:cake_wallet/entities/exchange_api_mode.dart';
import 'package:cake_wallet/entities/fiat_api_mode.dart';
import 'package:cake_wallet/entities/seed_phrase_length.dart';
import 'package:cake_wallet/entities/seed_type.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/screens/nodes/widgets/node_form.dart';
import 'package:cake_wallet/src/screens/settings/widgets/settings_choices_cell.dart';
import 'package:cake_wallet/src/screens/settings/widgets/settings_picker_cell.dart';
import 'package:cake_wallet/src/screens/settings/widgets/settings_switcher_cell.dart';
import 'package:cake_wallet/themes/extensions/new_wallet_theme.dart';
import 'package:cake_wallet/view_model/node_list/node_create_or_edit_view_model.dart';
import 'package:cake_wallet/view_model/advanced_privacy_settings_view_model.dart';
import 'package:cake_wallet/view_model/seed_type_view_model.dart';
import 'package:cake_wallet/view_model/settings/choices_list_item.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
import 'package:cake_wallet/src/widgets/primary_button.dart';
import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
import 'package:cake_wallet/themes/extensions/new_wallet_theme.dart';
import 'package:cake_wallet/view_model/advanced_privacy_settings_view_model.dart';
import 'package:cake_wallet/view_model/node_list/node_create_or_edit_view_model.dart';
import 'package:cake_wallet/view_model/seed_settings_view_model.dart';
import 'package:cake_wallet/view_model/settings/choices_list_item.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
class AdvancedPrivacySettingsPage extends BasePage {
AdvancedPrivacySettingsPage(this.useTestnet, this.toggleUseTestnet,
this.advancedPrivacySettingsViewModel, this.nodeViewModel, this.seedTypeViewModel);
AdvancedPrivacySettingsPage({
required this.isFromRestore,
required this.useTestnet,
required this.toggleUseTestnet,
required this.advancedPrivacySettingsViewModel,
required this.nodeViewModel,
required this.seedSettingsViewModel,
});
final AdvancedPrivacySettingsViewModel advancedPrivacySettingsViewModel;
final NodeCreateOrEditViewModel nodeViewModel;
final SeedTypeViewModel seedTypeViewModel;
final SeedSettingsViewModel seedSettingsViewModel;
@override
String get title => S.current.privacy_settings;
final bool isFromRestore;
final bool useTestnet;
final Function(bool? val) toggleUseTestnet;
@override
Widget body(BuildContext context) => AdvancedPrivacySettingsBody(useTestnet, toggleUseTestnet,
advancedPrivacySettingsViewModel, nodeViewModel, seedTypeViewModel);
Widget body(BuildContext context) => _AdvancedPrivacySettingsBody(isFromRestore, useTestnet,
toggleUseTestnet, advancedPrivacySettingsViewModel, nodeViewModel, seedSettingsViewModel);
}
class AdvancedPrivacySettingsBody extends StatefulWidget {
const AdvancedPrivacySettingsBody(this.useTestnet, this.toggleUseTestnet,
class _AdvancedPrivacySettingsBody extends StatefulWidget {
const _AdvancedPrivacySettingsBody(this.isFromRestore, this.useTestnet, this.toggleUseTestnet,
this.privacySettingsViewModel, this.nodeViewModel, this.seedTypeViewModel,
{Key? key})
: super(key: key);
final AdvancedPrivacySettingsViewModel privacySettingsViewModel;
final NodeCreateOrEditViewModel nodeViewModel;
final SeedTypeViewModel seedTypeViewModel;
final SeedSettingsViewModel seedTypeViewModel;
final bool isFromRestore;
final bool useTestnet;
final Function(bool? val) toggleUseTestnet;
@@ -56,15 +65,23 @@ class AdvancedPrivacySettingsBody extends StatefulWidget {
_AdvancedPrivacySettingsBodyState createState() => _AdvancedPrivacySettingsBodyState();
}
class _AdvancedPrivacySettingsBodyState extends State<AdvancedPrivacySettingsBody> {
_AdvancedPrivacySettingsBodyState();
class _AdvancedPrivacySettingsBodyState extends State<_AdvancedPrivacySettingsBody> {
final TextEditingController passphraseController = TextEditingController();
final _formKey = GlobalKey<FormState>();
bool? testnetValue;
@override
void initState() {
passphraseController.text = widget.seedTypeViewModel.passphrase ?? '';
passphraseController
.addListener(() => widget.seedTypeViewModel.setPassphrase(passphraseController.text));
super.initState();
}
@override
Widget build(BuildContext context) {
if (testnetValue == null && widget.useTestnet != null) {
if (testnetValue == null && widget.useTestnet) {
testnetValue = widget.useTestnet;
}
@@ -97,6 +114,52 @@ class _AdvancedPrivacySettingsBodyState extends State<AdvancedPrivacySettingsBod
),
);
}),
if (widget.privacySettingsViewModel.hasSeedTypeOption)
Observer(builder: (_) {
return SettingsChoicesCell(
ChoicesListItem<MoneroSeedType>(
title: S.current.seedtype,
items: MoneroSeedType.all,
selectedItem: widget.seedTypeViewModel.moneroSeedType,
onItemSelected: widget.seedTypeViewModel.setMoneroSeedType,
),
);
}),
if ([WalletType.bitcoin, WalletType.litecoin]
.contains(widget.privacySettingsViewModel.type))
Observer(builder: (_) {
return SettingsChoicesCell(
ChoicesListItem<BitcoinSeedType>(
title: S.current.seedtype,
items: BitcoinSeedType.all,
selectedItem: widget.seedTypeViewModel.bitcoinSeedType,
onItemSelected: widget.seedTypeViewModel.setBitcoinSeedType,
),
);
}),
if (!widget.isFromRestore) ...[
Observer(builder: (_) {
if (widget.privacySettingsViewModel.hasSeedPhraseLengthOption)
return SettingsPickerCell<SeedPhraseLength>(
title: S.current.seed_phrase_length,
items: SeedPhraseLength.values,
selectedItem: widget.privacySettingsViewModel.seedPhraseLength,
onItemSelected: (SeedPhraseLength length) {
widget.privacySettingsViewModel.setSeedPhraseLength(length);
},
);
return Container();
}),
if (widget.privacySettingsViewModel.hasPassphraseOption)
Padding(
padding: EdgeInsets.all(24),
child: BaseTextFormField(
hintText: S.current.passphrase,
controller: passphraseController,
obscureText: true,
),
),
],
Observer(builder: (_) {
return Column(
children: [
@@ -122,31 +185,9 @@ class _AdvancedPrivacySettingsBodyState extends State<AdvancedPrivacySettingsBod
],
);
}),
if (widget.privacySettingsViewModel.hasSeedPhraseLengthOption)
Observer(builder: (_) {
return SettingsPickerCell<SeedPhraseLength>(
title: S.current.seed_phrase_length,
items: SeedPhraseLength.values,
selectedItem: widget.privacySettingsViewModel.seedPhraseLength,
onItemSelected: (SeedPhraseLength length) {
widget.privacySettingsViewModel.setSeedPhraseLength(length);
},
);
}),
if (widget.privacySettingsViewModel.hasSeedTypeOption)
Observer(builder: (_) {
return SettingsChoicesCell(
ChoicesListItem<SeedType>(
title: S.current.seedtype,
items: SeedType.all,
selectedItem: widget.seedTypeViewModel.moneroSeedType,
onItemSelected: widget.seedTypeViewModel.setMoneroSeedType,
),
);
}),
if (widget.privacySettingsViewModel.type == WalletType.bitcoin)
Builder(builder: (_) {
final val = testnetValue!;
final val = testnetValue ?? false;
return SettingsSwitcherCell(
title: S.current.use_testnet,
value: val,
@@ -154,7 +195,7 @@ class _AdvancedPrivacySettingsBodyState extends State<AdvancedPrivacySettingsBod
setState(() {
testnetValue = !val;
});
widget.toggleUseTestnet!.call(testnetValue);
widget.toggleUseTestnet.call(testnetValue);
});
}),
],
@@ -203,4 +244,11 @@ class _AdvancedPrivacySettingsBodyState extends State<AdvancedPrivacySettingsBod
),
);
}
@override
void dispose() {
passphraseController
.removeListener(() => widget.seedTypeViewModel.setPassphrase(passphraseController.text));
super.dispose();
}
}
+30 -31
View File
@@ -1,36 +1,35 @@
import 'package:cake_wallet/core/execution_state.dart';
import 'package:cake_wallet/core/wallet_name_validator.dart';
import 'package:cake_wallet/entities/generate_name.dart';
import 'package:cake_wallet/src/screens/new_wallet/widgets/select_button.dart';
import 'package:cake_wallet/src/widgets/picker.dart';
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/entities/seed_type.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/main.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/themes/theme_base.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/view_model/seed_type_view_model.dart';
import 'package:mobx/mobx.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/core/wallet_name_validator.dart';
import 'package:cake_wallet/src/widgets/seed_language_selector.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/screens/new_wallet/widgets/select_button.dart';
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
import 'package:cake_wallet/src/widgets/picker.dart';
import 'package:cake_wallet/src/widgets/primary_button.dart';
import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
import 'package:cake_wallet/src/widgets/seed_language_picker.dart';
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
import 'package:cake_wallet/core/execution_state.dart';
import 'package:cake_wallet/view_model/wallet_new_vm.dart';
import 'package:cake_wallet/src/widgets/seed_language_selector.dart';
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/themes/extensions/new_wallet_theme.dart';
import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
import 'package:cake_wallet/entities/seed_type.dart';
import 'package:cake_wallet/themes/theme_base.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/view_model/seed_settings_view_model.dart';
import 'package:cake_wallet/view_model/wallet_new_vm.dart';
import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:mobx/mobx.dart';
class NewWalletPage extends BasePage {
NewWalletPage(this._walletNewVM, this._seedTypeViewModel);
NewWalletPage(this._walletNewVM, this._seedSettingsViewModel);
final WalletNewVM _walletNewVM;
final SeedTypeViewModel _seedTypeViewModel;
final SeedSettingsViewModel _seedSettingsViewModel;
final walletNameImage = Image.asset('assets/images/wallet_name.png');
@@ -51,15 +50,15 @@ class NewWalletPage extends BasePage {
Widget body(BuildContext context) => WalletNameForm(
_walletNewVM,
currentTheme.type == ThemeType.dark ? walletNameImage : walletNameLightImage,
_seedTypeViewModel);
_seedSettingsViewModel);
}
class WalletNameForm extends StatefulWidget {
WalletNameForm(this._walletNewVM, this.walletImage, this._seedTypeViewModel);
WalletNameForm(this._walletNewVM, this.walletImage, this._seedSettingsViewModel);
final WalletNewVM _walletNewVM;
final Image walletImage;
final SeedTypeViewModel _seedTypeViewModel;
final SeedSettingsViewModel _seedSettingsViewModel;
@override
_WalletNameFormState createState() => _WalletNameFormState(_walletNewVM);
@@ -110,7 +109,7 @@ class _WalletNameFormState extends State<WalletNameForm> {
}
});
_setSeedType(SeedType.defaultSeedType);
_setSeedType(MoneroSeedType.defaultSeedType);
super.initState();
}
@@ -285,12 +284,12 @@ class _WalletNameFormState extends State<WalletNameForm> {
builder: (BuildContext build) => Padding(
padding: EdgeInsets.only(top: 24),
child: SelectButton(
text: widget._seedTypeViewModel.moneroSeedType.title,
text: widget._seedSettingsViewModel.moneroSeedType.title,
onTap: () async {
await showPopUp<void>(
context: context,
builder: (_) => Picker(
items: SeedType.all,
items: MoneroSeedType.all,
selectedAtIndex: isPolyseed ? 1 : 0,
onItemSelected: _setSeedType,
isSeparated: false,
@@ -308,8 +307,8 @@ class _WalletNameFormState extends State<WalletNameForm> {
key: _languageSelectorKey,
initialSelected: defaultSeedLanguage,
seedType: _walletNewVM.hasSeedType
? widget._seedTypeViewModel.moneroSeedType
: SeedType.legacy,
? widget._seedSettingsViewModel.moneroSeedType
: MoneroSeedType.legacy,
),
),
)
@@ -380,10 +379,10 @@ class _WalletNameFormState extends State<WalletNameForm> {
_formProcessing = false;
}
bool get isPolyseed => widget._seedTypeViewModel.moneroSeedType == SeedType.polyseed;
bool get isPolyseed => widget._seedSettingsViewModel.moneroSeedType == MoneroSeedType.polyseed;
void _setSeedType(SeedType item) {
widget._seedTypeViewModel.setMoneroSeedType(item);
void _setSeedType(MoneroSeedType item) {
widget._seedSettingsViewModel.setMoneroSeedType(item);
_languageSelectorKey.currentState?.selected = defaultSeedLanguage; // Reset Seed language
}
}
@@ -9,35 +9,34 @@ import 'package:cake_wallet/src/widgets/seed_language_picker.dart';
import 'package:cake_wallet/src/widgets/seed_widget.dart';
import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/view_model/seed_type_view_model.dart';
import 'package:cake_wallet/view_model/seed_settings_view_model.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:flutter/material.dart';
import 'package:mobx/mobx.dart';
import 'package:polyseed/polyseed.dart';
class WalletRestoreFromSeedForm extends StatefulWidget {
WalletRestoreFromSeedForm(
{Key? key,
required this.displayLanguageSelector,
required this.displayBlockHeightSelector,
required this.displayPassphrase,
required this.type,
required this.displayWalletPassword,
required this.seedTypeViewModel,
this.blockHeightFocusNode,
this.onHeightOrDateEntered,
this.onSeedChange,
this.onLanguageChange,
this.onPasswordChange,
this.onRepeatedPasswordChange})
: super(key: key);
WalletRestoreFromSeedForm({Key? key,
required this.displayLanguageSelector,
required this.displayBlockHeightSelector,
required this.displayPassphrase,
required this.type,
required this.displayWalletPassword,
required this.seedSettingsViewModel,
this.blockHeightFocusNode,
this.onHeightOrDateEntered,
this.onSeedChange,
this.onLanguageChange,
this.onPasswordChange,
this.onRepeatedPasswordChange,
}) : super(key: key);
final WalletType type;
final bool displayLanguageSelector;
final bool displayBlockHeightSelector;
final bool displayWalletPassword;
final bool displayPassphrase;
final SeedTypeViewModel seedTypeViewModel;
final SeedSettingsViewModel seedSettingsViewModel;
final FocusNode? blockHeightFocusNode;
final Function(bool)? onHeightOrDateEntered;
final void Function(String)? onSeedChange;
@@ -58,7 +57,9 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
languageController = TextEditingController(),
nameTextEditingController = TextEditingController(),
passwordTextEditingController = displayWalletPassword ? TextEditingController() : null,
repeatedPasswordTextEditingController = displayWalletPassword ? TextEditingController() : null,
repeatedPasswordTextEditingController = displayWalletPassword
? TextEditingController()
: null,
passphraseController = TextEditingController(),
seedTypeController = TextEditingController();
@@ -75,10 +76,11 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
String language;
void Function()? passwordListener;
void Function()? repeatedPasswordListener;
void Function()? passphraseListener;
@override
void initState() {
_setSeedType(widget.seedTypeViewModel.moneroSeedType);
_setSeedType(widget.seedSettingsViewModel.moneroSeedType);
_setLanguageLabel(language);
if (passwordTextEditingController != null) {
@@ -87,14 +89,19 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
}
if (repeatedPasswordTextEditingController != null) {
repeatedPasswordListener = () => widget.onRepeatedPasswordChange?.call(repeatedPasswordTextEditingController!.text);
repeatedPasswordListener =
() => widget.onRepeatedPasswordChange?.call(repeatedPasswordTextEditingController!.text);
repeatedPasswordTextEditingController?.addListener(repeatedPasswordListener!);
}
passphraseListener = () => widget.seedSettingsViewModel.setPassphrase(passphraseController.text);
passphraseController.addListener(passphraseListener!);
moneroSeedTypeReaction =
reaction((_) => widget.seedTypeViewModel.moneroSeedType, (SeedType item) {
_setSeedType(item);
_changeLanguage('English');
});
reaction((_) => widget.seedSettingsViewModel.moneroSeedType, (MoneroSeedType item) {
_setSeedType(item);
_changeLanguage('English');
});
super.initState();
}
@@ -110,6 +117,9 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
if (repeatedPasswordListener != null) {
repeatedPasswordTextEditingController?.removeListener(repeatedPasswordListener!);
}
passphraseController.removeListener(passphraseListener!);
super.dispose();
}
@@ -118,11 +128,13 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
Polyseed.isValidSeed(seed)) {
final lang = PolyseedLang.getByPhrase(seed);
_changeSeedType(SeedType.polyseed);
_changeSeedType(MoneroSeedType.polyseed);
_changeLanguage(lang.nameEnglish);
}
if (widget.type == WalletType.wownero && seed.split(" ").length == 14) {
_changeSeedType(SeedType.wowneroSeed);
if (widget.type == WalletType.wownero && seed
.split(" ")
.length == 14) {
_changeSeedType(MoneroSeedType.wowneroSeed);
_changeLanguage("English");
}
widget.onSeedChange?.call(seed);
@@ -140,7 +152,9 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
children: [
BaseTextFormField(
controller: nameTextEditingController,
hintText: S.of(context).wallet_name,
hintText: S
.of(context)
.wallet_name,
suffixIcon: IconButton(
onPressed: () async {
final rName = await generateName();
@@ -156,7 +170,9 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6.0),
color: Theme.of(context).hintColor,
color: Theme
.of(context)
.hintColor,
),
width: 34,
height: 34,
@@ -183,13 +199,14 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
onTap: () async {
await showPopUp<void>(
context: context,
builder: (_) => Picker(
builder: (_) =>
Picker(
items: _getItems(),
selectedAtIndex: isPolyseed
? 1
: seedTypeController.value.text.contains("14")
? 2
: 0,
? 2
: 0,
mainAxisAlignment: MainAxisAlignment.start,
onItemSelected: _changeSeedType,
isSeparated: false,
@@ -211,37 +228,43 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
if (widget.displayWalletPassword)
...[BaseTextFormField(
controller: passwordTextEditingController,
hintText: S.of(context).password,
hintText: S
.of(context)
.password,
obscureText: true),
BaseTextFormField(
controller: repeatedPasswordTextEditingController,
hintText: S.of(context).repeat_wallet_password,
obscureText: true)],
hintText: S
.of(context)
.repeat_wallet_password,
obscureText: true)
],
if (widget.displayLanguageSelector)
if (!seedTypeController.value.text.contains("14") && widget.displayLanguageSelector)
GestureDetector(
onTap: () async {
await showPopUp<void>(
context: context,
builder: (_) => SeedLanguagePicker(
selected: language,
onItemSelected: _changeLanguage,
seedType: isPolyseed ? SeedType.polyseed : SeedType.legacy,
));
},
child: Container(
color: Colors.transparent,
padding: EdgeInsets.only(top: 20.0),
child: IgnorePointer(
child: BaseTextFormField(
controller: languageController,
enableInteractiveSelection: false,
readOnly: true,
suffixIcon: expandIcon,
if (!seedTypeController.value.text.contains("14") && widget.displayLanguageSelector)
GestureDetector(
onTap: () async {
await showPopUp<void>(
context: context,
builder: (_) =>
SeedLanguagePicker(
selected: language,
onItemSelected: _changeLanguage,
seedType: isPolyseed ? MoneroSeedType.polyseed : MoneroSeedType.legacy,
));
},
child: Container(
color: Colors.transparent,
padding: EdgeInsets.only(top: 20.0),
child: IgnorePointer(
child: BaseTextFormField(
controller: languageController,
enableInteractiveSelection: false,
readOnly: true,
suffixIcon: expandIcon,
),
),
),
),
),
if ((!isPolyseed) && widget.displayBlockHeightSelector)
BlockchainHeightWidget(
focusNode: widget.blockHeightFocusNode,
@@ -262,17 +285,20 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
}
bool get isPolyseed =>
widget.seedTypeViewModel.moneroSeedType == SeedType.polyseed &&
(widget.type == WalletType.monero || widget.type == WalletType.wownero);
widget.seedSettingsViewModel.moneroSeedType == MoneroSeedType.polyseed &&
(widget.type == WalletType.monero || widget.type == WalletType.wownero);
Widget get expandIcon => Container(
Widget get expandIcon =>
Container(
padding: EdgeInsets.all(18),
width: 24,
height: 24,
child: Image.asset(
'assets/images/arrow_bottom_purple_icon.png',
height: 8,
color: Theme.of(context).hintColor,
color: Theme
.of(context)
.hintColor,
),
);
@@ -280,8 +306,8 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
final setLang = isPolyseed
? "POLYSEED_$language"
: seedTypeController.value.text.contains("14")
? "WOWSEED_" + language
: language;
? "WOWSEED_" + language
: language;
setState(() {
this.language = setLang;
seedWidgetStateKey.currentState!.changeSeedLanguage(setLang);
@@ -293,24 +319,24 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
void _setLanguageLabel(String language) =>
languageController.text = '${language.replaceAll("POLYSEED_", "")} (Seed language)';
void _changeSeedType(SeedType item) {
void _changeSeedType(MoneroSeedType item) {
_setSeedType(item);
_changeLanguage('English');
widget.seedTypeViewModel.setMoneroSeedType(item);
widget.seedSettingsViewModel.setMoneroSeedType(item);
}
void _setSeedType(SeedType item) {
void _setSeedType(MoneroSeedType item) {
seedTypeController.text = item.toString();
}
List<SeedType> _getItems() {
List<MoneroSeedType> _getItems() {
switch (widget.type) {
case WalletType.monero:
return [SeedType.legacy, SeedType.polyseed];
return [MoneroSeedType.legacy, MoneroSeedType.polyseed];
case WalletType.wownero:
return [SeedType.legacy, SeedType.polyseed, SeedType.wowneroSeed];
return [MoneroSeedType.legacy, MoneroSeedType.polyseed, MoneroSeedType.wowneroSeed];
default:
return [SeedType.legacy];
return [MoneroSeedType.legacy];
}
}
}
@@ -12,7 +12,7 @@ import 'package:cake_wallet/themes/extensions/wallet_list_theme.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/view_model/restore/restore_mode.dart';
import 'package:cake_wallet/view_model/seed_type_view_model.dart';
import 'package:cake_wallet/view_model/seed_settings_view_model.dart';
import 'package:cake_wallet/view_model/wallet_restore_view_model.dart';
import 'package:cw_core/wallet_info.dart';
import 'package:cw_core/wallet_type.dart';
@@ -23,7 +23,7 @@ import 'package:mobx/mobx.dart';
import 'package:smooth_page_indicator/smooth_page_indicator.dart';
class WalletRestorePage extends BasePage {
WalletRestorePage(this.walletRestoreViewModel, this.seedTypeViewModel)
WalletRestorePage(this.walletRestoreViewModel, this.seedSettingsViewModel)
: walletRestoreFromSeedFormKey = GlobalKey<WalletRestoreFromSeedFormState>(),
walletRestoreFromKeysFormKey = GlobalKey<WalletRestoreFromKeysFromState>(),
_pages = [],
@@ -33,7 +33,7 @@ class WalletRestorePage extends BasePage {
switch (mode) {
case WalletRestoreMode.seed:
_pages.add(WalletRestoreFromSeedForm(
seedTypeViewModel: seedTypeViewModel,
seedSettingsViewModel: seedSettingsViewModel,
displayBlockHeightSelector:
walletRestoreViewModel.hasBlockchainHeightLanguageSelector,
displayLanguageSelector: walletRestoreViewModel.hasSeedLanguageSelector,
@@ -96,7 +96,7 @@ class WalletRestorePage extends BasePage {
));
final WalletRestoreViewModel walletRestoreViewModel;
final SeedTypeViewModel seedTypeViewModel;
final SeedSettingsViewModel seedSettingsViewModel;
final PageController _controller;
final List<Widget> _pages;
final GlobalKey<WalletRestoreFromSeedFormState> walletRestoreFromSeedFormKey;
@@ -233,6 +233,7 @@ class WalletRestorePage extends BasePage {
onTap: () {
Navigator.of(context)
.pushNamed(Routes.advancedPrivacySettings, arguments: {
'isFromRestore': true,
'type': walletRestoreViewModel.type,
'useTestnet': walletRestoreViewModel.useTestnet,
'toggleTestnet': walletRestoreViewModel.toggleUseTestnet
@@ -322,8 +323,7 @@ class WalletRestorePage extends BasePage {
}
if (walletRestoreViewModel.hasPassphrase) {
credentials['passphrase'] =
walletRestoreFromSeedFormKey.currentState!.passphraseController.text;
credentials['passphrase'] = seedSettingsViewModel.passphrase;
}
credentials['name'] =
@@ -426,6 +426,7 @@ class WalletRestorePage extends BasePage {
}
await walletRestoreViewModel.create(options: _credentials());
seedSettingsViewModel.setPassphrase(null);
} catch (e) {
_formProcessing = false;
rethrow;
+17 -17
View File
@@ -11,36 +11,36 @@ class SeedLanguagePickerOption {
final String name;
final String nameLocalized;
final Image image;
final List<SeedType> supportedSeedTypes;
final List<MoneroSeedType> supportedSeedTypes;
}
final List<SeedLanguagePickerOption> seedLanguages = [
SeedLanguagePickerOption('English', S.current.seed_language_english,
Image.asset('assets/images/flags/usa.png'), [SeedType.legacy, SeedType.polyseed]),
Image.asset('assets/images/flags/usa.png'), [MoneroSeedType.legacy, MoneroSeedType.polyseed]),
SeedLanguagePickerOption('Chinese (Simplified)', S.current.seed_language_chinese,
Image.asset('assets/images/flags/chn.png'), [SeedType.legacy, SeedType.polyseed]),
Image.asset('assets/images/flags/chn.png'), [MoneroSeedType.legacy, MoneroSeedType.polyseed]),
SeedLanguagePickerOption('Chinese (Traditional)', S.current.seed_language_chinese_traditional,
Image.asset('assets/images/flags/chn.png'), [SeedType.polyseed]),
Image.asset('assets/images/flags/chn.png'), [MoneroSeedType.polyseed]),
SeedLanguagePickerOption('Dutch', S.current.seed_language_dutch,
Image.asset('assets/images/flags/nld.png'), [SeedType.legacy]),
Image.asset('assets/images/flags/nld.png'), [MoneroSeedType.legacy]),
SeedLanguagePickerOption('German', S.current.seed_language_german,
Image.asset('assets/images/flags/deu.png'), [SeedType.legacy]),
Image.asset('assets/images/flags/deu.png'), [MoneroSeedType.legacy]),
SeedLanguagePickerOption('Japanese', S.current.seed_language_japanese,
Image.asset('assets/images/flags/jpn.png'), [SeedType.legacy, SeedType.polyseed]),
Image.asset('assets/images/flags/jpn.png'), [MoneroSeedType.legacy, MoneroSeedType.polyseed]),
SeedLanguagePickerOption('Korean', S.current.seed_language_korean,
Image.asset('assets/images/flags/kor.png'), [SeedType.polyseed]),
Image.asset('assets/images/flags/kor.png'), [MoneroSeedType.polyseed]),
SeedLanguagePickerOption('Portuguese', S.current.seed_language_portuguese,
Image.asset('assets/images/flags/prt.png'), [SeedType.legacy, SeedType.polyseed]),
Image.asset('assets/images/flags/prt.png'), [MoneroSeedType.legacy, MoneroSeedType.polyseed]),
SeedLanguagePickerOption('Russian', S.current.seed_language_russian,
Image.asset('assets/images/flags/rus.png'), [SeedType.legacy]),
Image.asset('assets/images/flags/rus.png'), [MoneroSeedType.legacy]),
SeedLanguagePickerOption('Czech', S.current.seed_language_czech,
Image.asset('assets/images/flags/czk.png'), [SeedType.polyseed]),
Image.asset('assets/images/flags/czk.png'), [MoneroSeedType.polyseed]),
SeedLanguagePickerOption('Spanish', S.current.seed_language_spanish,
Image.asset('assets/images/flags/esp.png'), [SeedType.legacy, SeedType.polyseed]),
Image.asset('assets/images/flags/esp.png'), [MoneroSeedType.legacy, MoneroSeedType.polyseed]),
SeedLanguagePickerOption('French', S.current.seed_language_french,
Image.asset('assets/images/flags/fra.png'), [SeedType.legacy, SeedType.polyseed]),
Image.asset('assets/images/flags/fra.png'), [MoneroSeedType.legacy, MoneroSeedType.polyseed]),
SeedLanguagePickerOption('Italian', S.current.seed_language_italian,
Image.asset('assets/images/flags/ita.png'), [SeedType.legacy, SeedType.polyseed]),
Image.asset('assets/images/flags/ita.png'), [MoneroSeedType.legacy, MoneroSeedType.polyseed]),
];
const defaultSeedLanguage = 'English';
@@ -51,11 +51,11 @@ class SeedLanguagePicker extends StatefulWidget {
SeedLanguagePicker(
{Key? key,
this.selected = defaultSeedLanguage,
this.seedType = SeedType.defaultSeedType,
this.seedType = MoneroSeedType.defaultSeedType,
required this.onItemSelected})
: super(key: key);
final SeedType seedType;
final MoneroSeedType seedType;
final String selected;
final Function(String) onItemSelected;
@@ -68,7 +68,7 @@ class SeedLanguagePickerState extends State<SeedLanguagePicker> {
SeedLanguagePickerState(
{required this.selected, required this.onItemSelected, required this.seedType});
final SeedType seedType;
final MoneroSeedType seedType;
final String selected;
final Function(String) onItemSelected;
+2 -2
View File
@@ -7,11 +7,11 @@ import 'package:flutter/material.dart';
class SeedLanguageSelector extends StatefulWidget {
SeedLanguageSelector(
{Key? key, required this.initialSelected, this.seedType = SeedType.defaultSeedType})
{Key? key, required this.initialSelected, this.seedType = MoneroSeedType.defaultSeedType})
: super(key: key);
final String initialSelected;
final SeedType seedType;
final MoneroSeedType seedType;
@override
SeedLanguageSelectorState createState() => SeedLanguageSelectorState(selected: initialSelected);