Merge pull request #240 from cake-tech/CW-19

Fixes for validation of monero seed. Add French and Italian seeds val…
This commit is contained in:
mkyq 2022-01-24 14:05:56 +02:00 committed by GitHub
commit a1b4929bd9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 3383 additions and 32 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) {
switch (language.toLowerCase()) {
case 'english':
return EnglishMnemonics.words;
case 'chinese (simplified)':
return ChineseSimplifiedMnemonics.words;
case 'dutch':
return DutchMnemonics.words;
case 'german':
return GermanMnemonics.words;
case 'japanese':
return JapaneseMnemonics.words;
case 'portuguese':
return PortugueseMnemonics.words;
case 'russian':
return RussianMnemonics.words;
case 'spanish':
return SpanishMnemonics.words;
default:
return EnglishMnemonics.words;
}
switch (language.toLowerCase()) {
case 'english':
return EnglishMnemonics.words;
case 'chinese (simplified)':
return ChineseSimplifiedMnemonics.words;
case 'dutch':
return DutchMnemonics.words;
case 'german':
return GermanMnemonics.words;
case 'japanese':
return JapaneseMnemonics.words;
case 'portuguese':
return PortugueseMnemonics.words;
case 'russian':
return RussianMnemonics.words;
case 'spanish':
return SpanishMnemonics.words;
case 'french':
return FrenchMnemonics.words;
case 'italian':
return ItalianMnemonics.words;
default:
return EnglishMnemonics.words;
}
}
WalletCredentials createMoneroRestoreWalletFromKeysCredentials({

View file

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

View file

@ -1,5 +1,6 @@
import 'package:cake_wallet/src/widgets/keyboard_done_button.dart';
import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:keyboard_actions/keyboard_actions.dart';
@ -18,6 +19,7 @@ import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/core/validator.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
import 'package:cake_wallet/core/seed_validator.dart';
class WalletRestorePage extends BasePage {
WalletRestorePage(this.walletRestoreViewModel)
@ -39,8 +41,44 @@ class WalletRestorePage extends BasePage {
type: walletRestoreViewModel.type,
key: walletRestoreFromSeedFormKey,
blockHeightFocusNode: _blockHeightFocusNode,
onHeightOrDateEntered: (value) =>
walletRestoreViewModel.isButtonEnabled = value));
onHeightOrDateEntered: (value) {
if (_isValidSeed()) {
walletRestoreViewModel.isButtonEnabled = value;
}
},
onSeedChange: (String seed) {
if (walletRestoreViewModel.hasBlockchainHeightLanguageSelector) {
final hasHeight = walletRestoreFromSeedFormKey
.currentState
.blockchainHeightKey
.currentState
.restoreHeightController
.text
.isNotEmpty;
if (hasHeight) {
walletRestoreViewModel.isButtonEnabled = _isValidSeed();
}
} else {
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;
case WalletRestoreMode.keys:
_pages.add(WalletRestoreFromKeysFrom(
@ -169,6 +207,39 @@ class WalletRestorePage extends BasePage {
])));
}
bool _isValidSeed() {
final seedWords = walletRestoreFromSeedFormKey
.currentState
.seedWidgetStateKey
.currentState
.text
.split(' ');
if (walletRestoreViewModel.type == WalletType.monero &&
seedWords.length != WalletRestoreViewModelBase.moneroSeedMnemonicLength) {
return false;
}
if ((walletRestoreViewModel.type == WalletType.bitcoin ||
walletRestoreViewModel.type == WalletType.litecoin) &&
(seedWords.length != WalletRestoreViewModelBase.electrumSeedMnemonicLength &&
seedWords.length != WalletRestoreViewModelBase.electrumShortSeedMnemonicLength)) {
return false;
}
final words = walletRestoreFromSeedFormKey
.currentState
.seedWidgetStateKey
.currentState
.words
.toSet();
return seedWords
.toSet()
.difference(words)
.toSet()
.isEmpty;
}
Map<String, dynamic> _credentials() {
final credentials = <String, dynamic>{};

View file

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

View file

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

View file

@ -141,6 +141,8 @@ import 'package:cw_monero/mnemonics/japanese.dart';
import 'package:cw_monero/mnemonics/russian.dart';
import 'package:cw_monero/mnemonics/spanish.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 moneroContent = """