diff --git a/lib/bitcoin/bitcoin_mnemonic.dart b/lib/bitcoin/bitcoin_mnemonic.dart index ea7a66920..7f4bcd13c 100644 --- a/lib/bitcoin/bitcoin_mnemonic.dart +++ b/lib/bitcoin/bitcoin_mnemonic.dart @@ -128,6 +128,17 @@ Uint8List mnemonicToSeedBytes(String mnemonic, {String prefix = segwit}) { nonce: cryptography.Nonce('electrum'.codeUnits)); } +bool matchesAnyPrefix(String mnemonic) => + prefixMatches(mnemonic, [segwit]).any((el) => el); + +bool validateMnemonic(String mnemonic, {String prefix = segwit}) { + try { + return matchesAnyPrefix(mnemonic); + } catch(e) { + return false; + } +} + final COMBININGCODEPOINTS = combiningcodepoints(); List combiningcodepoints() { diff --git a/lib/bitcoin/bitcoin_transaction_history.dart b/lib/bitcoin/bitcoin_transaction_history.dart index c687c0ba4..09cefe5d4 100644 --- a/lib/bitcoin/bitcoin_transaction_history.dart +++ b/lib/bitcoin/bitcoin_transaction_history.dart @@ -65,7 +65,7 @@ abstract class BitcoinTransactionHistoryBase return historiesWithDetails.fold>( {}, (acc, tx) { - acc[tx.id] = tx; + acc[tx.id] = acc[tx.id]?.updated(tx) ?? tx; return acc; }); } @@ -103,10 +103,6 @@ abstract class BitcoinTransactionHistoryBase Future save() async { final data = json.encode({'height': _height, 'transactions': transactions}); - - print('data'); - print(data); - await writeData(path: path, password: _password, data: data); } @@ -168,7 +164,9 @@ abstract class BitcoinTransactionHistoryBase }); _height = content['height'] as int; - } catch (_) {} + } catch (e) { + print(e); + } } void _updateOrInsert(BitcoinTransactionInfo transaction) { diff --git a/lib/bitcoin/bitcoin_transaction_info.dart b/lib/bitcoin/bitcoin_transaction_info.dart index 29cb8521e..40487ceb7 100644 --- a/lib/bitcoin/bitcoin_transaction_info.dart +++ b/lib/bitcoin/bitcoin_transaction_info.dart @@ -130,6 +130,17 @@ class BitcoinTransactionInfo extends TransactionInfo { @override void changeFiatAmount(String amount) => _fiatAmount = formatAmount(amount); + BitcoinTransactionInfo updated(BitcoinTransactionInfo info) { + return BitcoinTransactionInfo( + id: id, + height: info.height, + amount: info.amount, + direction: direction ?? info.direction, + date: date ?? info.date, + isPending: isPending ?? info.isPending, + confirmations: info.confirmations); + } + Map toJson() { final m = {}; m['id'] = id; diff --git a/lib/bitcoin/bitcoin_wallet.dart b/lib/bitcoin/bitcoin_wallet.dart index ef3f10eb4..d6f1ce8f0 100644 --- a/lib/bitcoin/bitcoin_wallet.dart +++ b/lib/bitcoin/bitcoin_wallet.dart @@ -175,6 +175,22 @@ abstract class BitcoinWalletBase extends WalletBase with Store { return address; } + Future> generateNewAddresses(int count) async { + final list = []; + + for (var i = 0; i < count; i++) { + _accountIndex += 1; + final address = BitcoinAddressRecord(_getAddress(index: _accountIndex), + index: _accountIndex, label: null); + list.add(address); + } + + addresses.addAll(list); + await save(); + + return list; + } + Future updateAddress(String address, {String label}) async { for (final addr in addresses) { if (addr.address == address) { @@ -190,8 +206,10 @@ abstract class BitcoinWalletBase extends WalletBase with Store { Future startSync() async { try { syncStatus = StartingSyncStatus(); - transactionHistory.updateAsync( - onFinished: () => print('transactionHistory update finished!')); + transactionHistory.updateAsync(onFinished: () { + print('transactionHistory update finished!'); + transactionHistory.save(); + }); _subscribeForUpdates(); await _updateBalance(); syncStatus = SyncedSyncStatus(); @@ -315,8 +333,10 @@ abstract class BitcoinWalletBase extends WalletBase with Store { bitcoinAmountToDouble(amount: _feeMultiplier(priority)); @override - Future save() async => - await write(path: path, password: _password, data: toJSON()); + Future save() async { + await write(path: path, password: _password, data: toJSON()); + await transactionHistory.save(); + } bitcoin.ECPair keyPairFor({@required int index}) => generateKeyPair(hd: hd, index: index); diff --git a/lib/bitcoin/bitcoin_wallet_service.dart b/lib/bitcoin/bitcoin_wallet_service.dart index 49481545c..429a4e2ea 100644 --- a/lib/bitcoin/bitcoin_wallet_service.dart +++ b/lib/bitcoin/bitcoin_wallet_service.dart @@ -84,6 +84,7 @@ class BitcoinWalletService extends WalletService< walletInfo: credentials.walletInfo); await wallet.save(); await wallet.init(); + await wallet.generateNewAddresses(32); return wallet; } diff --git a/lib/bitcoin/electrum.dart b/lib/bitcoin/electrum.dart index 5348959e7..f679a62c6 100644 --- a/lib/bitcoin/electrum.dart +++ b/lib/bitcoin/electrum.dart @@ -78,14 +78,14 @@ class ElectrumClient { print(jsoned); final method = jsoned['method']; final id = jsoned['id'] as String; - final params = jsoned['result']; + final result = jsoned['result']; if (method is String) { _methodHandler(method: method, request: jsoned); return; } - _finish(id, params); + _finish(id, result); } catch (e) { print(e); } @@ -209,16 +209,20 @@ class ElectrumClient { Future> getTransactionExpanded( {@required String hash}) async { - final originalTx = await getTransactionRaw(hash: hash); - final vins = originalTx['vin'] as List; + try { + final originalTx = await getTransactionRaw(hash: hash); + final vins = originalTx['vin'] as List; - for (dynamic vin in vins) { - if (vin is Map) { - vin['tx'] = await getTransactionRaw(hash: vin['txid'] as String); + for (dynamic vin in vins) { + if (vin is Map) { + vin['tx'] = await getTransactionRaw(hash: vin['txid'] as String); + } } - } - return originalTx; + return originalTx; + } catch (_) { + return {}; + } } Future broadcastTransaction( @@ -256,11 +260,13 @@ class ElectrumClient { return 0; }); - BehaviorSubject scripthashUpdate(String scripthash) => - subscribe( - id: 'blockchain.scripthash.subscribe:$scripthash', - method: 'blockchain.scripthash.subscribe', - params: [scripthash]); + BehaviorSubject scripthashUpdate(String scripthash) { + _id += 1; + return subscribe( + id: 'blockchain.scripthash.subscribe:$scripthash', + method: 'blockchain.scripthash.subscribe', + params: [scripthash]); + } BehaviorSubject subscribe( {@required String id, @@ -273,7 +279,8 @@ class ElectrumClient { return subscription; } - Future call({String method, List params = const []}) { + Future call({String method, List params = const []}) async { + await Future.delayed(Duration(milliseconds: 100)); final completer = Completer(); _id += 1; final id = _id; diff --git a/lib/core/seed_validator.dart b/lib/core/seed_validator.dart index 36a06cb03..94ada7481 100644 --- a/lib/core/seed_validator.dart +++ b/lib/core/seed_validator.dart @@ -1,4 +1,4 @@ -import 'package:bip39/src/wordlists/english.dart' as bitcoin_english; +import 'package:cake_wallet/bitcoin/bitcoin_mnemonic.dart' as bitcoin_electrum; import 'package:cake_wallet/core/validator.dart'; import 'package:cake_wallet/entities/mnemonic_item.dart'; import 'package:cake_wallet/entities/wallet_type.dart'; @@ -64,7 +64,7 @@ class SeedValidator extends Validator { static List getBitcoinWordList(String language) { assert(language.toLowerCase() == LanguageList.english.toLowerCase()); - return bitcoin_english.WORDLIST; + return bitcoin_electrum.englishWordlist; } @override diff --git a/lib/main.dart b/lib/main.dart index 9cd55e054..42f76eb5c 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,3 +1,4 @@ +import 'package:cake_wallet/bitcoin/bitcoin_mnemonic.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:hive/hive.dart'; diff --git a/lib/router.dart b/lib/router.dart index aa3f2cf71..43c1ebc05 100644 --- a/lib/router.dart +++ b/lib/router.dart @@ -74,7 +74,7 @@ Route createRoute(RouteSettings settings) { param2: true)); case Routes.newWallet: - final type = WalletType.monero; // settings.arguments as WalletType; + final type = settings.arguments as WalletType; final walletNewVM = getIt.get(param1: type); return CupertinoPageRoute( @@ -96,7 +96,7 @@ Route createRoute(RouteSettings settings) { builder: (_) => getIt.get( param1: (BuildContext context, WalletType type) => Navigator.of(context) - .pushNamed(Routes.restoreWalletFromSeed, arguments: type), + .pushNamed(Routes.restoreWallet, arguments: type), param2: false)); case Routes.restoreOptions: @@ -146,7 +146,7 @@ Route createRoute(RouteSettings settings) { case Routes.restoreWallet: return MaterialPageRoute( builder: (_) => - getIt.get(param1: WalletType.monero)); + getIt.get(param1: settings.arguments as WalletType)); case Routes.restoreWalletFromSeed: final type = settings.arguments as WalletType; diff --git a/lib/src/screens/new_wallet/new_wallet_type_page.dart b/lib/src/screens/new_wallet/new_wallet_type_page.dart index 5751b11bd..0924988d8 100644 --- a/lib/src/screens/new_wallet/new_wallet_type_page.dart +++ b/lib/src/screens/new_wallet/new_wallet_type_page.dart @@ -70,7 +70,7 @@ class WalletTypeFormState extends State { : walletTypeLightImage; return Container( - padding: EdgeInsets.only(top: 24), + padding: EdgeInsets.only(top: 24, bottom: 24), child: ScrollableWithBottomSection( contentPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24), content: Column( @@ -107,7 +107,10 @@ class WalletTypeFormState extends State { bottomSection: PrimaryButton( onPressed: () => onTypeSelected(), text: S.of(context).seed_language_next, - color: Colors.green, + color: Theme.of(context) + .accentTextTheme + .subtitle + .decorationColor, textColor: Colors.white, isDisabled: selected == null, ), diff --git a/lib/src/screens/new_wallet/widgets/select_button.dart b/lib/src/screens/new_wallet/widgets/select_button.dart index bd69a8015..42b99e40e 100644 --- a/lib/src/screens/new_wallet/widgets/select_button.dart +++ b/lib/src/screens/new_wallet/widgets/select_button.dart @@ -16,7 +16,7 @@ class SelectButton extends StatelessWidget { @override Widget build(BuildContext context) { final color = isSelected - ? Theme.of(context).accentTextTheme.subtitle.decorationColor + ? Colors.green : Theme.of(context).accentTextTheme.caption.color; final textColor = isSelected ? Theme.of(context).accentTextTheme.headline.decorationColor diff --git a/lib/src/screens/restore/wallet_restore_from_seed_form.dart b/lib/src/screens/restore/wallet_restore_from_seed_form.dart index 6044531d9..e94f63bf0 100644 --- a/lib/src/screens/restore/wallet_restore_from_seed_form.dart +++ b/lib/src/screens/restore/wallet_restore_from_seed_form.dart @@ -1,3 +1,5 @@ +import 'package:cake_wallet/entities/wallet_type.dart'; +import 'package:cake_wallet/view_model/wallet_restore_view_model.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:cake_wallet/utils/show_pop_up.dart'; @@ -7,12 +9,20 @@ import 'package:cake_wallet/src/widgets/base_text_form_field.dart'; import 'package:cake_wallet/src/widgets/blockchain_height_widget.dart'; class WalletRestoreFromSeedForm extends StatefulWidget { - WalletRestoreFromSeedForm({Key key, this.blockHeightFocusNode, - this.onHeightOrDateEntered}) + WalletRestoreFromSeedForm( + {Key key, + @required this.displayLanguageSelector, + @required this.displayBlockHeightSelector, + @required this.type, + this.blockHeightFocusNode, + this.onHeightOrDateEntered}) : super(key: key); + final WalletType type; + final bool displayLanguageSelector; + final bool displayBlockHeightSelector; final FocusNode blockHeightFocusNode; - final Function (bool) onHeightOrDateEntered; + final Function(bool) onHeightOrDateEntered; @override WalletRestoreFromSeedFormState createState() => @@ -41,32 +51,35 @@ class WalletRestoreFromSeedFormState extends State { return Container( padding: EdgeInsets.only(left: 25, right: 25), child: Column(children: [ - SeedWidget(key: seedWidgetStateKey, language: language), - GestureDetector( - onTap: () async { - final selected = await showPopUp( - context: context, - builder: (BuildContext context) => - SeedLanguagePicker(selected: language)); + SeedWidget( + key: seedWidgetStateKey, language: language, type: widget.type), + if (widget.displayLanguageSelector) + GestureDetector( + onTap: () async { + final selected = await showPopUp( + context: context, + builder: (BuildContext context) => + SeedLanguagePicker(selected: language)); - if (selected == null || selected.isEmpty) { - return; - } + if (selected == null || selected.isEmpty) { + return; + } - _changeLanguage(selected); - }, - child: Container( - color: Colors.transparent, - padding: EdgeInsets.only(top: 20.0), - child: IgnorePointer( - child: BaseTextFormField( - controller: languageController, - enableInteractiveSelection: false, - readOnly: true)))), - BlockchainHeightWidget( - focusNode: widget.blockHeightFocusNode, - key: blockchainHeightKey, - onHeightOrDateEntered: widget.onHeightOrDateEntered) + _changeLanguage(selected); + }, + child: Container( + color: Colors.transparent, + padding: EdgeInsets.only(top: 20.0), + child: IgnorePointer( + child: BaseTextFormField( + controller: languageController, + enableInteractiveSelection: false, + readOnly: true)))), + if (widget.displayBlockHeightSelector) + BlockchainHeightWidget( + focusNode: widget.blockHeightFocusNode, + key: blockchainHeightKey, + onHeightOrDateEntered: widget.onHeightOrDateEntered) ])); } diff --git a/lib/src/screens/restore/wallet_restore_page.dart b/lib/src/screens/restore/wallet_restore_page.dart index 1a00639b6..adae48c89 100644 --- a/lib/src/screens/restore/wallet_restore_page.dart +++ b/lib/src/screens/restore/wallet_restore_page.dart @@ -25,16 +25,30 @@ class WalletRestorePage extends BasePage { _pages = [], _blockHeightFocusNode = FocusNode(), _controller = PageController(initialPage: 0) { - _pages.addAll([ - WalletRestoreFromSeedForm( - key: walletRestoreFromSeedFormKey, - blockHeightFocusNode: _blockHeightFocusNode, - onHeightOrDateEntered: (value) - => walletRestoreViewModel.isButtonEnabled = value), - WalletRestoreFromKeysFrom(key: walletRestoreFromKeysFormKey, - onHeightOrDateEntered: (value) - => walletRestoreViewModel.isButtonEnabled = value) - ]); + walletRestoreViewModel.availableModes.forEach((mode) { + switch (mode) { + case WalletRestoreMode.seed: + _pages.add(WalletRestoreFromSeedForm( + displayBlockHeightSelector: + walletRestoreViewModel.hasBlockchainHeightLanguageSelector, + displayLanguageSelector: + walletRestoreViewModel.hasSeedLanguageSelector, + type: walletRestoreViewModel.type, + key: walletRestoreFromSeedFormKey, + blockHeightFocusNode: _blockHeightFocusNode, + onHeightOrDateEntered: (value) => + walletRestoreViewModel.isButtonEnabled = value)); + break; + case WalletRestoreMode.keys: + _pages.add(WalletRestoreFromKeysFrom( + key: walletRestoreFromKeysFormKey, + onHeightOrDateEntered: (value) => + walletRestoreViewModel.isButtonEnabled = value)); + break; + default: + break; + } + }); } @override @@ -76,20 +90,19 @@ class WalletRestorePage extends BasePage { } }); - reaction((_) => walletRestoreViewModel.mode, (WalletRestoreMode mode) - { - walletRestoreViewModel.isButtonEnabled = false; + reaction((_) => walletRestoreViewModel.mode, (WalletRestoreMode mode) { + walletRestoreViewModel.isButtonEnabled = false; - walletRestoreFromSeedFormKey.currentState.blockchainHeightKey - .currentState.restoreHeightController.text = ''; - walletRestoreFromSeedFormKey.currentState.blockchainHeightKey - .currentState.dateController.text = ''; + walletRestoreFromSeedFormKey.currentState.blockchainHeightKey.currentState + .restoreHeightController.text = ''; + walletRestoreFromSeedFormKey.currentState.blockchainHeightKey.currentState + .dateController.text = ''; - walletRestoreFromKeysFormKey.currentState.blockchainHeightKey - .currentState.restoreHeightController.text = ''; - walletRestoreFromKeysFormKey.currentState.blockchainHeightKey - .currentState.dateController.text = ''; - }); + walletRestoreFromKeysFormKey.currentState.blockchainHeightKey.currentState + .restoreHeightController.text = ''; + walletRestoreFromKeysFormKey.currentState.blockchainHeightKey.currentState + .dateController.text = ''; + }); return Column(mainAxisAlignment: MainAxisAlignment.center, children: [ Expanded( @@ -100,40 +113,37 @@ class WalletRestorePage extends BasePage { }, controller: _controller, itemCount: _pages.length, - itemBuilder: (_, index) => SingleChildScrollView(child: _pages[index]))), - Padding( - padding: EdgeInsets.only(top: 10), - child: SmoothPageIndicator( - controller: _controller, - count: _pages.length, - effect: ColorTransitionEffect( - spacing: 6.0, - radius: 6.0, - dotWidth: 6.0, - dotHeight: 6.0, - dotColor: Theme.of(context).hintColor.withOpacity(0.5), - activeDotColor: Theme.of(context).hintColor), - )), + itemBuilder: (_, index) => + SingleChildScrollView(child: _pages[index]))), + if (_pages.length > 1) + Padding( + padding: EdgeInsets.only(top: 10), + child: SmoothPageIndicator( + controller: _controller, + count: _pages.length, + effect: ColorTransitionEffect( + spacing: 6.0, + radius: 6.0, + dotWidth: 6.0, + dotHeight: 6.0, + dotColor: Theme.of(context).hintColor.withOpacity(0.5), + activeDotColor: Theme.of(context).hintColor), + )), Padding( padding: EdgeInsets.only(top: 20, bottom: 40, left: 25, right: 25), child: Observer( builder: (context) { return LoadingPrimaryButton( - onPressed: () => - walletRestoreViewModel.create(options: _credentials()), - text: S.of(context).restore_recover, - color: Theme - .of(context) - .accentTextTheme - .subtitle - .decorationColor, - textColor: Theme - .of(context) - .accentTextTheme - .headline - .decorationColor, - isLoading: walletRestoreViewModel.state is IsExecutingState, - isDisabled: !walletRestoreViewModel.isButtonEnabled,); + onPressed: () => + walletRestoreViewModel.create(options: _credentials()), + text: S.of(context).restore_recover, + color: + Theme.of(context).accentTextTheme.subtitle.decorationColor, + textColor: + Theme.of(context).accentTextTheme.headline.decorationColor, + isLoading: walletRestoreViewModel.state is IsExecutingState, + isDisabled: !walletRestoreViewModel.isButtonEnabled, + ); }, )) ]); @@ -145,8 +155,11 @@ class WalletRestorePage extends BasePage { if (walletRestoreViewModel.mode == WalletRestoreMode.seed) { credentials['seed'] = walletRestoreFromSeedFormKey .currentState.seedWidgetStateKey.currentState.text; - credentials['height'] = walletRestoreFromSeedFormKey - .currentState.blockchainHeightKey.currentState.height; + + if (walletRestoreViewModel.hasBlockchainHeightLanguageSelector) { + credentials['height'] = walletRestoreFromSeedFormKey + .currentState.blockchainHeightKey.currentState.height; + } } else { credentials['address'] = walletRestoreFromKeysFormKey.currentState.addressController.text; diff --git a/lib/src/widgets/seed_widget.dart b/lib/src/widgets/seed_widget.dart index ddebbffa0..b53dd8644 100644 --- a/lib/src/widgets/seed_widget.dart +++ b/lib/src/widgets/seed_widget.dart @@ -12,20 +12,21 @@ import 'package:cake_wallet/generated/i18n.dart'; import 'package:flutter/widgets.dart'; class SeedWidget extends StatefulWidget { - SeedWidget({Key key, this.language}) : super(key: key); + SeedWidget({Key key, this.language, this.type}) : super(key: key); final String language; + final WalletType type; @override - SeedWidgetState createState() => SeedWidgetState(language); + SeedWidgetState createState() => SeedWidgetState(language, type); } class SeedWidgetState extends State { - SeedWidgetState(String language) + SeedWidgetState(String language, this.type) : controller = TextEditingController(), focusNode = FocusNode(), words = SeedValidator.getWordList( - type: WalletType.monero, language: language) { + type:type, language: language) { focusNode.addListener(() { setState(() { if (!focusNode.hasFocus && controller.text.isEmpty) { @@ -41,6 +42,7 @@ class SeedWidgetState extends State { final TextEditingController controller; final FocusNode focusNode; + final WalletType type; List words; bool _showPlaceholder; @@ -55,7 +57,7 @@ class SeedWidgetState extends State { void changeSeedLanguage(String language) { setState(() { words = SeedValidator.getWordList( - type: WalletType.monero, language: language); + type: type, language: language); }); } diff --git a/lib/view_model/dashboard/dashboard_view_model.dart b/lib/view_model/dashboard/dashboard_view_model.dart index e76a663ec..5c1b33304 100644 --- a/lib/view_model/dashboard/dashboard_view_model.dart +++ b/lib/view_model/dashboard/dashboard_view_model.dart @@ -178,6 +178,7 @@ abstract class DashboardViewModelBase with Store { @action void _onWalletChange(WalletBase wallet) { this.wallet = wallet; + type = wallet.type; name = wallet.name; transactions.clear(); transactions.addAll(wallet.transactionHistory.transactions.values.map( diff --git a/lib/view_model/wallet_restore_view_model.dart b/lib/view_model/wallet_restore_view_model.dart index 49dab88e4..b015535ae 100644 --- a/lib/view_model/wallet_restore_view_model.dart +++ b/lib/view_model/wallet_restore_view_model.dart @@ -1,3 +1,4 @@ +import 'package:cake_wallet/bitcoin/bitcoin_wallet_creation_credentials.dart'; import 'package:flutter/foundation.dart'; import 'package:hive/hive.dart'; import 'package:mobx/mobx.dart'; @@ -22,10 +23,16 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store { WalletRestoreViewModelBase(AppStore appStore, this._walletCreationService, Box walletInfoSource, {@required WalletType type}) - : super(appStore, walletInfoSource, type: type, isRecovery: true) { - isButtonEnabled = false; + : availableModes = type == WalletType.monero + ? WalletRestoreMode.values + : [WalletRestoreMode.seed], + hasSeedLanguageSelector = type == WalletType.monero, + hasBlockchainHeightLanguageSelector = type == WalletType.monero, + super(appStore, walletInfoSource, type: type, isRecovery: true) { + isButtonEnabled = + !hasSeedLanguageSelector && !hasBlockchainHeightLanguageSelector; mode = WalletRestoreMode.seed; - _walletCreationService.changeWalletType(type: WalletType.monero); + _walletCreationService.changeWalletType(type: type); } @observable @@ -34,6 +41,10 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store { @observable bool isButtonEnabled; + final List availableModes; + final bool hasSeedLanguageSelector; + final bool hasBlockchainHeightLanguageSelector; + final WalletCreationService _walletCreationService; @override @@ -44,8 +55,16 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store { if (mode == WalletRestoreMode.seed) { final seed = options['seed'] as String; - return MoneroRestoreWalletFromSeedCredentials( - name: name, height: height, mnemonic: seed, password: password); + switch (type) { + case WalletType.monero: + return MoneroRestoreWalletFromSeedCredentials( + name: name, height: height, mnemonic: seed, password: password); + case WalletType.bitcoin: + return BitcoinRestoreWalletFromSeedCredentials( + name: name, mnemonic: seed, password: password); + default: + break; + } } if (mode == WalletRestoreMode.keys) {