Exemplo n.º 1
0
 public static string ToFriendlyString(this DequeueReason me)
 {
     return(me switch
     {
         DequeueReason.UserRequested => "User requested.",
         DequeueReason.TransactionBuilding => "Using coin for transaction building.",
         DequeueReason.Banned => "Coin is banned.",
         DequeueReason.NotEnoughFundsEnqueued => "Not enough funds enqueued.",
         DequeueReason.CoordinatorFeeChanged => "Coordinator fee changed.",
         DequeueReason.ApplicationExit => "Application is exiting.",
         DequeueReason.Spent => "Coin is spent.",
         DequeueReason.Mixing => "Coin is being mixed.",
         _ => me.ToString()
     });
 private void WalletManager_OnDequeue(object?sender, DequeueResult e)
 {
     try
     {
         foreach (var success in e.Successful.Where(x => x.Value.Any()))
         {
             DequeueReason reason = success.Key;
             if (reason == DequeueReason.ApplicationExit)
             {
                 SleepingCoins = success.Value;
             }
         }
     }
     catch (Exception ex)
     {
         Logger.LogWarning(ex);
     }
 }
Exemplo n.º 3
0
        public CoinJoinViewModel(ChaincaseWalletManager walletManager, Config config, INotificationManager notificationManager, SelectCoinsViewModel selectCoinsViewModel)
        {
            _walletManager       = walletManager;
            _config              = config;
            _notificationManager = notificationManager;
            CoinList             = selectCoinsViewModel;

            if (Disposables != null)
            {
                throw new Exception("Wallet opened before it was closed.");
            }

            Disposables = new CompositeDisposable();

            // Infer coordinator fee
            var registrableRound = _walletManager.CurrentWallet?.ChaumianClient?.State?.GetRegistrableRoundOrDefault();

            CoordinatorFeePercent = registrableRound?.State?.CoordinatorFeePercent.ToString() ?? "0.003";

            // Select most advanced coin join round
            ClientRound mostAdvancedRound = _walletManager.CurrentWallet?.ChaumianClient?.State?.GetMostAdvancedRoundOrDefault();

            if (mostAdvancedRound != default)
            {
                RoundPhaseState = new RoundPhaseState(mostAdvancedRound.State.Phase, _walletManager.CurrentWallet.ChaumianClient?.State.IsInErrorState ?? false);
                RoundTimesout   = mostAdvancedRound.State.Phase == RoundPhase.InputRegistration ? mostAdvancedRound.State.InputRegistrationTimesout : DateTimeOffset.UtcNow;
                PeersRegistered = mostAdvancedRound.State.RegisteredPeerCount;
                PeersQueued     = mostAdvancedRound.State.QueuedPeerCount;
                PeersNeeded     = mostAdvancedRound.State.RequiredPeerCount;
                RequiredBTC     = mostAdvancedRound.State.CalculateRequiredAmount();
            }
            else
            {
                RoundPhaseState = new RoundPhaseState(RoundPhase.InputRegistration, false);
                RoundTimesout   = DateTimeOffset.UtcNow;
                PeersRegistered = 0;
                PeersQueued     = 0;
                PeersNeeded     = 100;
                RequiredBTC     = Money.Parse("0.01");
            }

            // Set time left in round
            this.WhenAnyValue(x => x.RoundTimesout)
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(_ =>
            {
                TimeLeftTillRoundTimeout = TimeUntilOffset(RoundTimesout);
            });

            Task.Run(async() =>
            {
                while (_walletManager.CurrentWallet?.ChaumianClient == null)
                {
                    await Task.Delay(50).ConfigureAwait(false);
                }

                // Update view model state on chaumian client state updates
                Observable.FromEventPattern(_walletManager.CurrentWallet.ChaumianClient, nameof(_walletManager.CurrentWallet.ChaumianClient.CoinQueued))
                .Merge(Observable.FromEventPattern(_walletManager.CurrentWallet.ChaumianClient, nameof(_walletManager.CurrentWallet.ChaumianClient.OnDequeue)))
                .Merge(Observable.FromEventPattern(_walletManager.CurrentWallet.ChaumianClient, nameof(_walletManager.CurrentWallet.ChaumianClient.StateUpdated)))
                .ObserveOn(RxApp.MainThreadScheduler)
                .Subscribe(_ => UpdateStates())
                .DisposeWith(Disposables);

                // Remove notification on unconfirming status in coin join round
                Observable.FromEventPattern(_walletManager.CurrentWallet.ChaumianClient, nameof(_walletManager.CurrentWallet.ChaumianClient.OnDequeue))
                .Subscribe(pattern =>
                {
                    var e = (DequeueResult)pattern.EventArgs;
                    try
                    {
                        foreach (var success in e.Successful.Where(x => x.Value.Any()))
                        {
                            DequeueReason reason = success.Key;
                            if (reason == DequeueReason.UserRequested)
                            {
                                _notificationManager.RemoveAllPendingNotifications();
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Logger.LogWarning(ex);
                    }
                })
                .DisposeWith(Disposables);
            });

            // Update timeout label
            Observable.Interval(TimeSpan.FromSeconds(1))
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(_ =>
            {
                TimeLeftTillRoundTimeout = TimeUntilOffset(RoundTimesout);
            }).DisposeWith(Disposables);
        }
        public CoinJoinViewModel(CoinListViewModel coinList)
            : base(Locator.Current.GetService <IViewStackService>())
        {
            Global = Locator.Current.GetService <Global>();

            SetBalance();
            notificationManager = Global.NotificationManager;

            if (Disposables != null)
            {
                throw new Exception("Wallet opened before it was closed.");
            }

            Disposables = new CompositeDisposable();
            CoinList    = coinList;

            Observable
            .FromEventPattern <SmartCoin>(CoinList, nameof(CoinList.DequeueCoinsPressed))
            .Subscribe(async x => await DoDequeueAsync(x.EventArgs));

            this.WhenAnyValue(x => x.RoundTimesout)
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(_ =>
            {
                TimeSpan left            = RoundTimesout - DateTimeOffset.UtcNow;
                TimeLeftTillRoundTimeout = left > TimeSpan.Zero ? left : TimeSpan.Zero;     // Make sure cannot be less than zero.
            });

            AmountQueued = Money.Zero;

            var registrableRound = Global.Wallet.ChaumianClient.State.GetRegistrableRoundOrDefault();

            CoordinatorFeePercent = registrableRound?.State?.CoordinatorFeePercent.ToString() ?? "0.003";

            Observable.FromEventPattern(Global.Wallet.ChaumianClient, nameof(Global.Wallet.ChaumianClient.CoinQueued))
            .Merge(Observable.FromEventPattern(Global.Wallet.ChaumianClient, nameof(Global.Wallet.ChaumianClient.OnDequeue)))
            .Merge(Observable.FromEventPattern(Global.Wallet.ChaumianClient, nameof(Global.Wallet.ChaumianClient.StateUpdated)))
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(_ => UpdateStates())
            .DisposeWith(Disposables);

            Observable.FromEventPattern(Global.Wallet.ChaumianClient, nameof(Global.Wallet.ChaumianClient.OnDequeue))
            .Subscribe(pattern =>
            {
                var e = (DequeueResult)pattern.EventArgs;
                try
                {
                    foreach (var success in e.Successful.Where(x => x.Value.Any()))
                    {
                        DequeueReason reason = success.Key;
                        if (reason == DequeueReason.UserRequested)
                        {
                            notificationManager.RemoveAllPendingNotifications();
                        }
                    }
                }
                catch (Exception ex)
                {
                    Logger.LogWarning(ex);
                }
            })
            .DisposeWith(Disposables);

            ClientRound mostAdvancedRound = Global.Wallet.ChaumianClient?.State?.GetMostAdvancedRoundOrDefault();

            if (mostAdvancedRound != default)
            {
                RoundPhaseState = new RoundPhaseState(mostAdvancedRound.State.Phase, Global.Wallet.ChaumianClient?.State.IsInErrorState ?? false);
                RoundTimesout   = mostAdvancedRound.State.Phase == RoundPhase.InputRegistration ? mostAdvancedRound.State.InputRegistrationTimesout : DateTimeOffset.UtcNow;
                PeersRegistered = mostAdvancedRound.State.RegisteredPeerCount;
                PeersNeeded     = mostAdvancedRound.State.RequiredPeerCount;
            }
            else
            {
                RoundPhaseState = new RoundPhaseState(RoundPhase.InputRegistration, false);
                RoundTimesout   = DateTimeOffset.UtcNow;
                PeersRegistered = 0;
                PeersNeeded     = 100;
            }

            Observable.Interval(TimeSpan.FromSeconds(1))
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(_ =>
            {
                TimeSpan left            = RoundTimesout - DateTimeOffset.UtcNow;
                TimeLeftTillRoundTimeout = left > TimeSpan.Zero ? left : TimeSpan.Zero;     // Make sure cannot be less than zero.
            }).DisposeWith(Disposables);

            CoinJoinCommand     = ReactiveCommand.CreateFromTask <string, bool>(DoEnqueueAsync);
            ExitCoinJoinCommand = ReactiveCommand.CreateFromTask(ExitCoinJoinAsync);

            var canPromptPassword = this.WhenAnyValue(
                x => x.CoinList.SelectedAmount,
                x => x.RequiredBTC,
                (amnt, rBTC) =>
            {
                return(!(rBTC is null) && !(amnt is null) && amnt >= rBTC);
            });