Task <LightningInvoice> ILightningClient.CreateInvoice(CreateInvoiceParams req, CancellationToken cancellation)
 {
     if (req.DescriptionHash != null)
     {
         throw new NotSupportedException("Lightning Charge does not support creating an invoice with description_hash");
     }
     return((this as ILightningClient).CreateInvoice(req.Amount, req.Description, req.Expiry, cancellation));
 }
        public async Task <InvoiceData> CreateInvoice(CreateInvoiceParams req, CancellationToken cancellation)
        {
            var payload = new CreateInvoiceRequest
            {
                Amount            = req.Amount,
                Description       = req.Description,
                Expiry            = req.Expiry,
                PrivateRouteHints = req.PrivateRouteHints
            };

            return(await Post <CreateInvoiceRequest, InvoiceData>("invoice", payload, cancellation));
        }
        public override async Task <IPaymentMethodDetails> CreatePaymentMethodDetails(
            InvoiceLogs logs,
            LightningSupportedPaymentMethod supportedPaymentMethod, PaymentMethod paymentMethod, StoreData store,
            BTCPayNetwork network, object preparePaymentObject)
        {
            //direct casting to (BTCPayNetwork) is fixed in other pull requests with better generic interfacing for handlers
            var storeBlob = store.GetStoreBlob();
            var test      = GetNodeInfo(paymentMethod.PreferOnion, supportedPaymentMethod, (BTCPayNetwork)network);
            var invoice   = paymentMethod.ParentEntity;
            var due       = Extensions.RoundUp(invoice.ProductInformation.Price / paymentMethod.Rate, network.Divisibility);
            var client    = _lightningClientFactory.Create(supportedPaymentMethod.GetLightningUrl(), (BTCPayNetwork)network);
            var expiry    = invoice.ExpirationTime - DateTimeOffset.UtcNow;

            if (expiry < TimeSpan.Zero)
            {
                expiry = TimeSpan.FromSeconds(1);
            }

            LightningInvoice lightningInvoice = null;

            string description = storeBlob.LightningDescriptionTemplate;

            description = description.Replace("{StoreName}", store.StoreName ?? "", StringComparison.OrdinalIgnoreCase)
                          .Replace("{ItemDescription}", invoice.ProductInformation.ItemDesc ?? "", StringComparison.OrdinalIgnoreCase)
                          .Replace("{OrderId}", invoice.OrderId ?? "", StringComparison.OrdinalIgnoreCase);
            using (var cts = new CancellationTokenSource(LIGHTNING_TIMEOUT))
            {
                try
                {
                    var request = new CreateInvoiceParams(new LightMoney(due, LightMoneyUnit.BTC), description, expiry);
                    request.PrivateRouteHints = storeBlob.LightningPrivateRouteHints;
                    lightningInvoice          = await client.CreateInvoice(request, cts.Token);
                }
                catch (OperationCanceledException) when(cts.IsCancellationRequested)
                {
                    throw new PaymentMethodUnavailableException($"The lightning node did not reply in a timely manner");
                }
                catch (Exception ex)
                {
                    throw new PaymentMethodUnavailableException($"Impossible to create lightning invoice ({ex.Message})", ex);
                }
            }
            var nodeInfo = await test;

            return(new LightningLikePaymentMethodDetails()
            {
                BOLT11 = lightningInvoice.BOLT11,
                InvoiceId = lightningInvoice.Id,
                NodeInfo = nodeInfo.ToString()
            });
        }
예제 #4
0
        public async Task <LightningInvoice> CreateInvoice(CreateInvoiceParams req, CancellationToken cancellation = default)
        {
            var invoice = await _client.CreateInvoice(req, cancellation);

            return(new LightningInvoice
            {
                Id = invoice.Id,
                Amount = invoice.Amount,
                PaidAt = invoice.PaidAt,
                ExpiresAt = invoice.ExpiresAt,
                BOLT11 = invoice.BOLT11,
                Status = invoice.Status,
                AmountReceived = invoice.AmountReceived
            });
        }
예제 #5
0
 Task <LightningInvoice> ILightningClient.CreateInvoice(CreateInvoiceParams req, CancellationToken cancellation)
 {
     return((this as ILightningClient).CreateInvoice(req.Amount, req.Description, req.Expiry, cancellation));
 }
예제 #6
0
        public override async Task <IPaymentMethodDetails> CreatePaymentMethodDetails(
            InvoiceLogs logs,
            LightningSupportedPaymentMethod supportedPaymentMethod, PaymentMethod paymentMethod, Data.StoreData store,
            BTCPayNetwork network, object preparePaymentObject)
        {
            if (paymentMethod.ParentEntity.Type == InvoiceType.TopUp)
            {
                throw new PaymentMethodUnavailableException("Lightning Network payment method is not available for top-up invoices");
            }

            if (preparePaymentObject is null)
            {
                return(new LightningLikePaymentMethodDetails()
                {
                    Activated = false
                });
            }
            //direct casting to (BTCPayNetwork) is fixed in other pull requests with better generic interfacing for handlers
            var storeBlob = store.GetStoreBlob();
            var test      = GetNodeInfo(supportedPaymentMethod, network, paymentMethod.PreferOnion);

            var     invoice = paymentMethod.ParentEntity;
            decimal due     = Extensions.RoundUp(invoice.Price / paymentMethod.Rate, network.Divisibility);

            try
            {
                due = paymentMethod.Calculate().Due.ToDecimal(MoneyUnit.BTC);
            }
            catch (Exception)
            {
                // ignored
            }
            var client = supportedPaymentMethod.CreateLightningClient(network, Options.Value, _lightningClientFactory);
            var expiry = invoice.ExpirationTime - DateTimeOffset.UtcNow;

            if (expiry < TimeSpan.Zero)
            {
                expiry = TimeSpan.FromSeconds(1);
            }

            LightningInvoice?lightningInvoice = null;

            string description = storeBlob.LightningDescriptionTemplate;

            description = description.Replace("{StoreName}", store.StoreName ?? "", StringComparison.OrdinalIgnoreCase)
                          .Replace("{ItemDescription}", invoice.Metadata.ItemDesc ?? "", StringComparison.OrdinalIgnoreCase)
                          .Replace("{OrderId}", invoice.Metadata.OrderId ?? "", StringComparison.OrdinalIgnoreCase);
            using (var cts = new CancellationTokenSource(LIGHTNING_TIMEOUT))
            {
                try
                {
                    var request = new CreateInvoiceParams(new LightMoney(due, LightMoneyUnit.BTC), description, expiry);
                    request.PrivateRouteHints = storeBlob.LightningPrivateRouteHints;
                    lightningInvoice          = await client.CreateInvoice(request, cts.Token);
                }
                catch (OperationCanceledException) when(cts.IsCancellationRequested)
                {
                    throw new PaymentMethodUnavailableException("The lightning node did not reply in a timely manner");
                }
                catch (Exception ex)
                {
                    throw new PaymentMethodUnavailableException($"Impossible to create lightning invoice ({ex.Message})", ex);
                }
            }

            var nodeInfo = await test;

            return(new LightningLikePaymentMethodDetails
            {
                Activated = true,
                BOLT11 = lightningInvoice.BOLT11,
                PaymentHash = BOLT11PaymentRequest.Parse(lightningInvoice.BOLT11, network.NBitcoinNetwork).PaymentHash,
                InvoiceId = lightningInvoice.Id,
                NodeInfo = nodeInfo.First().ToString()
            });
        }