Пример #1
0
        public static void Notify(string message, string title, NotificationType type, Action?onClick = null, object?sender = null)
        {
            List <string> titles = new();

            if (!string.IsNullOrEmpty(title))
            {
                titles.Add(title);
            }

            string walletName = sender switch
            {
                Wallet wallet => wallet.WalletName,
                WalletViewModelBase walletViewModelBase => walletViewModelBase.WalletName,
                   _ => ""
            };

            if (!string.IsNullOrEmpty(walletName))
            {
                titles.Add(walletName);
            }

            var fullTitle = string.Join(" - ", titles);

            fullTitle = fullTitle.Substring(0, Math.Min(fullTitle.Length, MaxTitleLength));

            RxApp.MainThreadScheduler
            .Schedule(() => GetNotificationManager()
                      .Show(new Notification(fullTitle, message, type, TimeSpan.FromSeconds(DefaultNotificationTimeout), onClick)));
        }
Пример #2
0
        public LoginViewModel(WalletViewModelBase walletViewModelBase)
        {
            Title            = "Login";
            KeyManager       = walletViewModelBase.Wallet.KeyManager;
            IsPasswordNeeded = !KeyManager.IsWatchOnly;
            _walletName      = walletViewModelBase.WalletName;
            _password        = "";
            var wallet = walletViewModelBase.Wallet;

            NextCommand = ReactiveCommand.CreateFromTask(async() =>
            {
                IsPasswordIncorrect = await Task.Run(async() =>
                {
                    if (!IsPasswordNeeded)
                    {
                        return(false);
                    }

                    if (PasswordHelper.TryPassword(KeyManager, Password, out var compatibilityPasswordUsed))
                    {
                        if (compatibilityPasswordUsed is { })
                        {
                            await ShowErrorAsync(PasswordHelper.CompatibilityPasswordWarnMessage, "Compatibility password was used");
                        }

                        return(false);
                    }

                    return(true);
                });
        public WalletInfoViewModel(WalletViewModelBase walletViewModelBase)
        {
            var wallet  = walletViewModelBase.Wallet;
            var network = wallet.Network;

            IsHardwareWallet = wallet.KeyManager.IsHardwareWallet;

            SetupCancel(enableCancel: true, enableCancelOnEscape: true, enableCancelOnPressed: true);

            EnableCancel = !wallet.KeyManager.IsWatchOnly;

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

            CancelCommand = ReactiveCommand.Create(() =>
            {
                ShowSensitiveData = !ShowSensitiveData;
                ShowButtonText    = ShowSensitiveData ? "Hide sensitive data" : "Show sensitive data";
                LockIconString    = ShowSensitiveData ? "eye_hide_regular" : "eye_show_regular";
            });

            if (!wallet.KeyManager.IsWatchOnly)
            {
                var secret = PasswordHelper.GetMasterExtKey(wallet.KeyManager, wallet.Kitchen.SaltSoup(), out _);

                ExtendedMasterPrivateKey  = secret.GetWif(network).ToWif();
                ExtendedAccountPrivateKey = secret.Derive(wallet.KeyManager.AccountKeyPath).GetWif(network).ToWif();
                ExtendedMasterZprv        = secret.ToZPrv(network);
                ExtendedAccountZprv       = secret.Derive(wallet.KeyManager.AccountKeyPath).ToZPrv(network);
            }

            ExtendedAccountPublicKey = wallet.KeyManager.ExtPubKey.ToString(network);
            ExtendedAccountZpub      = wallet.KeyManager.ExtPubKey.ToZpub(network);
            AccountKeyPath           = $"m/{wallet.KeyManager.AccountKeyPath}";
            MasterKeyFingerprint     = wallet.KeyManager.MasterFingerprint.ToString();
        }
Пример #4
0
        public ReceiveViewModel(WalletViewModelBase wallet, WalletManager walletManager, BitcoinStore bitcoinStore) : base(NavigationMode.Normal)
        {
            WasabiWallet = wallet.Wallet;
            _reference   = "";
            _suggestions = GetLabels(walletManager, bitcoinStore);

            var nextCommandCanExecute =
                this.WhenAnyValue(x => x.Reference)
                .ObserveOn(RxApp.MainThreadScheduler)
                .Select(reference => !string.IsNullOrEmpty(reference));

            NextCommand = ReactiveCommand.Create(
                () =>
            {
                var newKey = WasabiWallet.KeyManager.GetNextReceiveKey(Reference, out bool minGapLimitIncreased);

                if (minGapLimitIncreased)
                {
                    int minGapLimit        = WasabiWallet.KeyManager.MinGapLimit.Value;
                    int prevMinGapLimit    = minGapLimit - 1;
                    var minGapLimitMessage = $"Minimum gap limit increased from {prevMinGapLimit} to {minGapLimit}.";
                    // TODO: notification
                }

                Navigate().To(new ReceiveAddressViewModel(newKey, WasabiWallet.Network, WasabiWallet.KeyManager.MasterFingerprint, WasabiWallet.KeyManager.IsHardwareWallet));
            },
                nextCommandCanExecute);

            ShowExistingAddressesCommand = ReactiveCommand.Create(() => Navigate().To(new ReceiveAddressesViewModel(WasabiWallet)));
        }
Пример #5
0
        protected WalletActionViewModel(WalletViewModelBase wallet)
        {
            Wallet = Guard.NotNull(nameof(wallet), wallet);

            IsEnabled = wallet.WalletState == WalletState.Started;

            wallet.WhenAnyValue(x => x.WalletState).Select(x => IsEnabled = (x == WalletState.Started));
        }
    public WalletStatsViewModel(WalletViewModelBase walletViewModelBase)
    {
        _wallet = walletViewModelBase.Wallet;

        UpdateProps();

        NextCommand = ReactiveCommand.Create(() => Navigate().Clear());
        SetupCancel(enableCancel: true, enableCancelOnEscape: true, enableCancelOnPressed: true);
    }
Пример #7
0
        public static void Notify(string message, string title, NotificationType type, Action onClick = null, object sender = null)
        {
            string walletname = sender switch
            {
                Wallet wallet => wallet.WalletName,
                WalletViewModelBase walletViewModelBase => walletViewModelBase.WalletName,
                   _ => ""
            };

            title = $"{(string.IsNullOrEmpty(title) ? "" : $"{title} - ")}{walletname}";

            title = title.Substring(0, Math.Min(title.Length, MaxTitleLength));

            RxApp.MainThreadScheduler
            .Schedule(() => GetNotificationManager()
                      .Show(new Notification(title, message, type, TimeSpan.FromSeconds(DefaultNotificationTimeout), onClick)));
        }
Пример #8
0
        public ReceiveViewModel(WalletViewModelBase wallet, WalletManager walletManager, BitcoinStore bitcoinStore) : base(NavigationMode.Normal)
        {
            WasabiWallet = wallet.Wallet;
            _reference   = "";
            _suggestions = GetLabels(walletManager, bitcoinStore);

            var nextCommandCanExecute =
                this.WhenAnyValue(x => x.Reference)
                .ObserveOn(RxApp.MainThreadScheduler)
                .Select(reference => !string.IsNullOrEmpty(reference));

            EnableCancel = true;

            EnableBack = false;

            NextCommand = ReactiveCommand.Create(OnNext, nextCommandCanExecute);

            ShowExistingAddressesCommand = ReactiveCommand.Create(OnShowExistingAddresses);
        }
    public WalletSettingsViewModel(WalletViewModelBase walletViewModelBase)
    {
        _wallet             = walletViewModelBase.Wallet;
        Title               = $"{_wallet.WalletName} - Wallet Settings";
        _preferPsbtWorkflow = _wallet.KeyManager.PreferPsbtWorkflow;
        _autoCoinJoin       = _wallet.KeyManager.AutoCoinJoin;
        IsHardwareWallet    = _wallet.KeyManager.IsHardwareWallet;
        IsWatchOnly         = _wallet.KeyManager.IsWatchOnly;
        _plebStopThreshold  = _wallet.KeyManager.PlebStopThreshold?.ToString() ?? KeyManager.DefaultPlebStopThreshold.ToString();

        SetupCancel(enableCancel: false, enableCancelOnEscape: true, enableCancelOnPressed: true);

        NextCommand = CancelCommand;

        VerifyRecoveryWordsCommand = ReactiveCommand.Create(() => Navigate().To(new VerifyRecoveryWordsViewModel(_wallet)));

        this.WhenAnyValue(x => x.PreferPsbtWorkflow)
        .Skip(1)
        .Subscribe(value =>
        {
            _wallet.KeyManager.PreferPsbtWorkflow = value;
            _wallet.KeyManager.ToFile();
            walletViewModelBase.RaisePropertyChanged(nameof(walletViewModelBase.PreferPsbtWorkflow));
        });

        this.WhenAnyValue(x => x.AutoCoinJoin)
        .ObserveOn(RxApp.TaskpoolScheduler)
        .Skip(1)
        .Subscribe(x =>
        {
            _wallet.KeyManager.AutoCoinJoin = x;
            _wallet.KeyManager.ToFile();
        });

        _minAnonScoreTarget = _wallet.KeyManager.MinAnonScoreTarget;
        _maxAnonScoreTarget = _wallet.KeyManager.MaxAnonScoreTarget;

        this.WhenAnyValue(
            x => x.MinAnonScoreTarget,
            x => x.MaxAnonScoreTarget)
        .ObserveOn(RxApp.TaskpoolScheduler)
        .Throttle(TimeSpan.FromMilliseconds(1000))
        .Skip(1)
        .Subscribe(_ => _wallet.KeyManager.SetAnonScoreTargets(MinAnonScoreTarget, MaxAnonScoreTarget));

        this.WhenAnyValue(x => x.MinAnonScoreTarget)
        .Subscribe(
            x =>
        {
            if (x >= MaxAnonScoreTarget)
            {
                MaxAnonScoreTarget = x + 1;
            }
        });

        this.WhenAnyValue(x => x.MaxAnonScoreTarget)
        .Subscribe(
            x =>
        {
            if (x <= MinAnonScoreTarget)
            {
                MinAnonScoreTarget = x - 1;
            }
        });

        this.ValidateProperty(x => x.PlebStopThreshold, ValidatePlebStopThreshold);

        this.WhenAnyValue(x => x.PlebStopThreshold)
        .Skip(1)
        .Throttle(TimeSpan.FromMilliseconds(1000))
        .ObserveOn(RxApp.TaskpoolScheduler)
        .Subscribe(x =>
        {
            if (Money.TryParse(x, out Money result) && result != _wallet.KeyManager.PlebStopThreshold)
            {
                _wallet.KeyManager.PlebStopThreshold = result;
                _wallet.KeyManager.ToFile();
            }
        });
    }
Пример #10
0
 public AdvancedWalletActionViewModel(WalletViewModelBase wallet) : base(NavigationMode.Normal)
 {
     Title = "Advanced";
 }
Пример #11
0
 public ReceiveWalletActionViewModel(WalletViewModelBase wallet) : base(wallet)
 {
     Title         = "Receive";
     SelectionMode = NavBarItemSelectionMode.Button;
 }
        public AdvancedWalletActionViewModel(WalletViewModelBase wallet) : base(NavigationMode.Normal)
        {
            Title = "Advanced";

            SelectionMode = NavBarItemSelectionMode.Selected;
        }
Пример #13
0
    public WalletSettingsViewModel(WalletViewModelBase walletViewModelBase)
    {
        var wallet = walletViewModelBase.Wallet;

        Title = $"{wallet.WalletName} - Wallet Settings";
        _preferPsbtWorkflow = wallet.KeyManager.PreferPsbtWorkflow;
        _autoCoinJoin       = wallet.KeyManager.AutoCoinJoin;
        IsHardwareWallet    = wallet.KeyManager.IsHardwareWallet;
        IsWatchOnly         = wallet.KeyManager.IsWatchOnly;

        SetupCancel(enableCancel: false, enableCancelOnEscape: true, enableCancelOnPressed: true);

        NextCommand = CancelCommand;

        VerifyRecoveryWordsCommand = ReactiveCommand.Create(() => Navigate().To(new VerifyRecoveryWordsViewModel(wallet)));

        this.WhenAnyValue(x => x.PreferPsbtWorkflow)
        .Skip(1)
        .Subscribe(value =>
        {
            wallet.KeyManager.PreferPsbtWorkflow = value;
            wallet.KeyManager.ToFile();
            walletViewModelBase.RaisePropertyChanged(nameof(walletViewModelBase.PreferPsbtWorkflow));
        });

        this.WhenAnyValue(x => x.AutoCoinJoin)
        .ObserveOn(RxApp.TaskpoolScheduler)
        .Skip(1)
        .Subscribe(x =>
        {
            wallet.KeyManager.AutoCoinJoin = x;
            wallet.KeyManager.ToFile();
        });

        _minAnonScoreTarget = wallet.KeyManager.MinAnonScoreTarget;
        _maxAnonScoreTarget = wallet.KeyManager.MaxAnonScoreTarget;

        this.WhenAnyValue(
            x => x.MinAnonScoreTarget,
            x => x.MaxAnonScoreTarget)
        .ObserveOn(RxApp.TaskpoolScheduler)
        .Throttle(TimeSpan.FromMilliseconds(1000))
        .Skip(1)
        .Subscribe(_ => wallet.KeyManager.SetAnonScoreTargets(MinAnonScoreTarget, MaxAnonScoreTarget));

        this.WhenAnyValue(x => x.MinAnonScoreTarget)
        .Subscribe(
            x =>
        {
            if (x >= MaxAnonScoreTarget)
            {
                MaxAnonScoreTarget = x + 1;
            }
        });

        this.WhenAnyValue(x => x.MaxAnonScoreTarget)
        .Subscribe(
            x =>
        {
            if (x <= MinAnonScoreTarget)
            {
                MinAnonScoreTarget = x - 1;
            }
        });
    }
Пример #14
0
    public WalletSettingsViewModel(WalletViewModelBase walletViewModelBase)
    {
        _wallet             = walletViewModelBase.Wallet;
        Title               = $"{_wallet.WalletName} - Wallet Settings";
        _preferPsbtWorkflow = _wallet.KeyManager.PreferPsbtWorkflow;
        _autoCoinJoin       = _wallet.KeyManager.AutoCoinJoin;
        IsHardwareWallet    = _wallet.KeyManager.IsHardwareWallet;
        IsWatchOnly         = _wallet.KeyManager.IsWatchOnly;
        _plebStopThreshold  = _wallet.KeyManager.PlebStopThreshold?.ToString() ?? KeyManager.DefaultPlebStopThreshold.ToString();

        SetupCancel(enableCancel: false, enableCancelOnEscape: true, enableCancelOnPressed: true);

        NextCommand = CancelCommand;

        VerifyRecoveryWordsCommand = ReactiveCommand.Create(() => Navigate().To(new VerifyRecoveryWordsViewModel(_wallet)));

        this.WhenAnyValue(x => x.PreferPsbtWorkflow)
        .Skip(1)
        .Subscribe(value =>
        {
            _wallet.KeyManager.PreferPsbtWorkflow = value;
            _wallet.KeyManager.ToFile();
            walletViewModelBase.RaisePropertyChanged(nameof(walletViewModelBase.PreferPsbtWorkflow));
        });

        SetAutoCoinJoin = ReactiveCommand.CreateFromTask(async() =>
        {
            if (_wallet.KeyManager.IsCoinjoinProfileSelected)
            {
                AutoCoinJoin = !AutoCoinJoin;
            }
            else
            {
                await NavigateDialogAsync(new CoinJoinProfilesViewModel(_wallet.KeyManager, false), NavigationTarget.DialogScreen);
            }

            if (_wallet.KeyManager.IsCoinjoinProfileSelected)
            {
                _wallet.KeyManager.AutoCoinJoin = AutoCoinJoin;
                _wallet.KeyManager.ToFile();
            }
            else
            {
                AutoCoinJoin = false;
            }
        });

        SelectCoinjoinProfileCommand = ReactiveCommand.CreateFromTask(SelectCoinjoinProfileAsync);

        _anonScoreTarget = _wallet.KeyManager.AnonScoreTarget;

        this.WhenAnyValue(x => x.AnonScoreTarget)
        .ObserveOn(RxApp.TaskpoolScheduler)
        .Throttle(TimeSpan.FromMilliseconds(1000))
        .Skip(1)
        .Subscribe(_ => _wallet.KeyManager.SetAnonScoreTarget(AnonScoreTarget));

        this.ValidateProperty(x => x.PlebStopThreshold, ValidatePlebStopThreshold);

        this.WhenAnyValue(x => x.PlebStopThreshold)
        .Skip(1)
        .Throttle(TimeSpan.FromMilliseconds(1000))
        .ObserveOn(RxApp.TaskpoolScheduler)
        .Subscribe(x =>
        {
            if (Money.TryParse(x, out Money result) && result != _wallet.KeyManager.PlebStopThreshold)
            {
                _wallet.KeyManager.PlebStopThreshold = result;
                _wallet.KeyManager.ToFile();
            }
        });
    }
Пример #15
0
 public CoinJoinWalletActionViewModel(WalletViewModelBase wallet) : base(wallet)
 {
     Title = "CoinJoin";
 }
Пример #16
0
 public SendWalletActionViewModel(WalletViewModelBase wallet) : base(wallet)
 {
     Title = "Send";
 }
Пример #17
0
        public CoinJoinWalletActionViewModel(WalletViewModelBase wallet) : base(NavigationMode.Normal)
        {
            Title = "CoinJoin";

            SelectionMode = NavBarItemSelectionMode.Selected;
        }
Пример #18
0
 public CoinJoinWalletActionViewModel(WalletViewModelBase wallet) : base(NavigationMode.Normal)
 {
     Title = "CoinJoin";
 }
Пример #19
0
 public AdvancedWalletActionViewModel(WalletViewModelBase wallet)
 {
     Title = "Advanced";
 }