private async Task TryRewriteTableAsync() { try { var historyBuilder = new TransactionHistoryBuilder(_walletManager.CurrentWallet); var txRecordList = await Task.Run(historyBuilder.BuildHistorySummary); var tis = txRecordList.Select(txr => new TransactionInfo { DateTime = txr.DateTime.ToLocalTime(), Confirmed = txr.Height.Type == HeightType.Chain, Confirmations = txr.Height.Type == HeightType.Chain ? (int)_bitcoinStore.SmartHeaderChain.TipHeight - txr.Height.Value + 1 : 0, AmountBtc = $"{txr.Amount.ToString(fplus: true, trimExcessZero: true)}", Label = txr.Label, BlockHeight = txr.Height.Type == HeightType.Chain ? txr.Height.Value : 0, TransactionId = txr.TransactionId.ToString() }); Transactions?.Clear(); var trs = tis.Select(ti => new TransactionViewModel(ti)); Transactions = new ObservableCollection <TransactionViewModel>(trs.OrderByDescending(t => t.DateString)); _uiConfig.Transactions = tis.ToArray(); _uiConfig.ToFile(); // write to file once height is the highest } catch (Exception ex) { Logger.LogError(ex); } }
public async Task SetPasswordAsync(string password) { Mnemonic seedWords = null; await Task.Run(() => { // Here we are not letting anything that will be autocorrected later. // Generate wallet with password exactly as entered for compatibility. PasswordHelper.Guard(password); string walletFilePath = Path.Combine(_walletManager.WalletDirectories.WalletsDir, $"{_config.Network}.json"); KeyManager.CreateNew(out seedWords, password, walletFilePath); }); await _storage.SetSeedWords(password, seedWords.ToString()); // this should not be a config _uiConfig.HasSeed = true; _uiConfig.ToFile(); }
// Use an intermediate key. This way main password can be changed // out for a global pin in multi-wallet. Store it with biometrics // for access without a static password. public async Task <byte[]> GetOrGenerateIntermediateKey(string password) { byte[] iKey = await GetIntermediateKey(password); if (iKey is null) { // default one at cryptographically-secure pseudo-random iKey = AesThenHmac.NewKey(); } // store it encrypted under the password byte[] encIKey = AesThenHmac.EncryptWithPassword(iKey, password); string encIKeyString = Convert.ToBase64String(encIKey); await _hsm.SetAsync(I_KEY_LOC, encIKeyString); _uiConfig.HasIntermediateKey = true; _uiConfig.ToFile(); return(iKey); }
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 void SetIsBackedUp() { _uiConfig.IsBackedUp = true; _uiConfig.ToFile(); // successfully backed up! }
public WalletViewModel(Wallet wallet) : base(wallet) { Disposables = Disposables is null ? new CompositeDisposable() : throw new NotSupportedException($"Cannot open {GetType().Name} before closing it."); Actions = new ObservableCollection <ViewModelBase>(); UiConfig = Locator.Current.GetService <Global>().UiConfig; WalletManager = Locator.Current.GetService <Global>().WalletManager; LurkingWifeModeCommand = ReactiveCommand.Create(() => { UiConfig.LurkingWifeMode = !UiConfig.LurkingWifeMode; UiConfig.ToFile(); }); LurkingWifeModeCommand.ThrownExceptions .ObserveOn(RxApp.TaskpoolScheduler) .Subscribe(ex => Logger.LogError(ex)); Observable.Merge( Observable.FromEventPattern(Wallet.TransactionProcessor, nameof(Wallet.TransactionProcessor.WalletRelevantTransactionProcessed)).Select(_ => Unit.Default)) .Throttle(TimeSpan.FromSeconds(0.1)) .Merge(UiConfig.WhenAnyValue(x => x.LurkingWifeMode).Select(_ => Unit.Default)) .ObserveOn(RxApp.MainThreadScheduler) .Subscribe(_ => { try { Money balance = Wallet.Coins.TotalAmount(); Title = $"{WalletName} ({(UiConfig.LurkingWifeMode ? "#########" : balance.ToString(false, true))} BTC)"; } catch (Exception ex) { Logger.LogError(ex); } }) .DisposeWith(Disposables); // If hardware wallet or not watch only wallet then we need the Send tab. if (Wallet.KeyManager.IsHardwareWallet || !Wallet.KeyManager.IsWatchOnly) { SendTab = new SendTabViewModel(Wallet); Actions.Add(SendTab); } ReceiveTab = new ReceiveTabViewModel(Wallet); CoinjoinTab = new CoinJoinTabViewModel(Wallet); HistoryTab = new HistoryTabViewModel(Wallet); var advancedAction = new WalletAdvancedViewModel(); InfoTab = new WalletInfoViewModel(Wallet); BuildTab = new BuildTabViewModel(Wallet); Actions.Add(ReceiveTab); Actions.Add(CoinjoinTab); Actions.Add(HistoryTab); Actions.Add(advancedAction); advancedAction.Items.Add(InfoTab); advancedAction.Items.Add(BuildTab); }