public bool LoadWallet() { SeedWords = Guard.Correct(SeedWords); Password = Guard.Correct(Password); // Do not let whitespaces to the beginning and to the end. string walletFilePath = Path.Combine(Global.WalletManager.WalletDirectories.WalletsDir, $"{Global.Network}.json"); bool isLoadSuccessful; try { KeyPath.TryParse(ACCOUNT_KEY_PATH, out KeyPath keyPath); var mnemonic = new Mnemonic(SeedWords); var km = KeyManager.Recover(mnemonic, Password, filePath: null, keyPath, MIN_GAP_LIMIT); km.SetNetwork(Global.Network); km.SetFilePath(walletFilePath); Global.WalletManager.AddWallet(km); Hsm.SetAsync($"{Global.Network}-seedWords", SeedWords.ToString()); // PROMPT Global.UiConfig.HasSeed = true; Global.UiConfig.ToFile(); isLoadSuccessful = true; } catch (Exception ex) { Logger.LogError(ex); isLoadSuccessful = false; } return(isLoadSuccessful); }
protected override ValidationResult IsValid(object value, ValidationContext validationContext) { var str = value as string; if (string.IsNullOrWhiteSpace(str)) { return(ValidationResult.Success); } if (KeyPath.TryParse(str, out _)) { return(ValidationResult.Success); } else { return(new ValidationResult("Invalid keypath")); } }
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { if (reader.TokenType == JsonToken.Null) { return(null); } if (typeof(KeyPath).GetTypeInfo().IsAssignableFrom(objectType.GetTypeInfo())) { if (KeyPath.TryParse(reader.Value.ToString(), out var k)) { return(k); } throw new JsonObjectException("Invalid key path", reader); } else { if (RootedKeyPath.TryParse(reader.Value.ToString(), out var k)) { return(k); } throw new JsonObjectException("Invalid rooted key path", reader); } }
public async Task LoadWallet() { SeedWords = Guard.Correct(SeedWords); Password = Guard.Correct(Password); // Do not let whitespaces to the beginning and to the end. string walletFilePath = Path.Combine(_walletManager.WalletDirectories.WalletsDir, $"{_config.Network}.json"); Mnemonic mnemonic = null; await Task.Run(() => { KeyPath.TryParse(ACCOUNT_KEY_PATH, out KeyPath keyPath); mnemonic = new Mnemonic(SeedWords); var km = KeyManager.Recover(mnemonic, Password, filePath: null, keyPath, MIN_GAP_LIMIT); km.SetNetwork(_config.Network); km.SetFilePath(walletFilePath); _walletManager.AddWallet(km); }); await _storage.SetSeedWords(Password, mnemonic.ToString()); _uiConfig.HasSeed = true; _uiConfig.ToFile(); }
public RecoverWalletViewModel(WalletManagerViewModel owner) : base("Recover Wallet") { MnemonicWords = ""; RecoverCommand = ReactiveCommand.Create(() => { WalletName = Guard.Correct(WalletName); MnemonicWords = Guard.Correct(MnemonicWords); Password = Guard.Correct(Password); // Don't let whitespaces to the beginning and to the end. string walletFilePath = Path.Combine(Global.WalletsDir, $"{WalletName}.json"); if (string.IsNullOrWhiteSpace(WalletName)) { ValidationMessage = $"The name {WalletName} is not valid."; } else if (File.Exists(walletFilePath)) { ValidationMessage = $"The name {WalletName} is already taken."; } else if (string.IsNullOrWhiteSpace(MnemonicWords)) { ValidationMessage = "Recovery Words were not supplied."; } else if (string.IsNullOrWhiteSpace(AccountKeyPath)) { ValidationMessage = "The account key path is not valid."; } else if (MinGapLimit < KeyManager.AbsoluteMinGapLimit) { ValidationMessage = $"Min Gap Limit cannot be smaller than {KeyManager.AbsoluteMinGapLimit}."; } else if (MinGapLimit > 1_000_000) { ValidationMessage = $"Min Gap Limit cannot be larger than {1_000_000}."; } else if (!KeyPath.TryParse(AccountKeyPath, out KeyPath keyPath)) { ValidationMessage = "The account key path is not a valid derivation path."; } else { try { var mnemonic = new Mnemonic(MnemonicWords); KeyManager.Recover(mnemonic, Password, walletFilePath, keyPath, MinGapLimit); owner.SelectLoadWallet(); } catch (Exception ex) { ValidationMessage = ex.ToTypeMessageString(); Logger.LogError <LoadWalletViewModel>(ex); } } }); this.WhenAnyValue(x => x.MnemonicWords).Subscribe(x => UpdateSuggestions(x)); this.WhenAnyValue(x => x.Password).Subscribe(x => { try { if (x.NotNullAndNotEmpty()) { char lastChar = x.Last(); if (lastChar == '\r' || lastChar == '\n') // If the last character is cr or lf then act like it'd be a sign to do the job. { Password = x.TrimEnd('\r', '\n'); } } } catch (Exception ex) { Logger.LogTrace(ex); } }); this.WhenAnyValue(x => x.CaretIndex).Subscribe(_ => { if (CaretIndex != MnemonicWords.Length) { CaretIndex = MnemonicWords.Length; } }); _suggestions = new ObservableCollection <SuggestionViewModel>(); }
public RecoverWalletViewModel(WalletManagerViewModel owner) : base("Recover Wallet") { Global = Locator.Current.GetService <Global>(); MnemonicWords = ""; RecoverCommand = ReactiveCommand.Create(() => { WalletName = Guard.Correct(WalletName); MnemonicWords = Guard.Correct(MnemonicWords); Password = Guard.Correct(Password); // Do not let whitespaces to the beginning and to the end. string walletFilePath = Global.WalletManager.WalletDirectories.GetWalletFilePaths(WalletName).walletFilePath; if (string.IsNullOrWhiteSpace(WalletName)) { NotificationHelpers.Error("Invalid wallet name."); } else if (File.Exists(walletFilePath)) { NotificationHelpers.Error("Wallet name is already taken."); } else if (string.IsNullOrWhiteSpace(MnemonicWords)) { NotificationHelpers.Error("Recovery Words were not supplied."); } else if (string.IsNullOrWhiteSpace(AccountKeyPath)) { NotificationHelpers.Error("The account key path is not valid."); } else if (MinGapLimit < KeyManager.AbsoluteMinGapLimit) { NotificationHelpers.Error($"Min Gap Limit cannot be smaller than {KeyManager.AbsoluteMinGapLimit}."); } else if (MinGapLimit > 1_000_000) { NotificationHelpers.Error($"Min Gap Limit cannot be larger than {1_000_000}."); } else if (!KeyPath.TryParse(AccountKeyPath, out KeyPath keyPath)) { NotificationHelpers.Error("The account key path is not a valid derivation path."); } else { try { var mnemonic = new Mnemonic(MnemonicWords); var km = KeyManager.Recover(mnemonic, Password, filePath: null, keyPath, MinGapLimit); km.SetNetwork(Global.Network); km.SetFilePath(walletFilePath); km.ToFile(); NotificationHelpers.Success("Wallet was recovered."); owner.SelectLoadWallet(); } catch (Exception ex) { Logger.LogError(ex); NotificationHelpers.Error(ex.ToUserFriendlyString()); } } }); this.WhenAnyValue(x => x.MnemonicWords).Subscribe(UpdateSuggestions); _suggestions = new ObservableCollection <SuggestionViewModel>(); RecoverCommand.ThrownExceptions .ObserveOn(RxApp.TaskpoolScheduler) .Subscribe(ex => Logger.LogError(ex)); }
public async Task InitSeedWords(string password) { string wordString = null; KeyManager keyManager = null; try { // ensure correct pw PasswordHelper.Guard(password); string walletFilePath = Path.Combine(_walletManager.WalletDirectories.WalletsDir, $"{_config.Network}.json"); await Task.Run(() => { keyManager = KeyManager.FromFile(walletFilePath); keyManager.GetMasterExtKey(password ?? ""); }); await Task.Run(async() => { // this next line doesn't really run async :/ wordString = await _storage.GetSeedWords(password); if (wordString is null) { throw new KeyNotFoundException(); } }); } catch (SecurityException e) { // toss bad password to UI throw e; } // KeyNotFoundException || ArgumentException catch { // try migrate from the legacy system var seedWords = await _hsm.GetAsync(LegacyWordsLoc); if (string.IsNullOrEmpty(seedWords)) { // check if corrupted and show message throw new InvalidOperationException("Try again if you cancelled the biometric authentication. Otherwise, there are no seed words saved. Please back up using \"Export Wallet File\""); } // check if words match the wallet file KeyManager legacyKM = null; await Task.Run(() => { KeyPath.TryParse(ACCOUNT_KEY_PATH, out KeyPath keyPath); var mnemonic = new Mnemonic(seedWords); legacyKM = KeyManager.Recover(mnemonic, password, filePath: null, keyPath, MIN_GAP_LIMIT); }); if (legacyKM.EncryptedSecret != keyManager.EncryptedSecret) { throw new InvalidOperationException("Corrupt seed words. Please back up using \"Export Wallet File\" instead."); } await _storage.SetSeedWords(password, seedWords); wordString = seedWords; } finally { SeedWords = wordString?.Split(' ').ToList(); } }
public RecoverWalletViewModel(WalletManagerViewModel owner) : base("Recover Wallet") { Global = owner.Global; MnemonicWords = ""; RecoverCommand = ReactiveCommand.Create(() => { WalletName = Guard.Correct(WalletName); MnemonicWords = Guard.Correct(MnemonicWords); Password = Guard.Correct(Password); // Do not let whitespaces to the beginning and to the end. string walletFilePath = Path.Combine(Global.WalletsDir, $"{WalletName}.json"); if (string.IsNullOrWhiteSpace(WalletName)) { ValidationMessage = $"The name {WalletName} is not valid."; } else if (File.Exists(walletFilePath)) { ValidationMessage = $"The name {WalletName} is already taken."; } else if (string.IsNullOrWhiteSpace(MnemonicWords)) { ValidationMessage = "Recovery Words were not supplied."; } else if (string.IsNullOrWhiteSpace(AccountKeyPath)) { ValidationMessage = "The account key path is not valid."; } else if (MinGapLimit < KeyManager.AbsoluteMinGapLimit) { ValidationMessage = $"Min Gap Limit cannot be smaller than {KeyManager.AbsoluteMinGapLimit}."; } else if (MinGapLimit > 1_000_000) { ValidationMessage = $"Min Gap Limit cannot be larger than {1_000_000}."; } else if (!KeyPath.TryParse(AccountKeyPath, out KeyPath keyPath)) { ValidationMessage = "The account key path is not a valid derivation path."; } else { try { var mnemonic = new Mnemonic(MnemonicWords); KeyManager.Recover(mnemonic, Password, walletFilePath, keyPath, MinGapLimit); owner.SelectLoadWallet(); } catch (Exception ex) { ValidationMessage = ex.ToTypeMessageString(); Logger.LogError(ex); } } }); this.WhenAnyValue(x => x.MnemonicWords).Subscribe(UpdateSuggestions); _suggestions = new ObservableCollection <SuggestionViewModel>(); }