mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2025-02-27 16:44:53 +01:00
* Add dashboard and chart basics * More widgets * Make widgets responsive * Layout dashboard * Prepare ExplorerClient * Switch to Chartist * Dynamic data for store numbers and recent transactions tiles * Dynamic data for recent invoices tile * Improvements * Plug NBXPlorer DB * Properly filter by code * Reorder cheat mode button * AJAX update for graph data * Fix create invoice button * Retry connection on transient issues * App Top Items stats * Design updates * App Sales stats * Add points for weekly histogram, set last point to current balance Co-authored-by: nicolas.dorier <nicolas.dorier@gmail.com>
116 lines
4.8 KiB
C#
116 lines
4.8 KiB
C#
using System;
|
|
using System.Linq;
|
|
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
using System.Threading.Tasks;
|
|
using BTCPayServer.Abstractions.Extensions;
|
|
using BTCPayServer.Data;
|
|
using BTCPayServer.Services;
|
|
using BTCPayServer.Models.StoreViewModels;
|
|
using BTCPayServer.Services.Stores;
|
|
using Dapper;
|
|
using BTCPayServer.Services.Wallets;
|
|
using Microsoft.AspNetCore.Identity;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using NBXplorer.Client;
|
|
using static BTCPayServer.Components.StoreRecentTransactions.StoreRecentTransactionsViewModel;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using NBitcoin;
|
|
|
|
namespace BTCPayServer.Components.StoreRecentTransactions;
|
|
|
|
public class StoreRecentTransactions : ViewComponent
|
|
{
|
|
private const string CryptoCode = "BTC";
|
|
private readonly StoreRepository _storeRepo;
|
|
private readonly ApplicationDbContextFactory _dbContextFactory;
|
|
private readonly BTCPayWalletProvider _walletProvider;
|
|
|
|
public BTCPayNetworkProvider NetworkProvider { get; }
|
|
public NBXplorerConnectionFactory ConnectionFactory { get; }
|
|
|
|
public StoreRecentTransactions(
|
|
StoreRepository storeRepo,
|
|
BTCPayNetworkProvider networkProvider,
|
|
NBXplorerConnectionFactory connectionFactory,
|
|
BTCPayWalletProvider walletProvider,
|
|
ApplicationDbContextFactory dbContextFactory)
|
|
{
|
|
_storeRepo = storeRepo;
|
|
NetworkProvider = networkProvider;
|
|
ConnectionFactory = connectionFactory;
|
|
_walletProvider = walletProvider;
|
|
_dbContextFactory = dbContextFactory;
|
|
}
|
|
|
|
|
|
public async Task<IViewComponentResult> InvokeAsync(StoreData store)
|
|
{
|
|
var walletId = new WalletId(store.Id, CryptoCode);
|
|
var derivationSettings = store.GetDerivationSchemeSettings(NetworkProvider, walletId.CryptoCode);
|
|
var transactions = new List<StoreRecentTransactionViewModel>();
|
|
if (derivationSettings?.AccountDerivation is not null)
|
|
{
|
|
if (ConnectionFactory.Available)
|
|
{
|
|
var wallet_id = derivationSettings.GetNBXWalletId();
|
|
await using var conn = await ConnectionFactory.OpenConnection();
|
|
var rows = await conn.QueryAsync(
|
|
"SELECT t.tx_id, t.seen_at, to_btc(balance_change::NUMERIC) balance_change, (t.blk_id IS NOT NULL) confirmed " +
|
|
"FROM get_wallets_recent(@wallet_id, @code, @interval, 5, 0) " +
|
|
"JOIN txs t USING (code, tx_id) " +
|
|
"ORDER BY seen_at DESC;",
|
|
new
|
|
{
|
|
wallet_id,
|
|
code = CryptoCode,
|
|
interval = TimeSpan.FromDays(31)
|
|
});
|
|
var network = derivationSettings.Network;
|
|
foreach (var r in rows)
|
|
{
|
|
var seenAt = new DateTimeOffset(((DateTime)r.seen_at));
|
|
var balanceChange = new Money((decimal)r.balance_change, MoneyUnit.BTC);
|
|
transactions.Add(new StoreRecentTransactionViewModel()
|
|
{
|
|
Timestamp = seenAt,
|
|
Id = r.tx_id,
|
|
Balance = balanceChange.ShowMoney(network),
|
|
IsConfirmed = r.confirmed,
|
|
Link = string.Format(CultureInfo.InvariantCulture, network.BlockExplorerLink, r.tx_id),
|
|
Positive = balanceChange.GetValue(network) >= 0,
|
|
});
|
|
}
|
|
}
|
|
else
|
|
{
|
|
var network = derivationSettings.Network;
|
|
var wallet = _walletProvider.GetWallet(network);
|
|
var allTransactions = await wallet.FetchTransactions(derivationSettings.AccountDerivation);
|
|
transactions = allTransactions.UnconfirmedTransactions.Transactions
|
|
.Concat(allTransactions.ConfirmedTransactions.Transactions).ToArray()
|
|
.OrderByDescending(t => t.Timestamp)
|
|
.Take(5)
|
|
.Select(tx => new StoreRecentTransactionViewModel
|
|
{
|
|
Id = tx.TransactionId.ToString(),
|
|
Positive = tx.BalanceChange.GetValue(network) >= 0,
|
|
Balance = tx.BalanceChange.ShowMoney(network),
|
|
IsConfirmed = tx.Confirmations != 0,
|
|
Link = string.Format(CultureInfo.InvariantCulture, network.BlockExplorerLink, tx.TransactionId.ToString()),
|
|
Timestamp = tx.Timestamp
|
|
})
|
|
.ToList();
|
|
}
|
|
}
|
|
|
|
|
|
var vm = new StoreRecentTransactionsViewModel
|
|
{
|
|
Store = store,
|
|
WalletId = walletId,
|
|
Transactions = transactions
|
|
};
|
|
return View(vm);
|
|
}
|
|
}
|