예제 #1
0
 public InvoiceWatcher(ExplorerClient explorerClient,
                       InvoiceRepository invoiceRepository,
                       BTCPayWallet wallet,
                       InvoiceNotificationManager notificationManager)
 {
     LongPollingMode      = explorerClient.Network == Network.RegTest;
     PollInterval         = explorerClient.Network == Network.RegTest ? TimeSpan.FromSeconds(10.0) : TimeSpan.FromMinutes(1.0);
     _Wallet              = wallet ?? throw new ArgumentNullException(nameof(wallet));
     _ExplorerClient      = explorerClient ?? throw new ArgumentNullException(nameof(explorerClient));
     _DerivationFactory   = new DerivationStrategyFactory(_ExplorerClient.Network);
     _InvoiceRepository   = invoiceRepository ?? throw new ArgumentNullException(nameof(invoiceRepository));
     _NotificationManager = notificationManager ?? throw new ArgumentNullException(nameof(notificationManager));
 }
예제 #2
0
 public InvoiceWatcher(
     IHostingEnvironment env,
     BTCPayNetworkProvider networkProvider,
     InvoiceRepository invoiceRepository,
     EventAggregator eventAggregator,
     BTCPayWallet wallet)
 {
     PollInterval       = TimeSpan.FromMinutes(1.0);
     _Wallet            = wallet ?? throw new ArgumentNullException(nameof(wallet));
     _InvoiceRepository = invoiceRepository ?? throw new ArgumentNullException(nameof(invoiceRepository));
     _EventAggregator   = eventAggregator ?? throw new ArgumentNullException(nameof(eventAggregator));
     _NetworkProvider   = networkProvider;
 }
 private static async Task <string> GetBalanceString(BTCPayWallet wallet, DerivationStrategyBase derivationStrategy)
 {
     using (CancellationTokenSource cts = new CancellationTokenSource(TimeSpan.FromSeconds(10)))
     {
         try
         {
             return((await wallet.GetBalance(derivationStrategy, cts.Token)).ToString());
         }
         catch
         {
             return("--");
         }
     }
 }
예제 #4
0
 public InvoiceWatcher(ExplorerClient explorerClient,
                       BTCPayNetworkProvider networkProvider,
                       InvoiceRepository invoiceRepository,
                       EventAggregator eventAggregator,
                       BTCPayWallet wallet,
                       InvoiceWatcherAccessor accessor)
 {
     LongPollingMode    = explorerClient.Network == Network.RegTest;
     PollInterval       = explorerClient.Network == Network.RegTest ? TimeSpan.FromSeconds(10.0) : TimeSpan.FromMinutes(1.0);
     _Wallet            = wallet ?? throw new ArgumentNullException(nameof(wallet));
     _ExplorerClient    = explorerClient ?? throw new ArgumentNullException(nameof(explorerClient));
     _DerivationFactory = new DerivationStrategyFactory(_ExplorerClient.Network);
     _InvoiceRepository = invoiceRepository ?? throw new ArgumentNullException(nameof(invoiceRepository));
     _EventAggregator   = eventAggregator ?? throw new ArgumentNullException(nameof(eventAggregator));
     _NetworkProvider   = networkProvider;
     accessor.Instance  = this;
 }
예제 #5
0
 public StoresController(
     StoreRepository repo,
     TokenRepository tokenRepo,
     CallbackController callbackController,
     UserManager <ApplicationUser> userManager,
     AccessTokenController tokenController,
     BTCPayWallet wallet,
     Network network,
     IHostingEnvironment env)
 {
     _Repo               = repo;
     _TokenRepository    = tokenRepo;
     _UserManager        = userManager;
     _TokenController    = tokenController;
     _Wallet             = wallet;
     _Env                = env;
     _Network            = network;
     _CallbackController = callbackController;
 }
예제 #6
0
 public StoresController(
     StoreRepository repo,
     TokenRepository tokenRepo,
     UserManager <ApplicationUser> userManager,
     AccessTokenController tokenController,
     BTCPayWallet wallet,
     BTCPayNetworkProvider networkProvider,
     ExplorerClientProvider explorerProvider,
     IHostingEnvironment env)
 {
     _Repo             = repo;
     _TokenRepository  = tokenRepo;
     _UserManager      = userManager;
     _TokenController  = tokenController;
     _Wallet           = wallet;
     _Env              = env;
     _NetworkProvider  = networkProvider;
     _ExplorerProvider = explorerProvider;
 }
