Fixes for validation of monero seed. Add French and Italian seeds validation.

This commit is contained in:
M 2022-01-19 16:25:58 +02:00
parent 2bbd413b12
commit bd2e2ce258
8 changed files with 3372 additions and 30 deletions

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -169,26 +169,30 @@ class CWMonero extends Monero {
} }
List<String> getMoneroWordList(String language) { List<String> getMoneroWordList(String language) {
switch (language.toLowerCase()) { switch (language.toLowerCase()) {
case 'english': case 'english':
return EnglishMnemonics.words; return EnglishMnemonics.words;
case 'chinese (simplified)': case 'chinese (simplified)':
return ChineseSimplifiedMnemonics.words; return ChineseSimplifiedMnemonics.words;
case 'dutch': case 'dutch':
return DutchMnemonics.words; return DutchMnemonics.words;
case 'german': case 'german':
return GermanMnemonics.words; return GermanMnemonics.words;
case 'japanese': case 'japanese':
return JapaneseMnemonics.words; return JapaneseMnemonics.words;
case 'portuguese': case 'portuguese':
return PortugueseMnemonics.words; return PortugueseMnemonics.words;
case 'russian': case 'russian':
return RussianMnemonics.words; return RussianMnemonics.words;
case 'spanish': case 'spanish':
return SpanishMnemonics.words; return SpanishMnemonics.words;
default: case 'french':
return EnglishMnemonics.words; return FrenchMnemonics.words;
} case 'italian':
return ItalianMnemonics.words;
default:
return EnglishMnemonics.words;
}
} }
WalletCredentials createMoneroRestoreWalletFromKeysCredentials({ WalletCredentials createMoneroRestoreWalletFromKeysCredentials({

View file

@ -18,7 +18,9 @@ class WalletRestoreFromSeedForm extends StatefulWidget {
@required this.displayBlockHeightSelector, @required this.displayBlockHeightSelector,
@required this.type, @required this.type,
this.blockHeightFocusNode, this.blockHeightFocusNode,
this.onHeightOrDateEntered}) this.onHeightOrDateEntered,
this.onSeedChange,
this.onLanguageChange})
: super(key: key); : super(key: key);
final WalletType type; final WalletType type;
@ -26,6 +28,8 @@ class WalletRestoreFromSeedForm extends StatefulWidget {
final bool displayBlockHeightSelector; final bool displayBlockHeightSelector;
final FocusNode blockHeightFocusNode; final FocusNode blockHeightFocusNode;
final Function(bool) onHeightOrDateEntered; final Function(bool) onHeightOrDateEntered;
final void Function(String) onSeedChange;
final void Function(String) onLanguageChange;
@override @override
WalletRestoreFromSeedFormState createState() => WalletRestoreFromSeedFormState createState() =>
@ -62,7 +66,10 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
validator: WalletNameValidator()), validator: WalletNameValidator()),
Container(height: 20), Container(height: 20),
SeedWidget( SeedWidget(
key: seedWidgetStateKey, language: language, type: widget.type), key: seedWidgetStateKey,
language: language,
type: widget.type,
onSeedChange: widget.onSeedChange),
if (widget.displayLanguageSelector) if (widget.displayLanguageSelector)
GestureDetector( GestureDetector(
onTap: () async { onTap: () async {
@ -98,6 +105,7 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
this.language = language; this.language = language;
seedWidgetStateKey.currentState.changeSeedLanguage(language); seedWidgetStateKey.currentState.changeSeedLanguage(language);
_setLanguageLabel(language); _setLanguageLabel(language);
widget.onLanguageChange?.call(language);
}); });
} }

View file

