Exemplo n.º 1
0
    public async Task BuildPrivacySuggestionsAsync(Wallet wallet, TransactionInfo info, BitcoinAddress destination, BuildTransactionResult transaction, bool isFixedAmount, CancellationToken cancellationToken)
    {
        _suggestionCancellationTokenSource?.Cancel();
        _suggestionCancellationTokenSource?.Dispose();

        _suggestionCancellationTokenSource      = new(TimeSpan.FromSeconds(15));
        using CancellationTokenSource linkedCts = CancellationTokenSource.CreateLinkedTokenSource(_suggestionCancellationTokenSource.Token, cancellationToken);

        Suggestions.Clear();
        SelectedSuggestion = null;

        if (!info.IsPrivate)
        {
            Suggestions.Add(new PocketSuggestionViewModel(SmartLabel.Merge(transaction.SpentCoins.Select(x => x.GetLabels(wallet.KeyManager.MinAnonScoreTarget)))));
        }

        var loadingRing = new LoadingSuggestionViewModel();

        Suggestions.Add(loadingRing);

        var hasChange = transaction.InnerWalletOutputs.Any(x => x.ScriptPubKey != destination.ScriptPubKey);

        if (hasChange && !isFixedAmount && !info.IsPayJoin)
        {
            var suggestions =
                ChangeAvoidanceSuggestionViewModel.GenerateSuggestionsAsync(info, destination, wallet, linkedCts.Token);

            await foreach (var suggestion in suggestions)
            {
                Suggestions.Insert(Suggestions.Count - 1, suggestion);
            }
        }

        Suggestions.Remove(loadingRing);
    }
Exemplo n.º 2
0
    public async Task BuildPrivacySuggestionsAsync(Wallet wallet, TransactionInfo info, BitcoinAddress destination, BuildTransactionResult transaction, bool isFixedAmount, CancellationToken cancellationToken)
    {
        _suggestionCancellationTokenSource?.Cancel();
        _suggestionCancellationTokenSource?.Dispose();

        _suggestionCancellationTokenSource      = new(TimeSpan.FromSeconds(15));
        using CancellationTokenSource linkedCts = CancellationTokenSource.CreateLinkedTokenSource(_suggestionCancellationTokenSource.Token, cancellationToken);

        Suggestions.Clear();
        SelectedSuggestion = null;

        if (!info.IsPrivate)
        {
            Suggestions.Add(new PocketSuggestionViewModel(SmartLabel.Merge(transaction.SpentCoins.Select(x => x.GetLabels(wallet.KeyManager.MinAnonScoreTarget)))));
        }

        var loadingRing = new LoadingSuggestionViewModel();

        Suggestions.Add(loadingRing);

        var hasChange = transaction.InnerWalletOutputs.Any(x => x.ScriptPubKey != destination.ScriptPubKey);

        if (hasChange && !isFixedAmount && !info.IsPayJoin)
        {
            // Exchange rate can change substantially during computation itself.
            // Reporting up-to-date exchange rates would just confuse users.
            decimal usdExchangeRate = wallet.Synchronizer.UsdExchangeRate;

            int originalInputCount = transaction.SpentCoins.Count();
            int maxInputCount      = (int)(Math.Max(3, originalInputCount * 1.3));

            IAsyncEnumerable <ChangeAvoidanceSuggestionViewModel> suggestions =
                ChangeAvoidanceSuggestionViewModel.GenerateSuggestionsAsync(info, destination, wallet, maxInputCount, usdExchangeRate, linkedCts.Token);

            await foreach (var suggestion in suggestions)
            {
                Suggestions.Insert(Suggestions.Count - 1, suggestion);
            }
        }

        Suggestions.Remove(loadingRing);
    }
Exemplo n.º 3
0
    public async Task BuildPrivacySuggestionsAsync(Wallet wallet, TransactionInfo info, BitcoinAddress destination, BuildTransactionResult transaction, bool isFixedAmount, CancellationToken cancellationToken)
    {
        _suggestionCancellationTokenSource?.Cancel();
        _suggestionCancellationTokenSource?.Dispose();

        _suggestionCancellationTokenSource      = new(TimeSpan.FromSeconds(15));
        using CancellationTokenSource linkedCts = CancellationTokenSource.CreateLinkedTokenSource(_suggestionCancellationTokenSource.Token, cancellationToken);

        Suggestions.Clear();
        SelectedSuggestion = null;

        var loadingRing = new LoadingSuggestionViewModel();

        Suggestions.Add(loadingRing);

        var hasChange = transaction.InnerWalletOutputs.Any(x => x.ScriptPubKey != destination.ScriptPubKey);

        if (hasChange && !isFixedAmount && !info.IsPayJoin)
        {
            // Exchange rate can change substantially during computation itself.
            // Reporting up-to-date exchange rates would just confuse users.
            decimal usdExchangeRate = wallet.Synchronizer.UsdExchangeRate;

            // Only allow to create 1 more input with BnB. This accounts for the change created.
            int maxInputCount = transaction.SpentCoins.Count() + 1;

            var pockets     = wallet.GetPockets();
            var spentCoins  = transaction.SpentCoins;
            var usedPockets = pockets.Where(x => x.Coins.Any(coin => spentCoins.Contains(coin)));
            var coinsToUse  = usedPockets.SelectMany(x => x.Coins).ToImmutableArray();

            IAsyncEnumerable <ChangeAvoidanceSuggestionViewModel> suggestions =
                ChangeAvoidanceSuggestionViewModel.GenerateSuggestionsAsync(info, destination, wallet, coinsToUse, maxInputCount, usdExchangeRate, linkedCts.Token);

            await foreach (var suggestion in suggestions)
            {
                Suggestions.Insert(Suggestions.Count - 1, suggestion);
            }
        }

        Suggestions.Remove(loadingRing);
    }