public ConfirmRecoveryWordsViewModel(NavigationStateViewModel navigationState, List <RecoveryWordViewModel> mnemonicWords, KeyManager keyManager, WalletManager walletManager)
            : base(navigationState, NavigationTarget.DialogScreen)
        {
            _confirmationWordsSourceList = new SourceList <RecoveryWordViewModel>();

            var finishCommandCanExecute =
                _confirmationWordsSourceList
                .Connect()
                .ObserveOn(RxApp.MainThreadScheduler)
                .WhenValueChanged(x => x.IsConfirmed)
                .Select(x => !_confirmationWordsSourceList.Items.Any(x => !x.IsConfirmed));

            NextCommand = ReactiveCommand.Create(
                () =>
            {
                walletManager.AddWallet(keyManager);
                ClearNavigation(NavigationTarget.DialogScreen);
            },
                finishCommandCanExecute);

            CancelCommand = ReactiveCommand.Create(() => ClearNavigation(NavigationTarget.DialogScreen));

            _confirmationWordsSourceList
            .Connect()
            .ObserveOn(RxApp.MainThreadScheduler)
            .OnItemAdded(x => x.Reset())
            .Sort(SortExpressionComparer <RecoveryWordViewModel> .Ascending(x => x.Index))
            .Bind(out _confirmationWords)
            .Subscribe();

            // Select 4 random words to confirm.
            _confirmationWordsSourceList.AddRange(mnemonicWords.OrderBy(x => new Random().NextDouble()).Take(4));
        }
Пример #2
0
        public void AddWalletTest()
        {
            WalletManager walletManager = new WalletManager();
            var           result        = walletManager.AddWallet("Test Wallet", 5.1m);

            Assert.AreEqual(2, result);
        }
Пример #3
0
        public async Task GenerateWalletAsync(string walletName)
        {
            var selectedDevice = SelectedDevice;

            try
            {
                if (selectedDevice?.Fingerprint is null)
                {
                    throw new Exception("Cannot be null.");
                }

                await StopDetectionAsync();

                var fingerPrint = (HDFingerprint)selectedDevice.Fingerprint;
                using var cts = new CancellationTokenSource(TimeSpan.FromMinutes(3));
                var extPubKey = await Client.GetXpubAsync(
                    selectedDevice.Model,
                    selectedDevice.Path,
                    KeyManager.DefaultAccountKeyPath,
                    cts.Token).ConfigureAwait(false);

                var path = WalletManager.WalletDirectories.GetWalletFilePaths(walletName).walletFilePath;

                var km = KeyManager.CreateNewHardwareWalletWatchOnly(fingerPrint, extPubKey, path);
                WalletManager.AddWallet(km);
            }
            catch (Exception)
            {
                StartDetection();
                throw;
            }
        }
Пример #4
0
        public ConfirmRecoveryWordsViewModel(IScreen screen, List <RecoveryWordViewModel> mnemonicWords, KeyManager keyManager, WalletManager walletManager)
        {
            HostScreen = screen;

            _confirmationWordsSourceList = new SourceList <RecoveryWordViewModel>();

            var finishCommandCanExecute =
                _confirmationWordsSourceList
                .Connect()
                .ObserveOn(RxApp.MainThreadScheduler)
                .WhenValueChanged(x => x.IsConfirmed)
                .Select(x => !_confirmationWordsSourceList.Items.Any(x => !x.IsConfirmed));

            FinishCommand = ReactiveCommand.Create(
                () =>
            {
                walletManager.AddWallet(keyManager);
                screen.Router.NavigationStack.Clear();
            },
                finishCommandCanExecute);

            _confirmationWordsSourceList
            .Connect()
            .ObserveOn(RxApp.MainThreadScheduler)
            .OnItemAdded(x => x.Reset())
            .Sort(SortExpressionComparer <RecoveryWordViewModel> .Ascending(x => x.Index))
            .Bind(out _confirmationWords)
            .Subscribe();

            SelectRandomConfirmationWords(mnemonicWords);
        }