@ -18,6 +18,7 @@ import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/core/validator.dart'; import 'package:cake_wallet/core/validator.dart';
import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/widgets/base_text_form_field.dart'; import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
import 'package:cake_wallet/core/seed_validator.dart';
class WalletRestorePage extends BasePage { class WalletRestorePage extends BasePage {
WalletRestorePage(this.walletRestoreViewModel) WalletRestorePage(this.walletRestoreViewModel)
@ -39,8 +40,40 @@ class WalletRestorePage extends BasePage {
type: walletRestoreViewModel.type, type: walletRestoreViewModel.type,
key: walletRestoreFromSeedFormKey, key: walletRestoreFromSeedFormKey,
blockHeightFocusNode: _blockHeightFocusNode, blockHeightFocusNode: _blockHeightFocusNode,
onHeightOrDateEntered: (value) => onHeightOrDateEntered: (value) {
walletRestoreViewModel.isButtonEnabled = value)); if (_isValidSeed()) {
walletRestoreViewModel.isButtonEnabled = value;
}
},
onSeedChange: (String seed) {
final hasHeight = walletRestoreFromSeedFormKey
.currentState
.blockchainHeightKey
.currentState
.restoreHeightController
.text
.isNotEmpty;
if (hasHeight) {
walletRestoreViewModel.isButtonEnabled = _isValidSeed();
}
},
onLanguageChange: (_) {
if (walletRestoreViewModel.hasBlockchainHeightLanguageSelector) {
final hasHeight = walletRestoreFromSeedFormKey
.currentState
.blockchainHeightKey
.currentState
.restoreHeightController
.text
.isNotEmpty;
if (hasHeight) {
walletRestoreViewModel.isButtonEnabled = _isValidSeed();
}
} else {
walletRestoreViewModel.isButtonEnabled = _isValidSeed();
}
}));
break; break;
case WalletRestoreMode.keys: case WalletRestoreMode.keys:
_pages.add(WalletRestoreFromKeysFrom( _pages.add(WalletRestoreFromKeysFrom(
@ -169,6 +202,31 @@ class WalletRestorePage extends BasePage {
]))); ])));
} }
bool _isValidSeed() {
final seedWords = walletRestoreFromSeedFormKey
.currentState
.seedWidgetStateKey
.currentState
.text
.split(' ');
if (seedWords.length != walletRestoreViewModel.seedMnemonicLength) {
return false;
}
final words = walletRestoreFromSeedFormKey
.currentState
.seedWidgetStateKey
.currentState
.words
.toSet();
return seedWords
.toSet()
.difference(words)
.toSet()
.isEmpty;
}
Map<String, dynamic> _credentials() { Map<String, dynamic> _credentials() {
final credentials = <String, dynamic>{}; final credentials = <String, dynamic>{};

View file

@ -12,10 +12,11 @@ import 'package:cake_wallet/generated/i18n.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
class SeedWidget extends StatefulWidget { class SeedWidget extends StatefulWidget {
SeedWidget({Key key, this.language, this.type}) : super(key: key); SeedWidget({Key key, this.language, this.type, this.onSeedChange}) : super(key: key);
final String language; final String language;
final WalletType type; final WalletType type;
final void Function(String) onSeedChange;
@override @override
SeedWidgetState createState() => SeedWidgetState(language, type); SeedWidgetState createState() => SeedWidgetState(language, type);
@ -52,6 +53,7 @@ class SeedWidgetState extends State<SeedWidget> {
void initState() { void initState() {
super.initState(); super.initState();
_showPlaceholder = true; _showPlaceholder = true;
controller.addListener(() => widget.onSeedChange?.call(text));
} }
void changeSeedLanguage(String language) { void changeSeedLanguage(String language) {

View file

@ -1,4 +1,5 @@
import 'package:cake_wallet/bitcoin/bitcoin.dart'; import 'package:cake_wallet/bitcoin/bitcoin.dart';
import 'package:cake_wallet/core/mnemonic_length.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:hive/hive.dart'; import 'package:hive/hive.dart';
import 'package:mobx/mobx.dart'; import 'package:mobx/mobx.dart';
@ -35,17 +36,24 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
_walletCreationService.changeWalletType(type: type); _walletCreationService.changeWalletType(type: type);
} }
static const moneroSeedMnemonicLength = 25;
static const electrumSeedMnemonicLength = 24;
final List<WalletRestoreMode> availableModes;
final bool hasSeedLanguageSelector;
final bool hasBlockchainHeightLanguageSelector;
final WalletCreationService _walletCreationService;
@observable @observable
WalletRestoreMode mode; WalletRestoreMode mode;
@observable @observable
bool isButtonEnabled; bool isButtonEnabled;
final List<WalletRestoreMode> availableModes; int get seedMnemonicLength =>
final bool hasSeedLanguageSelector; type == WalletType.monero
final bool hasBlockchainHeightLanguageSelector; ? moneroSeedMnemonicLength
: electrumSeedMnemonicLength;
final WalletCreationService _walletCreationService;
@override @override
WalletCredentials getCredentials(dynamic options) { WalletCredentials getCredentials(dynamic options) {

View file

@ -143,6 +143,8 @@ import 'package:cw_monero/mnemonics/japanese.dart';
import 'package:cw_monero/mnemonics/russian.dart'; import 'package:cw_monero/mnemonics/russian.dart';
import 'package:cw_monero/mnemonics/spanish.dart'; import 'package:cw_monero/mnemonics/spanish.dart';
import 'package:cw_monero/mnemonics/portuguese.dart'; import 'package:cw_monero/mnemonics/portuguese.dart';
import 'package:cw_monero/mnemonics/french.dart';
import 'package:cw_monero/mnemonics/italian.dart';
"""; """;
const moneroCwPart = "part 'cw_monero.dart';"; const moneroCwPart = "part 'cw_monero.dart';";
const moneroContent = """ const moneroContent = """