Fixes

M committed Nov 30, 2020 at 19:17 UTC 62a877dd6168549f003d58e92226df91c5a369de
16 files changed +223 -123
lib/bitcoin/bitcoin_mnemonic.dart
+11
@@ -128,6 +128,17 @@ Uint8List mnemonicToSeedBytes(String mnemonic, {String prefix = segwit}) {
128 nonce: cryptography.Nonce('electrum'.codeUnits));
129 }
130
131 +bool matchesAnyPrefix(String mnemonic) =>
132 + prefixMatches(mnemonic, [segwit]).any((el) => el);
133 +
134 +bool validateMnemonic(String mnemonic, {String prefix = segwit}) {
135 + try {
136 + return matchesAnyPrefix(mnemonic);
137 + } catch(e) {
138 + return false;
139 + }
140 +}
141 +
142 final COMBININGCODEPOINTS = combiningcodepoints();
143
144 List<int> combiningcodepoints() {
lib/bitcoin/bitcoin_transaction_history.dart
+4 -6
@@ -65,7 +65,7 @@ abstract class BitcoinTransactionHistoryBase
65
66 return historiesWithDetails.fold<Map<String, BitcoinTransactionInfo>>(
67 <String, BitcoinTransactionInfo>{}, (acc, tx) {
68 - acc[tx.id] = tx;
68 + acc[tx.id] = acc[tx.id]?.updated(tx) ?? tx;
69 return acc;
70 });
71 }
@@ -103,10 +103,6 @@ abstract class BitcoinTransactionHistoryBase
103
104 Future<void> save() async {
105 final data = json.encode({'height': _height, 'transactions': transactions});
106 -
107 - print('data');
108 - print(data);
109 -
106 await writeData(path: path, password: _password, data: data);
107 }
108
@@ -168,7 +164,9 @@ abstract class BitcoinTransactionHistoryBase
164 });
165
166 _height = content['height'] as int;
171 - } catch (_) {}
167 + } catch (e) {
168 + print(e);
169 + }
170 }
171
172 void _updateOrInsert(BitcoinTransactionInfo transaction) {
lib/bitcoin/bitcoin_transaction_info.dart
+11
@@ -130,6 +130,17 @@ class BitcoinTransactionInfo extends TransactionInfo {
130 @override
131 void changeFiatAmount(String amount) => _fiatAmount = formatAmount(amount);
132
133 + BitcoinTransactionInfo updated(BitcoinTransactionInfo info) {
134 + return BitcoinTransactionInfo(
135 + id: id,
136 + height: info.height,
137 + amount: info.amount,
138 + direction: direction ?? info.direction,
139 + date: date ?? info.date,
140 + isPending: isPending ?? info.isPending,
141 + confirmations: info.confirmations);
142 + }
143 +
144 Map<String, dynamic> toJson() {
145 final m = <String, dynamic>{};
146 m['id'] = id;
lib/bitcoin/bitcoin_wallet.dart
+24 -4
@@ -175,6 +175,22 @@ abstract class BitcoinWalletBase extends WalletBase<BitcoinBalance> with Store {
175 return address;
176 }
177
178 + Future<List<BitcoinAddressRecord>> generateNewAddresses(int count) async {
179 + final list = <BitcoinAddressRecord>[];
180 +
181 + for (var i = 0; i < count; i++) {
182 + _accountIndex += 1;
183 + final address = BitcoinAddressRecord(_getAddress(index: _accountIndex),
184 + index: _accountIndex, label: null);
185 + list.add(address);
186 + }
187 +
188 + addresses.addAll(list);
189 + await save();
190 +
191 + return list;
192 + }
193 +
194 Future<void> updateAddress(String address, {String label}) async {
195 for (final addr in addresses) {
196 if (addr.address == address) {
@@ -190,8 +206,10 @@ abstract class BitcoinWalletBase extends WalletBase<BitcoinBalance> with Store {
206 Future<void> startSync() async {
207 try {
208 syncStatus = StartingSyncStatus();
193 - transactionHistory.updateAsync(
194 - onFinished: () => print('transactionHistory update finished!'));
209 + transactionHistory.updateAsync(onFinished: () {
210 + print('transactionHistory update finished!');
211 + transactionHistory.save();
212 + });
213 _subscribeForUpdates();
214 await _updateBalance();
215 syncStatus = SyncedSyncStatus();
@@ -315,8 +333,10 @@ abstract class BitcoinWalletBase extends WalletBase<BitcoinBalance> with Store {
333 bitcoinAmountToDouble(amount: _feeMultiplier(priority));
334
335 @override
318 - Future<void> save() async =>
319 - await write(path: path, password: _password, data: toJSON());
336 + Future<void> save() async {
337 + await write(path: path, password: _password, data: toJSON());
338 + await transactionHistory.save();
339 + }
340
341 bitcoin.ECPair keyPairFor({@required int index}) =>
342 generateKeyPair(hd: hd, index: index);
lib/bitcoin/bitcoin_wallet_service.dart
+1
@@ -84,6 +84,7 @@ class BitcoinWalletService extends WalletService<
84 walletInfo: credentials.walletInfo);
85 await wallet.save();
86 await wallet.init();
87 + await wallet.generateNewAddresses(32);
88
89 return wallet;
90 }
lib/bitcoin/electrum.dart
+22 -15
@@ -78,14 +78,14 @@ class ElectrumClient {
78 print(jsoned);
79 final method = jsoned['method'];
80 final id = jsoned['id'] as String;
81 - final params = jsoned['result'];
81 + final result = jsoned['result'];
82
83 if (method is String) {
84 _methodHandler(method: method, request: jsoned);
85 return;
86 }
87
88 - _finish(id, params);
88 + _finish(id, result);
89 } catch (e) {
90 print(e);
91 }
@@ -209,16 +209,20 @@ class ElectrumClient {
209
210 Future<Map<String, Object>> getTransactionExpanded(
211 {@required String hash}) async {
212 - final originalTx = await getTransactionRaw(hash: hash);
213 - final vins = originalTx['vin'] as List<Object>;
212 + try {
213 + final originalTx = await getTransactionRaw(hash: hash);
214 + final vins = originalTx['vin'] as List<Object>;
215
215 - for (dynamic vin in vins) {
216 - if (vin is Map<String, Object>) {
217 - vin['tx'] = await getTransactionRaw(hash: vin['txid'] as String);
216 + for (dynamic vin in vins) {
217 + if (vin is Map<String, Object>) {
218 + vin['tx'] = await getTransactionRaw(hash: vin['txid'] as String);
219 + }
220 }
219 - }
221
221 - return originalTx;
222 + return originalTx;
223 + } catch (_) {
224 + return {};
225 + }
226 }
227
228 Future<String> broadcastTransaction(
@@ -256,11 +260,13 @@ class ElectrumClient {
260 return 0;
261 });
262
259 - BehaviorSubject<Object> scripthashUpdate(String scripthash) =>
260 - subscribe<Object>(
261 - id: 'blockchain.scripthash.subscribe:$scripthash',
262 - method: 'blockchain.scripthash.subscribe',
263 - params: [scripthash]);
263 + BehaviorSubject<Object> scripthashUpdate(String scripthash) {
264 + _id += 1;
265 + return subscribe<Object>(
266 + id: 'blockchain.scripthash.subscribe:$scripthash',
267 + method: 'blockchain.scripthash.subscribe',
268 + params: [scripthash]);
269 + }
270
271 BehaviorSubject<T> subscribe<T>(
272 {@required String id,
@@ -273,7 +279,8 @@ class ElectrumClient {
279 return subscription;
280 }
281
276 - Future<dynamic> call({String method, List<Object> params = const []}) {
282 + Future<dynamic> call({String method, List<Object> params = const []}) async {
283 + await Future<void>.delayed(Duration(milliseconds: 100));
284 final completer = Completer<dynamic>();
285 _id += 1;
286 final id = _id;
lib/core/seed_validator.dart
+2 -2
@@ -1,4 +1,4 @@
1 -import 'package:bip39/src/wordlists/english.dart' as bitcoin_english;
1 +import 'package:cake_wallet/bitcoin/bitcoin_mnemonic.dart' as bitcoin_electrum;
2 import 'package:cake_wallet/core/validator.dart';
3 import 'package:cake_wallet/entities/mnemonic_item.dart';
4 import 'package:cake_wallet/entities/wallet_type.dart';
@@ -64,7 +64,7 @@ class SeedValidator extends Validator<MnemonicItem> {
64
65 static List<String> getBitcoinWordList(String language) {
66 assert(language.toLowerCase() == LanguageList.english.toLowerCase());
67 - return bitcoin_english.WORDLIST;
67 + return bitcoin_electrum.englishWordlist;
68 }
69
70 @override
lib/main.dart
+1
@@ -1,3 +1,4 @@
1 +import 'package:cake_wallet/bitcoin/bitcoin_mnemonic.dart';
2 import 'package:flutter/material.dart';
3 import 'package:flutter/services.dart';
4 import 'package:hive/hive.dart';
lib/router.dart
+3 -3
@@ -74,7 +74,7 @@ Route<dynamic> createRoute(RouteSettings settings) {
74 param2: true));
75
76 case Routes.newWallet:
77 - final type = WalletType.monero; // settings.arguments as WalletType;
77 + final type = settings.arguments as WalletType;
78 final walletNewVM = getIt.get<WalletNewVM>(param1: type);
79
80 return CupertinoPageRoute<void>(
@@ -96,7 +96,7 @@ Route<dynamic> createRoute(RouteSettings settings) {
96 builder: (_) => getIt.get<NewWalletTypePage>(
97 param1: (BuildContext context, WalletType type) =>
98 Navigator.of(context)
99 - .pushNamed(Routes.restoreWalletFromSeed, arguments: type),
99 + .pushNamed(Routes.restoreWallet, arguments: type),
100 param2: false));
101
102 case Routes.restoreOptions:
@@ -146,7 +146,7 @@ Route<dynamic> createRoute(RouteSettings settings) {
146 case Routes.restoreWallet:
147 return MaterialPageRoute<void>(
148 builder: (_) =>
149 - getIt.get<WalletRestorePage>(param1: WalletType.monero));
149 + getIt.get<WalletRestorePage>(param1: settings.arguments as WalletType));
150
151 case Routes.restoreWalletFromSeed:
152 final type = settings.arguments as WalletType;
lib/src/screens/new_wallet/new_wallet_type_page.dart
+5 -2
@@ -70,7 +70,7 @@ class WalletTypeFormState extends State<WalletTypeForm> {
70 : walletTypeLightImage;
71
72 return Container(
73 - padding: EdgeInsets.only(top: 24),
73 + padding: EdgeInsets.only(top: 24, bottom: 24),
74 child: ScrollableWithBottomSection(
75 contentPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24),
76 content: Column(
@@ -107,7 +107,10 @@ class WalletTypeFormState extends State<WalletTypeForm> {
107 bottomSection: PrimaryButton(
108 onPressed: () => onTypeSelected(),
109 text: S.of(context).seed_language_next,
110 - color: Colors.green,
110 + color: Theme.of(context)
111 + .accentTextTheme
112 + .subtitle
113 + .decorationColor,
114 textColor: Colors.white,
115 isDisabled: selected == null,
116 ),
lib/src/screens/new_wallet/widgets/select_button.dart
+1 -1
@@ -16,7 +16,7 @@ class SelectButton extends StatelessWidget {
16 @override
17 Widget build(BuildContext context) {
18 final color = isSelected
19 - ? Theme.of(context).accentTextTheme.subtitle.decorationColor
19 + ? Colors.green
20 : Theme.of(context).accentTextTheme.caption.color;
21 final textColor = isSelected
22 ? Theme.of(context).accentTextTheme.headline.decorationColor
lib/src/screens/restore/wallet_restore_from_seed_form.dart
+40 -27
@@ -1,3 +1,5 @@
1 +import 'package:cake_wallet/entities/wallet_type.dart';
2 +import 'package:cake_wallet/view_model/wallet_restore_view_model.dart';
3 import 'package:flutter/cupertino.dart';
4 import 'package:flutter/material.dart';
5 import 'package:cake_wallet/utils/show_pop_up.dart';
@@ -7,12 +9,20 @@ import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
9 import 'package:cake_wallet/src/widgets/blockchain_height_widget.dart';
10
11 class WalletRestoreFromSeedForm extends StatefulWidget {
10 - WalletRestoreFromSeedForm({Key key, this.blockHeightFocusNode,
11 - this.onHeightOrDateEntered})
12 + WalletRestoreFromSeedForm(
13 + {Key key,
14 + @required this.displayLanguageSelector,
15 + @required this.displayBlockHeightSelector,
16 + @required this.type,
17 + this.blockHeightFocusNode,
18 + this.onHeightOrDateEntered})
19 : super(key: key);
20
21 + final WalletType type;
22 + final bool displayLanguageSelector;
23 + final bool displayBlockHeightSelector;
24 final FocusNode blockHeightFocusNode;
15 - final Function (bool) onHeightOrDateEntered;
25 + final Function(bool) onHeightOrDateEntered;
26
27 @override
28 WalletRestoreFromSeedFormState createState() =>
@@ -41,32 +51,35 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
51 return Container(
52 padding: EdgeInsets.only(left: 25, right: 25),
53 child: Column(children: [
44 - SeedWidget(key: seedWidgetStateKey, language: language),
45 - GestureDetector(
46 - onTap: () async {
47 - final selected = await showPopUp<String>(
48 - context: context,
49 - builder: (BuildContext context) =>
50 - SeedLanguagePicker(selected: language));
54 + SeedWidget(
55 + key: seedWidgetStateKey, language: language, type: widget.type),
56 + if (widget.displayLanguageSelector)
57 + GestureDetector(
58 + onTap: () async {
59 + final selected = await showPopUp<String>(
60 + context: context,
61 + builder: (BuildContext context) =>
62 + SeedLanguagePicker(selected: language));
63
52 - if (selected == null || selected.isEmpty) {
53 - return;
54 - }
64 + if (selected == null || selected.isEmpty) {
65 + return;
66 + }
67
56 - _changeLanguage(selected);
57 - },
58 - child: Container(
59 - color: Colors.transparent,
60 - padding: EdgeInsets.only(top: 20.0),
61 - child: IgnorePointer(
62 - child: BaseTextFormField(
63 - controller: languageController,
64 - enableInteractiveSelection: false,
65 - readOnly: true)))),
66 - BlockchainHeightWidget(
67 - focusNode: widget.blockHeightFocusNode,
68 - key: blockchainHeightKey,
69 - onHeightOrDateEntered: widget.onHeightOrDateEntered)
68 + _changeLanguage(selected);
69 + },
70 + child: Container(
71 + color: Colors.transparent,
72 + padding: EdgeInsets.only(top: 20.0),
73 + child: IgnorePointer(
74 + child: BaseTextFormField(
75 + controller: languageController,
76 + enableInteractiveSelection: false,
77 + readOnly: true)))),
78 + if (widget.displayBlockHeightSelector)
79 + BlockchainHeightWidget(
80 + focusNode: widget.blockHeightFocusNode,
81 + key: blockchainHeightKey,
82 + onHeightOrDateEntered: widget.onHeightOrDateEntered)
83 ]));
84 }
85
lib/src/screens/restore/wallet_restore_page.dart
+66 -53
@@ -25,16 +25,30 @@ class WalletRestorePage extends BasePage {
25 _pages = [],
26 _blockHeightFocusNode = FocusNode(),
27 _controller = PageController(initialPage: 0) {
28 - _pages.addAll([
29 - WalletRestoreFromSeedForm(
30 - key: walletRestoreFromSeedFormKey,
31 - blockHeightFocusNode: _blockHeightFocusNode,
32 - onHeightOrDateEntered: (value)
33 - => walletRestoreViewModel.isButtonEnabled = value),
34 - WalletRestoreFromKeysFrom(key: walletRestoreFromKeysFormKey,
35 - onHeightOrDateEntered: (value)
36 - => walletRestoreViewModel.isButtonEnabled = value)
37 - ]);
28 + walletRestoreViewModel.availableModes.forEach((mode) {
29 + switch (mode) {
30 + case WalletRestoreMode.seed:
31 + _pages.add(WalletRestoreFromSeedForm(
32 + displayBlockHeightSelector:
33 + walletRestoreViewModel.hasBlockchainHeightLanguageSelector,
34 + displayLanguageSelector:
35 + walletRestoreViewModel.hasSeedLanguageSelector,
36 + type: walletRestoreViewModel.type,
37 + key: walletRestoreFromSeedFormKey,
38 + blockHeightFocusNode: _blockHeightFocusNode,
39 + onHeightOrDateEntered: (value) =>
40 + walletRestoreViewModel.isButtonEnabled = value));
41 + break;
42 + case WalletRestoreMode.keys:
43 + _pages.add(WalletRestoreFromKeysFrom(
44 + key: walletRestoreFromKeysFormKey,
45 + onHeightOrDateEntered: (value) =>
46 + walletRestoreViewModel.isButtonEnabled = value));
47 + break;
48 + default:
49 + break;
50 + }
51 + });
52 }
53
54 @override
@@ -76,20 +90,19 @@ class WalletRestorePage extends BasePage {
90 }
91 });
92
79 - reaction((_) => walletRestoreViewModel.mode, (WalletRestoreMode mode)
80 - {
81 - walletRestoreViewModel.isButtonEnabled = false;
93 + reaction((_) => walletRestoreViewModel.mode, (WalletRestoreMode mode) {
94 + walletRestoreViewModel.isButtonEnabled = false;
95
83 - walletRestoreFromSeedFormKey.currentState.blockchainHeightKey
84 - .currentState.restoreHeightController.text = '';
85 - walletRestoreFromSeedFormKey.currentState.blockchainHeightKey
86 - .currentState.dateController.text = '';
96 + walletRestoreFromSeedFormKey.currentState.blockchainHeightKey.currentState
97 + .restoreHeightController.text = '';
98 + walletRestoreFromSeedFormKey.currentState.blockchainHeightKey.currentState
99 + .dateController.text = '';
100
88 - walletRestoreFromKeysFormKey.currentState.blockchainHeightKey
89 - .currentState.restoreHeightController.text = '';
90 - walletRestoreFromKeysFormKey.currentState.blockchainHeightKey
91 - .currentState.dateController.text = '';
92 - });
101 + walletRestoreFromKeysFormKey.currentState.blockchainHeightKey.currentState
102 + .restoreHeightController.text = '';
103 + walletRestoreFromKeysFormKey.currentState.blockchainHeightKey.currentState
104 + .dateController.text = '';
105 + });
106
107 return Column(mainAxisAlignment: MainAxisAlignment.center, children: [
108 Expanded(
@@ -100,40 +113,37 @@ class WalletRestorePage extends BasePage {
113 },
114 controller: _controller,
115 itemCount: _pages.length,
103 - itemBuilder: (_, index) => SingleChildScrollView(child: _pages[index]))),
104 - Padding(
105 - padding: EdgeInsets.only(top: 10),
106 - child: SmoothPageIndicator(
107 - controller: _controller,
108 - count: _pages.length,
109 - effect: ColorTransitionEffect(
110 - spacing: 6.0,
111 - radius: 6.0,
112 - dotWidth: 6.0,
113 - dotHeight: 6.0,
114 - dotColor: Theme.of(context).hintColor.withOpacity(0.5),
115 - activeDotColor: Theme.of(context).hintColor),
116 - )),
116 + itemBuilder: (_, index) =>
117 + SingleChildScrollView(child: _pages[index]))),
118 + if (_pages.length > 1)
119 + Padding(
120 + padding: EdgeInsets.only(top: 10),
121 + child: SmoothPageIndicator(
122 + controller: _controller,
123 + count: _pages.length,
124 + effect: ColorTransitionEffect(
125 + spacing: 6.0,
126 + radius: 6.0,
127 + dotWidth: 6.0,
128 + dotHeight: 6.0,
129 + dotColor: Theme.of(context).hintColor.withOpacity(0.5),
130 + activeDotColor: Theme.of(context).hintColor),
131 + )),
132 Padding(
133 padding: EdgeInsets.only(top: 20, bottom: 40, left: 25, right: 25),
134 child: Observer(
135 builder: (context) {
136 return LoadingPrimaryButton(
122 - onPressed: () =>
123 - walletRestoreViewModel.create(options: _credentials()),
124 - text: S.of(context).restore_recover,
125 - color: Theme
126 - .of(context)
127 - .accentTextTheme
128 - .subtitle
129 - .decorationColor,
130 - textColor: Theme
131 - .of(context)
132 - .accentTextTheme
133 - .headline
134 - .decorationColor,
135 - isLoading: walletRestoreViewModel.state is IsExecutingState,
136 - isDisabled: !walletRestoreViewModel.isButtonEnabled,);
137 + onPressed: () =>
138 + walletRestoreViewModel.create(options: _credentials()),
139 + text: S.of(context).restore_recover,
140 + color:
141 + Theme.of(context).accentTextTheme.subtitle.decorationColor,
142 + textColor:
143 + Theme.of(context).accentTextTheme.headline.decorationColor,
144 + isLoading: walletRestoreViewModel.state is IsExecutingState,
145 + isDisabled: !walletRestoreViewModel.isButtonEnabled,
146 + );
147 },
148 ))
149 ]);
@@ -145,8 +155,11 @@ class WalletRestorePage extends BasePage {
155 if (walletRestoreViewModel.mode == WalletRestoreMode.seed) {
156 credentials['seed'] = walletRestoreFromSeedFormKey
157 .currentState.seedWidgetStateKey.currentState.text;
148 - credentials['height'] = walletRestoreFromSeedFormKey
149 - .currentState.blockchainHeightKey.currentState.height;
158 +
159 + if (walletRestoreViewModel.hasBlockchainHeightLanguageSelector) {
160 + credentials['height'] = walletRestoreFromSeedFormKey
161 + .currentState.blockchainHeightKey.currentState.height;
162 + }
163 } else {
164 credentials['address'] =
165 walletRestoreFromKeysFormKey.currentState.addressController.text;
lib/src/widgets/seed_widget.dart
+7 -5
@@ -12,20 +12,21 @@ import 'package:cake_wallet/generated/i18n.dart';
12 import 'package:flutter/widgets.dart';
13
14 class SeedWidget extends StatefulWidget {
15 - SeedWidget({Key key, this.language}) : super(key: key);
15 + SeedWidget({Key key, this.language, this.type}) : super(key: key);
16
17 final String language;
18 + final WalletType type;
19
20 @override
20 - SeedWidgetState createState() => SeedWidgetState(language);
21 + SeedWidgetState createState() => SeedWidgetState(language, type);
22 }
23
24 class SeedWidgetState extends State<SeedWidget> {
24 - SeedWidgetState(String language)
25 + SeedWidgetState(String language, this.type)
26 : controller = TextEditingController(),
27 focusNode = FocusNode(),
28 words = SeedValidator.getWordList(
28 - type: WalletType.monero, language: language) {
29 + type:type, language: language) {
30 focusNode.addListener(() {
31 setState(() {
32 if (!focusNode.hasFocus && controller.text.isEmpty) {
@@ -41,6 +42,7 @@ class SeedWidgetState extends State<SeedWidget> {
42
43 final TextEditingController controller;
44 final FocusNode focusNode;
45 + final WalletType type;
46 List<String> words;
47 bool _showPlaceholder;
48
@@ -55,7 +57,7 @@ class SeedWidgetState extends State<SeedWidget> {
57 void changeSeedLanguage(String language) {
58 setState(() {
59 words = SeedValidator.getWordList(
58 - type: WalletType.monero, language: language);
60 + type: type, language: language);
61 });
62 }
63
lib/view_model/dashboard/dashboard_view_model.dart
+1
@@ -178,6 +178,7 @@ abstract class DashboardViewModelBase with Store {
178 @action
179 void _onWalletChange(WalletBase wallet) {
180 this.wallet = wallet;
181 + type = wallet.type;
182 name = wallet.name;
183 transactions.clear();
184 transactions.addAll(wallet.transactionHistory.transactions.values.map(
lib/view_model/wallet_restore_view_model.dart
+24 -5
@@ -1,3 +1,4 @@
1 +import 'package:cake_wallet/bitcoin/bitcoin_wallet_creation_credentials.dart';
2 import 'package:flutter/foundation.dart';
3 import 'package:hive/hive.dart';
4 import 'package:mobx/mobx.dart';
@@ -22,10 +23,16 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
23 WalletRestoreViewModelBase(AppStore appStore, this._walletCreationService,
24 Box<WalletInfo> walletInfoSource,
25 {@required WalletType type})
25 - : super(appStore, walletInfoSource, type: type, isRecovery: true) {
26 - isButtonEnabled = false;
26 + : availableModes = type == WalletType.monero
27 + ? WalletRestoreMode.values
28 + : [WalletRestoreMode.seed],
29 + hasSeedLanguageSelector = type == WalletType.monero,
30 + hasBlockchainHeightLanguageSelector = type == WalletType.monero,
31 + super(appStore, walletInfoSource, type: type, isRecovery: true) {
32 + isButtonEnabled =
33 + !hasSeedLanguageSelector && !hasBlockchainHeightLanguageSelector;
34 mode = WalletRestoreMode.seed;
28 - _walletCreationService.changeWalletType(type: WalletType.monero);
35 + _walletCreationService.changeWalletType(type: type);
36 }
37
38 @observable
@@ -34,6 +41,10 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
41 @observable
42 bool isButtonEnabled;
43
44 + final List<WalletRestoreMode> availableModes;
45 + final bool hasSeedLanguageSelector;
46 + final bool hasBlockchainHeightLanguageSelector;
47 +
48 final WalletCreationService _walletCreationService;
49
50 @override
@@ -44,8 +55,16 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
55 if (mode == WalletRestoreMode.seed) {
56 final seed = options['seed'] as String;
57
47 - return MoneroRestoreWalletFromSeedCredentials(
48 - name: name, height: height, mnemonic: seed, password: password);
58 + switch (type) {
59 + case WalletType.monero:
60 + return MoneroRestoreWalletFromSeedCredentials(
61 + name: name, height: height, mnemonic: seed, password: password);
62 + case WalletType.bitcoin:
63 + return BitcoinRestoreWalletFromSeedCredentials(
64 + name: name, mnemonic: seed, password: password);
65 + default:
66 + break;
67 + }
68 }
69
70 if (mode == WalletRestoreMode.keys) {