Пример #5
0
        public ConfirmRecoveryWordsViewModel(List <RecoveryWordViewModel> mnemonicWords, KeyManager keyManager, WalletManager walletManager)
        {
            var confirmationWordsSourceList = new SourceList <RecoveryWordViewModel>();

            var finishCommandCanExecute =
                confirmationWordsSourceList
                .Connect()
                .ObserveOn(RxApp.MainThreadScheduler)
                .WhenValueChanged(x => x.IsConfirmed)
                .Select(_ => confirmationWordsSourceList.Items.All(x => x.IsConfirmed));

            NextCommand = ReactiveCommand.Create(
                () =>
            {
                walletManager.AddWallet(keyManager);

                Navigate().To(new AddedWalletPageViewModel(keyManager.WalletName, WalletType.Normal));
            },
                finishCommandCanExecute);

            CancelCommand = ReactiveCommand.Create(() => Navigate().Clear());

            confirmationWordsSourceList
            .Connect()
            .ObserveOn(RxApp.MainThreadScheduler)
            .OnItemAdded(x => x.Reset())
            .Sort(SortExpressionComparer <RecoveryWordViewModel> .Ascending(x => x.Index))
            .Bind(out _confirmationWords)
            .Subscribe();

            // Select 4 random words to confirm.
            confirmationWordsSourceList.AddRange(mnemonicWords.OrderBy(_ => new Random().NextDouble()).Take(4));
        }
Пример #6
0
        public void GetWalletsTest()
        {
            WalletManager walletManager = new WalletManager();
            var           result        = walletManager.AddWallet("Test Wallet", 5.1m);

            Assert.AreEqual(2, result);

            var walletList = walletManager.GetWallets();

            CollectionAssert.AllItemsAreUnique(walletList);
        }
Пример #7
0
        private void OnNext(WalletManager walletManager, KeyManager keyManager)
        {
            walletManager.AddWallet(keyManager);

            Navigate().Clear();

            var navBar = NavigationManager.Get <NavBarViewModel>();

            var wallet = navBar?.Items.OfType <WalletViewModelBase>().FirstOrDefault(x => x.WalletName == WalletName);

            if (wallet is { } && navBar is { })
        public AddedWalletPageViewModel(WalletManager walletManager, KeyManager keyManager)
        {
            KeyManager = keyManager;
            WalletName = keyManager.WalletName;

            NextCommand = ReactiveCommand.Create(
                () =>
            {
                walletManager.AddWallet(keyManager);

                Navigate().Clear();

                var navBar = NavigationManager.Get <NavBarViewModel>();

                var wallet = navBar?.Items.OfType <WalletViewModelBase>().FirstOrDefault(x => x.WalletName == WalletName);

                if (wallet is { } && navBar is { })
Пример #9
0
        public void RemoveWalletTest()
        {
            WalletManager walletManager = new WalletManager();
            var           output        = walletManager.AddWallet("Test Wallet", 5.1m);

            Assert.AreEqual(2, output);

            var walletList = walletManager.GetWallets();

            CollectionAssert.AllItemsAreUnique(walletList);

            var wallet = walletList.Last();
            var result = walletManager.RemoveWallet(wallet);

            Assert.AreEqual(1, result);
            CollectionAssert.DoesNotContain(walletList, wallet);
        }
        private void RecoverWallet(WalletManagerViewModel owner)
        {
            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 = 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
            {
                var minGapLimit = int.Parse(MinGapLimit);
                var keyPath     = KeyPath.Parse(AccountKeyPath);

                try
                {
                    var mnemonic = new Mnemonic(MnemonicWords);
                    var km       = KeyManager.Recover(mnemonic, Password, filePath: null, keyPath, minGapLimit);
                    km.SetNetwork(Global.Network);
                    km.SetFilePath(walletFilePath);
                    WalletManager.AddWallet(km);

                    NotificationHelpers.Success("Wallet was recovered.");

                    owner.SelectLoadWallet(km);
                }
                catch (Exception ex)
                {
                    Logger.LogError(ex);
                    NotificationHelpers.Error(ex.ToUserFriendlyString());
                }
            }
        }
Пример #11
0
        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();
        }
Пример #12
0
        public RecoverWalletViewModel(WalletManagerViewModel owner) : base("Recover Wallet")
        {
            Global        = Locator.Current.GetService <Global>();
            WalletManager = Global.WalletManager;

            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 = 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);
                        WalletManager.AddWallet(km);

                        NotificationHelpers.Success("Wallet was recovered.");

                        owner.SelectLoadWallet(km);
                    }
                    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));
        }