예제 #7
0
 public InvoiceController(
     Network network,
     InvoiceRepository invoiceRepository,
     UserManager <ApplicationUser> userManager,
     BTCPayWallet wallet,
     IRateProvider rateProvider,
     StoreRepository storeRepository,
     InvoiceWatcher watcher,
     ExplorerClient explorerClient,
     IFeeProvider feeProvider)
 {
     _Explorer          = explorerClient ?? throw new ArgumentNullException(nameof(explorerClient));
     _StoreRepository   = storeRepository ?? throw new ArgumentNullException(nameof(storeRepository));
     _Network           = network ?? throw new ArgumentNullException(nameof(network));
     _InvoiceRepository = invoiceRepository ?? throw new ArgumentNullException(nameof(invoiceRepository));
     _Wallet            = wallet ?? throw new ArgumentNullException(nameof(wallet));
     _RateProvider      = rateProvider ?? throw new ArgumentNullException(nameof(rateProvider));
     _Watcher           = watcher ?? throw new ArgumentNullException(nameof(watcher));
     _UserManager       = userManager;
     _FeeProvider       = feeProvider ?? throw new ArgumentNullException(nameof(feeProvider));
 }
예제 #8
0
 public ManageController(
     UserManager <ApplicationUser> userManager,
     SignInManager <ApplicationUser> signInManager,
     IEmailSender emailSender,
     ILogger <ManageController> logger,
     UrlEncoder urlEncoder,
     TokenRepository tokenRepository,
     BTCPayWallet wallet,
     StoreRepository storeRepository,
     IHostingEnvironment env)
 {
     _userManager     = userManager;
     _signInManager   = signInManager;
     _emailSender     = emailSender;
     _logger          = logger;
     _urlEncoder      = urlEncoder;
     _TokenRepository = tokenRepository;
     _Wallet          = wallet;
     _Env             = env;
     _StoreRepository = storeRepository;
 }
예제 #9
0
 public InvoiceController(InvoiceRepository invoiceRepository,
                          CurrencyNameTable currencyNameTable,
                          UserManager <ApplicationUser> userManager,
                          BTCPayWallet wallet,
                          IRateProviderFactory rateProviders,
                          StoreRepository storeRepository,
                          EventAggregator eventAggregator,
                          BTCPayNetworkProvider networkProvider,
                          ExplorerClientProvider explorerClientProviders,
                          IFeeProviderFactory feeProviderFactory)
 {
     _ExplorerClients    = explorerClientProviders;
     _CurrencyNameTable  = currencyNameTable ?? throw new ArgumentNullException(nameof(currencyNameTable));
     _StoreRepository    = storeRepository ?? throw new ArgumentNullException(nameof(storeRepository));
     _InvoiceRepository  = invoiceRepository ?? throw new ArgumentNullException(nameof(invoiceRepository));
     _Wallet             = wallet ?? throw new ArgumentNullException(nameof(wallet));
     _RateProviders      = rateProviders ?? throw new ArgumentNullException(nameof(rateProviders));
     _UserManager        = userManager;
     _FeeProviderFactory = feeProviderFactory ?? throw new ArgumentNullException(nameof(feeProviderFactory));
     _EventAggregator    = eventAggregator;
     _NetworkProvider    = networkProvider;
 }
예제 #10
0
 public InvoiceController(InvoiceRepository invoiceRepository,
                          CurrencyNameTable currencyNameTable,
                          UserManager <ApplicationUser> userManager,
                          BTCPayWallet wallet,
                          IRateProvider rateProvider,
                          StoreRepository storeRepository,
                          EventAggregator eventAggregator,
                          InvoiceWatcherAccessor watcher,
                          ExplorerClient explorerClient,
                          BTCPayNetworkProvider networkProvider,
                          IFeeProviderFactory feeProviderFactory)
 {
     _CurrencyNameTable  = currencyNameTable ?? throw new ArgumentNullException(nameof(currencyNameTable));
     _Explorer           = explorerClient ?? throw new ArgumentNullException(nameof(explorerClient));
     _StoreRepository    = storeRepository ?? throw new ArgumentNullException(nameof(storeRepository));
     _InvoiceRepository  = invoiceRepository ?? throw new ArgumentNullException(nameof(invoiceRepository));
     _Wallet             = wallet ?? throw new ArgumentNullException(nameof(wallet));
     _RateProvider       = rateProvider ?? throw new ArgumentNullException(nameof(rateProvider));
     _Watcher            = (watcher ?? throw new ArgumentNullException(nameof(watcher))).Instance;
     _UserManager        = userManager;
     _FeeProviderFactory = feeProviderFactory ?? throw new ArgumentNullException(nameof(feeProviderFactory));
     _EventAggregator    = eventAggregator;
     _NetworkProvider    = networkProvider;
 }
        public static async Task <Dictionary <uint256, TransactionResult> > GetTransactions(this BTCPayWallet client, uint256[] hashes, bool includeOffchain = false, CancellationToken cts = default(CancellationToken))
        {
            hashes = hashes.Distinct().ToArray();
            var transactions = hashes
                               .Select(async o => await client.GetTransactionAsync(o, includeOffchain, cts))
                               .ToArray();
            await Task.WhenAll(transactions).ConfigureAwait(false);

            return(transactions.Select(t => t.Result).Where(t => t != null).ToDictionary(o => o.Transaction.GetHash()));
        }
