dev
dart 379 lines 12.9 KB
Raw
1 import 'package:cake_wallet/bitcoin/bitcoin.dart';
2 import 'package:cake_wallet/bitcoin_cash/bitcoin_cash.dart';
3 import 'package:cake_wallet/core/generate_wallet_password.dart';
4 import 'package:cake_wallet/core/wallet_creation_service.dart';
5 import 'package:cake_wallet/di.dart';
6 import 'package:cake_wallet/dogecoin/dogecoin.dart';
7 import 'package:cake_wallet/evm/evm.dart';
8 import 'package:cake_wallet/monero/monero.dart';
9 import 'package:cake_wallet/nano/nano.dart';
10 import 'package:cake_wallet/reactions/wallet_connect.dart';
11 import 'package:cake_wallet/solana/solana.dart';
12 import 'package:cake_wallet/store/app_store.dart';
13 import 'package:cake_wallet/tron/tron.dart';
14 import 'package:cake_wallet/decred/decred.dart';
15 import 'package:cake_wallet/utils/feature_flag.dart';
16 import 'package:cake_wallet/view_model/restore/restore_mode.dart';
17 import 'package:cake_wallet/view_model/restore/restore_wallet.dart';
18 import 'package:cake_wallet/view_model/seed_settings_view_model.dart';
19 import 'package:cake_wallet/view_model/wallet_creation_vm.dart';
20 import 'package:cake_wallet/wownero/wownero.dart';
21 import 'package:cake_wallet/zano/zano.dart';
22 import 'package:cake_wallet/zcash/zcash.dart';
23 import 'package:cw_core/wallet_base.dart';
24 import 'package:cw_core/wallet_credentials.dart';
25 import 'package:cw_core/wallet_info.dart';
26 import 'package:cw_core/wallet_type.dart';
27 import 'package:mobx/mobx.dart';
28
29 part 'wallet_restore_view_model.g.dart';
30
31 class WalletRestoreViewModel = WalletRestoreViewModelBase with _$WalletRestoreViewModel;
32
33 abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
34 WalletRestoreViewModelBase(AppStore appStore, WalletCreationService walletCreationService,
35 SeedSettingsViewModel seedSettingsViewModel,
36 {required WalletType type, this.restoredWallet, this.hardwareWalletType})
37 : isButtonEnabled = restoredWallet != null,
38 hasPassphrase = false,
39 mode = restoredWallet?.restoreMode ?? WalletRestoreMode.seed,
40 super(appStore, walletCreationService, seedSettingsViewModel,
41 type: type, isRecovery: true) {
42 switch (type) {
43 case WalletType.monero:
44 availableModes = WalletRestoreMode.values;
45 break;
46 case WalletType.nano:
47 case WalletType.banano:
48 case WalletType.solana:
49 case WalletType.tron:
50 case WalletType.wownero:
51 case WalletType.haven:
52 case WalletType.ethereum:
53 case WalletType.polygon:
54 case WalletType.base:
55 case WalletType.arbitrum:
56 case WalletType.bsc:
57 case WalletType.decred:
58 case WalletType.bitcoin:
59 case WalletType.litecoin:
60 case WalletType.zcash:
61 availableModes = [WalletRestoreMode.seed, WalletRestoreMode.keys];
62 break;
63 case WalletType.bitcoinCash:
64 case WalletType.zano:
65 case WalletType.dogecoin:
66 availableModes = [WalletRestoreMode.seed];
67 break;
68 case WalletType.none:
69 availableModes = [];
70 }
71 walletCreationService.changeWalletType(type: type);
72 if (restoredWallet != null) {
73 if (restoredWallet!.restoreMode == WalletRestoreMode.seed) {
74 seedSettingsViewModel.setPassphrase(restoredWallet!.passphrase);
75 }
76 }
77 }
78
79 static const moneroSeedMnemonicLength = 25;
80 static const decredSeedMnemonicLength = 15;
81
82 late List<WalletRestoreMode> availableModes;
83 late final bool hasSeedLanguageSelector =
84 [WalletType.monero, WalletType.haven, WalletType.wownero].contains(type);
85
86 late final bool hasBlockchainHeightSelector =
87 [WalletType.monero, WalletType.haven, WalletType.wownero, WalletType.zcash].contains(type);
88
89 late final bool hasRestoreFromPrivateKey = [
90 WalletType.ethereum,
91 WalletType.polygon,
92 WalletType.base,
93 WalletType.arbitrum,
94 WalletType.bsc,
95 WalletType.nano,
96 WalletType.banano,
97 WalletType.solana,
98 WalletType.tron,
99 WalletType.zcash,
100 ].contains(type);
101
102 late final bool onlyViewKeyRestore =
103 [if (FeatureFlag.hasBitcoinViewOnly) WalletType.bitcoin, WalletType.decred].contains(type);
104
105 final RestoredWallet? restoredWallet;
106 final HardwareWalletType? hardwareWalletType;
107
108 @observable
109 WalletRestoreMode mode;
110
111 @computed
112 bool get passphraseAvailable =>
113 mode == WalletRestoreMode.seed || hardwareWalletType == HardwareWalletType.trezor;
114
115 @observable
116 bool hasPassphrase;
117
118 @observable
119 bool isButtonEnabled;
120
121 @override
122 WalletCredentials getCredentials(dynamic options) {
123 final password = walletPassword ?? generateWalletPassword();
124 String? passphrase = options['passphrase'] as String?;
125 final height = options['height'] as int? ?? 0;
126 name = options['name'] as String;
127 DerivationInfo? derivationInfo = options["derivationInfo"] as DerivationInfo?;
128
129 if (mode == WalletRestoreMode.seed) {
130 final seed = options['seed'] as String;
131 switch (type) {
132 case WalletType.monero:
133 return monero!.createMoneroRestoreWalletFromSeedCredentials(
134 name: name,
135 height: height,
136 mnemonic: seed,
137 password: password,
138 passphrase: passphrase ?? '');
139 case WalletType.bitcoin:
140 case WalletType.litecoin:
141 return bitcoin!.createBitcoinRestoreWalletFromSeedCredentials(
142 name: name,
143 mnemonic: seed,
144 password: password,
145 passphrase: passphrase,
146 derivationType: derivationInfo!.derivationType!,
147 derivationPath: derivationInfo.derivationPath!,
148 );
149
150 case WalletType.bitcoinCash:
151 return bitcoinCash!.createBitcoinCashRestoreWalletFromSeedCredentials(
152 name: name,
153 mnemonic: seed,
154 password: password,
155 passphrase: passphrase,
156 );
157 case WalletType.dogecoin:
158 return dogecoin!.createDogeCoinRestoreWalletFromSeedCredentials(
159 name: name,
160 mnemonic: seed,
161 password: password,
162 passphrase: passphrase,
163 );
164 case WalletType.nano:
165 case WalletType.banano:
166 return nano!.createNanoRestoreWalletFromSeedCredentials(
167 name: name,
168 mnemonic: seed,
169 password: password,
170 derivationType: derivationInfo!.derivationType!,
171 passphrase: passphrase,
172 );
173 case WalletType.ethereum:
174 case WalletType.polygon:
175 case WalletType.base:
176 case WalletType.arbitrum:
177 case WalletType.bsc:
178 return evm!.createEVMRestoreWalletFromSeedCredentials(
179 name: name,
180 mnemonic: seed,
181 password: password,
182 passphrase: passphrase,
183 );
184 case WalletType.solana:
185 return solana!.createSolanaRestoreWalletFromSeedCredentials(
186 name: name,
187 mnemonic: seed,
188 password: password,
189 passphrase: passphrase,
190 );
191 case WalletType.tron:
192 return tron!.createTronRestoreWalletFromSeedCredentials(
193 name: name,
194 mnemonic: seed,
195 password: password,
196 passphrase: passphrase,
197 );
198 case WalletType.wownero:
199 return wownero!.createWowneroRestoreWalletFromSeedCredentials(
200 name: name,
201 mnemonic: seed,
202 password: password,
203 passphrase: passphrase ?? '',
204 height: height,
205 );
206 case WalletType.zano:
207 return zano!.createZanoRestoreWalletFromSeedCredentials(
208 name: name,
209 password: password,
210 height: height,
211 passphrase: passphrase ?? '',
212 mnemonic: seed,
213 );
214 case WalletType.decred:
215 return decred!.createDecredRestoreWalletFromSeedCredentials(
216 name: name,
217 mnemonic: seed,
218 password: password,
219 passphrase: passphrase,
220 );
221 case WalletType.zcash:
222 return zcash!.createZcashRestoreWalletFromSeedCredentials(
223 name: name,
224 mnemonic: seed,
225 password: password,
226 passphrase: passphrase,
227 height: height,
228 network: zcashNetwork,
229 );
230 case WalletType.none:
231 case WalletType.haven:
232 break;
233 }
234 }
235
236 if (mode == WalletRestoreMode.keys) {
237 final viewKey = options['viewKey'] as String?;
238 final spendKey = options['spendKey'] as String?;
239 final scanSecret = options['scanSecret'] as String?;
240 final spendPubkey = options['spendPubkey'] as String?;
241 final address = options['address'] as String?;
242
243 switch (type) {
244 case WalletType.bitcoin:
245 return bitcoin!.createBitcoinWalletFromKeys(
246 name: name,
247 password: password,
248 xpub: viewKey!,
249 hardwareWalletType: hardwareWalletType,
250 );
251
252 case WalletType.litecoin:
253 return bitcoin!.createLitecoinWalletFromKeys(
254 name: name,
255 password: password,
256 xpub: viewKey!,
257 scanSecret: scanSecret!,
258 spendPubkey: spendPubkey!,
259 hardwareWalletType: hardwareWalletType,
260 );
261
262 case WalletType.monero:
263 return monero!.createMoneroRestoreWalletFromKeysCredentials(
264 name: name,
265 height: height,
266 spendKey: spendKey!,
267 viewKey: viewKey!,
268 address: address!,
269 password: password,
270 language: 'English',
271 hardwareWalletType: hardwareWalletType);
272
273 case WalletType.nano:
274 return nano!.createNanoRestoreWalletFromKeysCredentials(
275 name: name,
276 password: password,
277 seedKey: options['private_key'] as String,
278 derivationType: derivationInfo!.derivationType!,
279 );
280 case WalletType.ethereum:
281 case WalletType.polygon:
282 case WalletType.base:
283 case WalletType.arbitrum:
284 case WalletType.bsc:
285 return evm!.createEVMRestoreWalletFromPrivateKey(
286 name: name,
287 password: password,
288 privateKey: options['private_key'] as String,
289 );
290 case WalletType.solana:
291 return solana!.createSolanaRestoreWalletFromPrivateKey(
292 name: name,
293 password: password,
294 privateKey: options['private_key'] as String,
295 );
296 case WalletType.tron:
297 return tron!.createTronRestoreWalletFromPrivateKey(
298 name: name,
299 password: password,
300 privateKey: options['private_key'] as String,
301 );
302 case WalletType.wownero:
303 return wownero!.createWowneroRestoreWalletFromKeysCredentials(
304 name: name,
305 height: height,
306 spendKey: spendKey!,
307 viewKey: viewKey!,
308 address: address!,
309 password: password,
310 language: 'English',
311 );
312 case WalletType.decred:
313 return decred!.createDecredRestoreWalletFromPubkeyCredentials(
314 name: name,
315 password: password,
316 pubkey: viewKey!,
317 );
318 case WalletType.zcash:
319 return zcash!.createZcashRestoreWalletFromPrivateKey(
320 name: name,
321 privateKey: options['private_key'] as String,
322 password: password,
323 height: height);
324 default:
325 break;
326 }
327 }
328
329 throw Exception('Unexpected type: ${type.toString()}');
330 }
331
332 Future<List<DerivationInfo>> getDerivationInfo(dynamic credentials) async {
333 var list = <DerivationInfo>[];
334 var walletType = credentials["walletType"] as WalletType;
335 var appStore = getIt.get<AppStore>();
336
337 int? chainId;
338 if (isEVMCompatibleChain(walletType)) {
339 if (appStore.wallet != null) {
340 chainId = evm!.getSelectedChainId(appStore.wallet!);
341 }
342 chainId ??= evm!.getChainIdByWalletType(walletType);
343 }
344
345 var node = appStore.settingsStore.getCurrentNode(walletType, chainId: chainId);
346
347 switch (walletType) {
348 case WalletType.bitcoin:
349 case WalletType.litecoin:
350 String? mnemonic = credentials['seed'] as String?;
351 String? passphrase = credentials['passphrase'] as String?;
352 if (mnemonic == null) break;
353 return bitcoin!.getDerivationsFromMnemonic(
354 mnemonic: mnemonic,
355 node: node,
356 passphrase: passphrase,
357 );
358 case WalletType.nano:
359 String? mnemonic = credentials['seed'] as String?;
360 String? seedKey = credentials['private_key'] as String?;
361 return nanoUtil!.getDerivationsFromMnemonic(
362 mnemonic: mnemonic,
363 seedKey: seedKey,
364 node: node,
365 );
366 default:
367 break;
368 }
369 return list;
370 }
371
372 @override
373 Future<WalletBase> process(WalletCredentials credentials) async {
374 if (mode == WalletRestoreMode.keys) {
375 return walletCreationService.restoreFromKeys(credentials, isTestnet: useTestnet);
376 }
377 return walletCreationService.restoreFromSeed(credentials, isTestnet: useTestnet);
378 }
379 }