예제 #12
0
        private async Task Listen(BTCPayWallet wallet)
        {
            var  network = wallet.Network;
            bool cleanup = false;

            try
            {
                if (_SessionsByCryptoCode.ContainsKey(network.CryptoCode))
                {
                    return;
                }
                var client = _ExplorerClients.GetExplorerClient(network);
                if (client == null)
                {
                    return;
                }
                if (_Cts.IsCancellationRequested)
                {
                    return;
                }
                var session = await client.CreateWebsocketNotificationSessionAsync(_Cts.Token).ConfigureAwait(false);

                if (!_SessionsByCryptoCode.TryAdd(network.CryptoCode, session))
                {
                    await session.DisposeAsync();

                    return;
                }
                cleanup = true;

                using (session)
                {
                    await session.ListenNewBlockAsync(_Cts.Token).ConfigureAwait(false);

                    await session.ListenAllTrackedSourceAsync(cancellation : _Cts.Token).ConfigureAwait(false);

                    Logs.PayServer.LogInformation($"{network.CryptoCode}: Checking if any pending invoice got paid while offline...");
                    int paymentCount = await FindPaymentViaPolling(wallet, network);

                    Logs.PayServer.LogInformation($"{network.CryptoCode}: {paymentCount} payments happened while offline");

                    Logs.PayServer.LogInformation($"Connected to WebSocket of NBXplorer ({network.CryptoCode})");
                    while (!_Cts.IsCancellationRequested)
                    {
                        var newEvent = await session.NextEventAsync(_Cts.Token).ConfigureAwait(false);

                        switch (newEvent)
                        {
                        case NBXplorer.Models.NewBlockEvent evt:
                            await UpdatePaymentStates(wallet, await _InvoiceRepository.GetPendingInvoices());

                            _Aggregator.Publish(new Events.NewBlockEvent()
                            {
                                CryptoCode = evt.CryptoCode
                            });
                            break;

                        case NBXplorer.Models.NewTransactionEvent evt:
                            if (evt.DerivationStrategy != null)
                            {
                                wallet.InvalidateCache(evt.DerivationStrategy);
                                var validOutputs = network.GetValidOutputs(evt).ToList();
                                if (!validOutputs.Any())
                                {
                                    break;
                                }
                                foreach (var output in validOutputs)
                                {
                                    var key = output.Item1.ScriptPubKey.Hash + "#" +
                                              network.CryptoCode.ToUpperInvariant();
                                    var invoice = (await _InvoiceRepository.GetInvoicesFromAddresses(new[] { key }))
                                                  .FirstOrDefault();
                                    if (invoice != null)
                                    {
                                        var address = network.NBXplorerNetwork.CreateAddress(evt.DerivationStrategy,
                                                                                             output.Item1.KeyPath, output.Item1.ScriptPubKey);

                                        var paymentData = new BitcoinLikePaymentData(address,
                                                                                     output.matchedOutput.Value, output.outPoint,
                                                                                     evt.TransactionData.Transaction.RBF, output.matchedOutput.KeyPath);

                                        var alreadyExist = invoice
                                                           .GetAllBitcoinPaymentData(false).Any(c => c.GetPaymentId() == paymentData.GetPaymentId());
                                        if (!alreadyExist)
                                        {
                                            var payment = await _paymentService.AddPayment(invoice.Id,
                                                                                           DateTimeOffset.UtcNow, paymentData, network);

                                            if (payment != null)
                                            {
                                                await ReceivedPayment(wallet, invoice, payment,
                                                                      evt.DerivationStrategy);
                                            }
                                        }
                                        else
                                        {
                                            await UpdatePaymentStates(wallet, invoice.Id);
                                        }
                                    }
                                }
                            }

                            _Aggregator.Publish(new NewOnChainTransactionEvent()
                            {
                                CryptoCode          = wallet.Network.CryptoCode,
                                NewTransactionEvent = evt
                            });

                            break;

                        default:
                            Logs.PayServer.LogWarning("Received unknown message from NBXplorer");
                            break;
                        }
                    }
                }
            }
            catch when(_Cts.IsCancellationRequested)
            {
            }
        private bool GetCryptoCodeWallet(string cryptoCode, out BTCPayNetwork network, out BTCPayWallet wallet)
        {
            network = _btcPayNetworkProvider.GetNetwork <BTCPayNetwork>(cryptoCode);
            wallet  = network != null?_walletProvider.GetWallet(network) : null;

            return(wallet != null);
        }
예제 #14
0
        private async Task Listen(BTCPayWallet wallet)
        {
            var  network = wallet.Network;
            bool cleanup = false;

            try
            {
                if (_SessionsByCryptoCode.ContainsKey(network.CryptoCode))
                {
                    return;
                }
                var client = _ExplorerClients.GetExplorerClient(network);
                if (client == null)
                {
                    return;
                }
                if (_Cts.IsCancellationRequested)
                {
                    return;
                }
                var session = await client.CreateNotificationSessionAsync(_Cts.Token).ConfigureAwait(false);

                if (!_SessionsByCryptoCode.TryAdd(network.CryptoCode, session))
                {
                    await session.DisposeAsync();

                    return;
                }
                cleanup = true;

                using (session)
                {
                    await session.ListenNewBlockAsync(_Cts.Token).ConfigureAwait(false);

                    await session.ListenAllDerivationSchemesAsync(cancellation : _Cts.Token).ConfigureAwait(false);

                    Logs.PayServer.LogInformation($"{network.CryptoCode}: Checking if any pending invoice got paid while offline...");
                    int paymentCount = await FindPaymentViaPolling(wallet, network);

                    Logs.PayServer.LogInformation($"{network.CryptoCode}: {paymentCount} payments happened while offline");

                    Logs.PayServer.LogInformation($"Connected to WebSocket of NBXplorer ({network.CryptoCode})");
                    while (!_Cts.IsCancellationRequested)
                    {
                        var newEvent = await session.NextEventAsync(_Cts.Token).ConfigureAwait(false);

                        switch (newEvent)
                        {
                        case NBXplorer.Models.NewBlockEvent evt:

                            await Task.WhenAll((await _InvoiceRepository.GetPendingInvoices())
                                               .Select(invoiceId => UpdatePaymentStates(wallet, invoiceId))
                                               .ToArray());

                            _Aggregator.Publish(new Events.NewBlockEvent()
                            {
                                CryptoCode = evt.CryptoCode
                            });
                            break;

                        case NBXplorer.Models.NewTransactionEvent evt:
                            wallet.InvalidateCache(evt.DerivationStrategy);
                            foreach (var output in evt.Outputs)
                            {
                                foreach (var txCoin in evt.TransactionData.Transaction.Outputs.AsCoins()
                                         .Where(o => o.ScriptPubKey == output.ScriptPubKey)
                                         .Select(o => output.Redeem == null ? o : o.ToScriptCoin(output.Redeem)))
                                {
                                    var invoice = await _InvoiceRepository.GetInvoiceFromScriptPubKey(output.ScriptPubKey, network.CryptoCode);

                                    if (invoice != null)
                                    {
                                        var paymentData  = new BitcoinLikePaymentData(txCoin, evt.TransactionData.Transaction.RBF);
                                        var alreadyExist = GetAllBitcoinPaymentData(invoice).Where(c => c.GetPaymentId() == paymentData.GetPaymentId()).Any();
                                        if (!alreadyExist)
                                        {
                                            var payment = await _InvoiceRepository.AddPayment(invoice.Id, DateTimeOffset.UtcNow, paymentData, network.CryptoCode);
                                            await ReceivedPayment(wallet, invoice.Id, payment, evt.DerivationStrategy);
                                        }
                                        else
                                        {
                                            await UpdatePaymentStates(wallet, invoice.Id);
                                        }
                                    }
                                }
                            }
                            break;

                        default:
                            Logs.PayServer.LogWarning("Received unknown message from NBXplorer");
                            break;
                        }
                    }
                }
            }
            catch when(_Cts.IsCancellationRequested)
            {
            }
예제 #15
0
        private void AssertCryptoCodeWallet(string cryptoCode, out BTCPayNetwork network, out BTCPayWallet wallet)
        {
            network = _btcPayNetworkProvider.GetNetwork <BTCPayNetwork>(cryptoCode);
            if (network is null)
            {
                throw new JsonHttpException(this.CreateAPIError(404, "unknown-cryptocode", "This crypto code isn't set up in this GRSPay Server instance"));
            }

            wallet = _walletProvider.GetWallet(network);
            if (wallet is null)
            {
                throw ErrorPaymentMethodNotConfigured();
            }
        }
예제 #16
0
 public TransactionsExport(BTCPayWallet wallet, Dictionary <string, WalletTransactionInfo> walletTransactionsInfo)
 {
     _wallet = wallet;
     _walletTransactionsInfo = walletTransactionsInfo;
 }