mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2025-03-12 10:30:47 +01:00
Abstract ChargeClient to prepare for support of other lightning implementation
This commit is contained in:
parent
73cc75fe66
commit
2b2e12b290
20 changed files with 133 additions and 54 deletions
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using BTCPayServer.Payments.Lightning.Charge;
|
||||||
using BTCPayServer.Payments.Lightning.CLightning;
|
using BTCPayServer.Payments.Lightning.CLightning;
|
||||||
using NBitcoin;
|
using NBitcoin;
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BTCPayServer.Payments.Lightning.CLightning;
|
using BTCPayServer.Payments.Lightning.CLightning;
|
||||||
using BTCPayServer.Payments.Lightning.CLightning.RPC;
|
|
||||||
using NBitcoin;
|
using NBitcoin;
|
||||||
|
|
||||||
namespace BTCPayServer.Tests
|
namespace BTCPayServer.Tests
|
||||||
|
|
|
@ -18,7 +18,8 @@ using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using BTCPayServer.Payments.Lightning.CLightning.RPC;
|
using BTCPayServer.Payments.Lightning.CLightning;
|
||||||
|
using BTCPayServer.Payments.Lightning.Charge;
|
||||||
|
|
||||||
namespace BTCPayServer.Tests
|
namespace BTCPayServer.Tests
|
||||||
{
|
{
|
||||||
|
@ -117,7 +118,7 @@ namespace BTCPayServer.Tests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<Payments.Lightning.CLightning.GetInfoResponse> WaitLNSynched()
|
private async Task<GetInfoResponse> WaitLNSynched()
|
||||||
{
|
{
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
|
|
|
@ -68,7 +68,6 @@ namespace BTCPayServer
|
||||||
public BTCPayDefaultSettings DefaultSettings { get; set; }
|
public BTCPayDefaultSettings DefaultSettings { get; set; }
|
||||||
public KeyPath CoinType { get; internal set; }
|
public KeyPath CoinType { get; internal set; }
|
||||||
public int MaxTrackedConfirmation { get; internal set; } = 6;
|
public int MaxTrackedConfirmation { get; internal set; } = 6;
|
||||||
public string CLightningNetworkName { get; internal set; }
|
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
|
|
|
@ -28,10 +28,7 @@ namespace BTCPayServer
|
||||||
CryptoImagePath = "imlegacy/bitcoin-symbol.svg",
|
CryptoImagePath = "imlegacy/bitcoin-symbol.svg",
|
||||||
LightningImagePath = "imlegacy/btc-lightning.svg",
|
LightningImagePath = "imlegacy/btc-lightning.svg",
|
||||||
DefaultSettings = BTCPayDefaultSettings.GetDefaultSettings(NBXplorerNetworkProvider.ChainType),
|
DefaultSettings = BTCPayDefaultSettings.GetDefaultSettings(NBXplorerNetworkProvider.ChainType),
|
||||||
CoinType = NBXplorerNetworkProvider.ChainType == ChainType.Main ? new KeyPath("0'") : new KeyPath("1'"),
|
CoinType = NBXplorerNetworkProvider.ChainType == ChainType.Main ? new KeyPath("0'") : new KeyPath("1'")
|
||||||
CLightningNetworkName = ChainType == ChainType.Main ? "bitcoin" :
|
|
||||||
ChainType == ChainType.Test ? "testnet" :
|
|
||||||
ChainType == ChainType.Regtest ? "regtest" : null
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,9 +27,7 @@ namespace BTCPayServer
|
||||||
CryptoImagePath = "imlegacy/litecoin-symbol.svg",
|
CryptoImagePath = "imlegacy/litecoin-symbol.svg",
|
||||||
LightningImagePath = "imlegacy/ltc-lightning.svg",
|
LightningImagePath = "imlegacy/ltc-lightning.svg",
|
||||||
DefaultSettings = BTCPayDefaultSettings.GetDefaultSettings(NBXplorerNetworkProvider.ChainType),
|
DefaultSettings = BTCPayDefaultSettings.GetDefaultSettings(NBXplorerNetworkProvider.ChainType),
|
||||||
CoinType = NBXplorerNetworkProvider.ChainType == ChainType.Main ? new KeyPath("2'") : new KeyPath("3'"),
|
CoinType = NBXplorerNetworkProvider.ChainType == ChainType.Main ? new KeyPath("2'") : new KeyPath("3'")
|
||||||
CLightningNetworkName = ChainType == ChainType.Main ? "litecoin" :
|
|
||||||
ChainType == ChainType.Test ? "litecoin-testnet" : null
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ namespace BTCPayServer.Controllers
|
||||||
var network = vm.CryptoCurrency == null ? null : _ExplorerProvider.GetNetwork(vm.CryptoCurrency);
|
var network = vm.CryptoCurrency == null ? null : _ExplorerProvider.GetNetwork(vm.CryptoCurrency);
|
||||||
vm.SetCryptoCurrencies(_NetworkProvider, vm.CryptoCurrency);
|
vm.SetCryptoCurrencies(_NetworkProvider, vm.CryptoCurrency);
|
||||||
vm.InternalLightningNode = GetInternalLightningNodeIfAuthorized();
|
vm.InternalLightningNode = GetInternalLightningNodeIfAuthorized();
|
||||||
if (network == null || network.CLightningNetworkName == null)
|
if (network == null)
|
||||||
{
|
{
|
||||||
ModelState.AddModelError(nameof(vm.CryptoCurrency), "Invalid network");
|
ModelState.AddModelError(nameof(vm.CryptoCurrency), "Invalid network");
|
||||||
return View(vm);
|
return View(vm);
|
||||||
|
|
|
@ -147,7 +147,7 @@ namespace BTCPayServer.Hosting
|
||||||
services.AddSingleton<IHostedService, Payments.Bitcoin.NBXplorerListener>();
|
services.AddSingleton<IHostedService, Payments.Bitcoin.NBXplorerListener>();
|
||||||
|
|
||||||
services.AddSingleton<Payments.IPaymentMethodHandler<Payments.Lightning.LightningSupportedPaymentMethod>, Payments.Lightning.LightningLikePaymentHandler>();
|
services.AddSingleton<Payments.IPaymentMethodHandler<Payments.Lightning.LightningSupportedPaymentMethod>, Payments.Lightning.LightningLikePaymentHandler>();
|
||||||
services.AddSingleton<IHostedService, Payments.Lightning.ChargeListener>();
|
services.AddSingleton<IHostedService, Payments.Lightning.LightningListener>();
|
||||||
|
|
||||||
services.AddSingleton<IHostedService, NBXplorerWaiters>();
|
services.AddSingleton<IHostedService, NBXplorerWaiters>();
|
||||||
services.AddSingleton<IHostedService, InvoiceNotificationManager>();
|
services.AddSingleton<IHostedService, InvoiceNotificationManager>();
|
||||||
|
|
|
@ -34,7 +34,6 @@ namespace BTCPayServer.Models.StoreViewModels
|
||||||
public void SetCryptoCurrencies(BTCPayNetworkProvider networkProvider, string selectedScheme)
|
public void SetCryptoCurrencies(BTCPayNetworkProvider networkProvider, string selectedScheme)
|
||||||
{
|
{
|
||||||
var choices = networkProvider.GetAll()
|
var choices = networkProvider.GetAll()
|
||||||
.Where(n => n.CLightningNetworkName != null)
|
|
||||||
.Select(o => new Format() { Name = o.CryptoCode, Value = o.CryptoCode }).ToArray();
|
.Select(o => new Format() { Name = o.CryptoCode, Value = o.CryptoCode }).ToArray();
|
||||||
var chosen = choices.FirstOrDefault(f => f.Name == selectedScheme) ?? choices.FirstOrDefault();
|
var chosen = choices.FirstOrDefault(f => f.Name == selectedScheme) ?? choices.FirstOrDefault();
|
||||||
CryptoCurrencies = new SelectList(choices, nameof(chosen.Value), nameof(chosen.Name), chosen);
|
CryptoCurrencies = new SelectList(choices, nameof(chosen.Value), nameof(chosen.Name), chosen);
|
||||||
|
|
|
@ -6,12 +6,13 @@ using System.Net;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using BTCPayServer.Payments.Lightning.Charge;
|
||||||
using NBitcoin;
|
using NBitcoin;
|
||||||
using NBitcoin.RPC;
|
using NBitcoin.RPC;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
namespace BTCPayServer.Payments.Lightning.CLightning.RPC
|
namespace BTCPayServer.Payments.Lightning.CLightning
|
||||||
{
|
{
|
||||||
public class CLightningRPCClient
|
public class CLightningRPCClient
|
||||||
{
|
{
|
|
@ -3,7 +3,7 @@ using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace BTCPayServer.Payments.Lightning.CLightning.RPC
|
namespace BTCPayServer.Payments.Lightning.CLightning
|
||||||
{
|
{
|
||||||
public class NodeInfo
|
public class NodeInfo
|
||||||
{
|
{
|
|
@ -5,7 +5,7 @@ using System.Threading.Tasks;
|
||||||
using NBitcoin;
|
using NBitcoin;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace BTCPayServer.Payments.Lightning.CLightning.RPC
|
namespace BTCPayServer.Payments.Lightning.CLightning
|
||||||
{
|
{
|
||||||
public class ChannelInfo
|
public class ChannelInfo
|
||||||
{
|
{
|
|
@ -13,9 +13,9 @@ using NBitcoin;
|
||||||
using NBXplorer;
|
using NBXplorer;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace BTCPayServer.Payments.Lightning.CLightning
|
namespace BTCPayServer.Payments.Lightning.Charge
|
||||||
{
|
{
|
||||||
public class ChargeClient
|
public class ChargeClient : ILightningInvoiceClient
|
||||||
{
|
{
|
||||||
private Uri _Uri;
|
private Uri _Uri;
|
||||||
public Uri Uri
|
public Uri Uri
|
||||||
|
@ -126,5 +126,48 @@ namespace BTCPayServer.Payments.Lightning.CLightning
|
||||||
uri += "/";
|
uri += "/";
|
||||||
return new Uri(uri + partialUrl);
|
return new Uri(uri + partialUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async Task<LightningInvoice> ILightningInvoiceClient.GetInvoice(string invoiceId, CancellationToken cancellation)
|
||||||
|
{
|
||||||
|
var invoice = await GetInvoice(invoiceId, cancellation);
|
||||||
|
return ChargeClient.ToLightningInvoice(invoice);
|
||||||
|
}
|
||||||
|
|
||||||
|
async Task<ILightningListenInvoiceSession> ILightningInvoiceClient.Listen(CancellationToken cancellation)
|
||||||
|
{
|
||||||
|
return await Listen(cancellation);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static LightningInvoice ToLightningInvoice(ChargeInvoice invoice)
|
||||||
|
{
|
||||||
|
return new LightningInvoice()
|
||||||
|
{
|
||||||
|
Id = invoice.Id,
|
||||||
|
Amount = invoice.MilliSatoshi,
|
||||||
|
BOLT11 = invoice.PaymentRequest,
|
||||||
|
PaidAt = invoice.PaidAt,
|
||||||
|
Status = invoice.Status
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async Task<LightningInvoice> ILightningInvoiceClient.CreateInvoice(LightMoney amount, TimeSpan expiry, CancellationToken cancellation)
|
||||||
|
{
|
||||||
|
var invoice = await CreateInvoiceAsync(new CreateInvoiceRequest() { Amont = amount, Expiry = expiry });
|
||||||
|
return new LightningInvoice() { Id = invoice.Id, Amount = amount, BOLT11 = invoice.PayReq, Status = "unpaid" };
|
||||||
|
}
|
||||||
|
|
||||||
|
async Task<LightningNodeInformation> ILightningInvoiceClient.GetInfo(CancellationToken cancellation)
|
||||||
|
{
|
||||||
|
var info = await GetInfoAsync(cancellation);
|
||||||
|
var address = info.Address.Select(a => a.Address).FirstOrDefault();
|
||||||
|
var port = info.Port;
|
||||||
|
address = address ?? Uri.DnsSafeHost;
|
||||||
|
return new LightningNodeInformation()
|
||||||
|
{
|
||||||
|
P2PPort = port,
|
||||||
|
Address = address,
|
||||||
|
BlockHeight = info.BlockHeight
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -8,7 +8,7 @@ using System.Threading.Tasks;
|
||||||
using NBXplorer;
|
using NBXplorer;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace BTCPayServer.Payments.Lightning.CLightning
|
namespace BTCPayServer.Payments.Lightning.Charge
|
||||||
{
|
{
|
||||||
public class ChargeInvoice
|
public class ChargeInvoice
|
||||||
{
|
{
|
||||||
|
@ -28,7 +28,7 @@ namespace BTCPayServer.Payments.Lightning.CLightning
|
||||||
[JsonProperty("payreq")]
|
[JsonProperty("payreq")]
|
||||||
public string PaymentRequest { get; set; }
|
public string PaymentRequest { get; set; }
|
||||||
}
|
}
|
||||||
public class ChargeSession : IDisposable
|
public class ChargeSession : ILightningListenInvoiceSession
|
||||||
{
|
{
|
||||||
private ClientWebSocket socket;
|
private ClientWebSocket socket;
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ namespace BTCPayServer.Payments.Lightning.CLightning
|
||||||
}
|
}
|
||||||
|
|
||||||
ArraySegment<byte> _Buffer;
|
ArraySegment<byte> _Buffer;
|
||||||
public async Task<ChargeInvoice> NextEvent(CancellationToken cancellation = default(CancellationToken))
|
public async Task<ChargeInvoice> WaitInvoice(CancellationToken cancellation = default(CancellationToken))
|
||||||
{
|
{
|
||||||
var buffer = _Buffer;
|
var buffer = _Buffer;
|
||||||
var array = _Buffer.Array;
|
var array = _Buffer.Array;
|
||||||
|
@ -120,5 +120,15 @@ namespace BTCPayServer.Payments.Lightning.CLightning
|
||||||
{
|
{
|
||||||
await this.socket.CloseSocket();
|
await this.socket.CloseSocket();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async Task<LightningInvoice> ILightningListenInvoiceSession.WaitInvoice(CancellationToken token)
|
||||||
|
{
|
||||||
|
return ChargeClient.ToLightningInvoice(await WaitInvoice(token));
|
||||||
|
}
|
||||||
|
|
||||||
|
void IDisposable.Dispose()
|
||||||
|
{
|
||||||
|
Dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -3,7 +3,7 @@ using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace BTCPayServer.Payments.Lightning.CLightning
|
namespace BTCPayServer.Payments.Lightning.Charge
|
||||||
{
|
{
|
||||||
public class CreateInvoiceRequest
|
public class CreateInvoiceRequest
|
||||||
{
|
{
|
|
@ -3,7 +3,7 @@ using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace BTCPayServer.Payments.Lightning.CLightning
|
namespace BTCPayServer.Payments.Lightning.Charge
|
||||||
{
|
{
|
||||||
public class CreateInvoiceResponse
|
public class CreateInvoiceResponse
|
||||||
{
|
{
|
|
@ -3,7 +3,7 @@ using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace BTCPayServer.Payments.Lightning.CLightning
|
namespace BTCPayServer.Payments.Lightning.Charge
|
||||||
{
|
{
|
||||||
//[{"type":"ipv4","address":"52.166.90.122","port":9735}]
|
//[{"type":"ipv4","address":"52.166.90.122","port":9735}]
|
||||||
public class GetInfoResponse
|
public class GetInfoResponse
|
40
BTCPayServer/Payments/Lightning/ILightningInvoiceClient.cs
Normal file
40
BTCPayServer/Payments/Lightning/ILightningInvoiceClient.cs
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using BTCPayServer.Payments.Lightning.Charge;
|
||||||
|
|
||||||
|
namespace BTCPayServer.Payments.Lightning
|
||||||
|
{
|
||||||
|
public class LightningInvoice
|
||||||
|
{
|
||||||
|
public string Id { get; set; }
|
||||||
|
public string Status { get; set; }
|
||||||
|
public string BOLT11 { get; set; }
|
||||||
|
public DateTimeOffset? PaidAt
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
public LightMoney Amount { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class LightningNodeInformation
|
||||||
|
{
|
||||||
|
public string Address { get; internal set; }
|
||||||
|
public int P2PPort { get; internal set; }
|
||||||
|
public int BlockHeight { get; set; }
|
||||||
|
}
|
||||||
|
public interface ILightningInvoiceClient
|
||||||
|
{
|
||||||
|
Task<LightningInvoice> GetInvoice(string invoiceId, CancellationToken cancellation = default(CancellationToken));
|
||||||
|
Task<LightningInvoice> CreateInvoice(LightMoney amount, TimeSpan expiry, CancellationToken cancellation = default(CancellationToken));
|
||||||
|
Task<ILightningListenInvoiceSession> Listen(CancellationToken cancellation = default(CancellationToken));
|
||||||
|
Task<LightningNodeInformation> GetInfo(CancellationToken cancellation = default(CancellationToken));
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface ILightningListenInvoiceSession : IDisposable
|
||||||
|
{
|
||||||
|
Task<LightningInvoice> WaitInvoice(CancellationToken token);
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,6 +6,7 @@ using System.Net.Sockets;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BTCPayServer.HostedServices;
|
using BTCPayServer.HostedServices;
|
||||||
|
using BTCPayServer.Payments.Lightning.Charge;
|
||||||
using BTCPayServer.Payments.Lightning.CLightning;
|
using BTCPayServer.Payments.Lightning.CLightning;
|
||||||
using BTCPayServer.Services.Invoices;
|
using BTCPayServer.Services.Invoices;
|
||||||
|
|
||||||
|
@ -24,14 +25,12 @@ namespace BTCPayServer.Payments.Lightning
|
||||||
var due = Extensions.RoundUp(invoice.ProductInformation.Price / paymentMethod.Rate, 8);
|
var due = Extensions.RoundUp(invoice.ProductInformation.Price / paymentMethod.Rate, 8);
|
||||||
var client = GetClient(supportedPaymentMethod, network);
|
var client = GetClient(supportedPaymentMethod, network);
|
||||||
var expiry = invoice.ExpirationTime - DateTimeOffset.UtcNow;
|
var expiry = invoice.ExpirationTime - DateTimeOffset.UtcNow;
|
||||||
var lightningInvoice = await client.CreateInvoiceAsync(new CreateInvoiceRequest()
|
if (expiry < TimeSpan.Zero)
|
||||||
{
|
expiry = TimeSpan.FromSeconds(1);
|
||||||
Amont = new LightMoney(due, LightMoneyUnit.BTC),
|
var lightningInvoice = await client.CreateInvoice(new LightMoney(due, LightMoneyUnit.BTC), expiry);
|
||||||
Expiry = expiry < TimeSpan.Zero ? TimeSpan.FromSeconds(1) : expiry
|
|
||||||
});
|
|
||||||
return new LightningLikePaymentMethodDetails()
|
return new LightningLikePaymentMethodDetails()
|
||||||
{
|
{
|
||||||
BOLT11 = lightningInvoice.PayReq,
|
BOLT11 = lightningInvoice.BOLT11,
|
||||||
InvoiceId = lightningInvoice.Id
|
InvoiceId = lightningInvoice.Id
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -54,23 +53,15 @@ namespace BTCPayServer.Payments.Lightning
|
||||||
|
|
||||||
var cts = new CancellationTokenSource(5000);
|
var cts = new CancellationTokenSource(5000);
|
||||||
var client = GetClient(supportedPaymentMethod, network);
|
var client = GetClient(supportedPaymentMethod, network);
|
||||||
GetInfoResponse info = null;
|
LightningNodeInformation info = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
||||||
info = await client.GetInfoAsync(cts.Token);
|
info = await client.GetInfo(cts.Token);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
throw new Exception($"Error while connecting to the lightning charge {client.Uri} ({ex.Message})");
|
throw new Exception($"Error while connecting to the API ({ex.Message})");
|
||||||
}
|
|
||||||
var address = info.Address.Select(a=>a.Address).FirstOrDefault();
|
|
||||||
var port = info.Port;
|
|
||||||
address = address ?? client.Uri.DnsSafeHost;
|
|
||||||
|
|
||||||
if (info.Network != network.CLightningNetworkName)
|
|
||||||
{
|
|
||||||
throw new Exception($"Lightning node network {info.Network}, but expected is {network.CLightningNetworkName}");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var blocksGap = Math.Abs(info.BlockHeight - summary.Status.ChainHeight);
|
var blocksGap = Math.Abs(info.BlockHeight - summary.Status.ChainHeight);
|
||||||
|
@ -81,15 +72,15 @@ namespace BTCPayServer.Payments.Lightning
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await TestConnection(address, port, cts.Token);
|
await TestConnection(info.Address, info.P2PPort, cts.Token);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
throw new Exception($"Error while connecting to the lightning node via {address}:{port} ({ex.Message})");
|
throw new Exception($"Error while connecting to the lightning node via {info.Address}:{info.P2PPort} ({ex.Message})");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ChargeClient GetClient(LightningSupportedPaymentMethod supportedPaymentMethod, BTCPayNetwork network)
|
private static ILightningInvoiceClient GetClient(LightningSupportedPaymentMethod supportedPaymentMethod, BTCPayNetwork network)
|
||||||
{
|
{
|
||||||
return new ChargeClient(supportedPaymentMethod.GetLightningChargeUrl(true), network.NBitcoinNetwork);
|
return new ChargeClient(supportedPaymentMethod.GetLightningChargeUrl(true), network.NBitcoinNetwork);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,14 +6,14 @@ using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BTCPayServer.Events;
|
using BTCPayServer.Events;
|
||||||
using BTCPayServer.Logging;
|
using BTCPayServer.Logging;
|
||||||
using BTCPayServer.Payments.Lightning.CLightning;
|
|
||||||
using BTCPayServer.Services.Invoices;
|
using BTCPayServer.Services.Invoices;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
using NBXplorer;
|
using NBXplorer;
|
||||||
|
using BTCPayServer.Payments.Lightning.Charge;
|
||||||
|
|
||||||
namespace BTCPayServer.Payments.Lightning
|
namespace BTCPayServer.Payments.Lightning
|
||||||
{
|
{
|
||||||
public class ChargeListener : IHostedService
|
public class LightningListener : IHostedService
|
||||||
{
|
{
|
||||||
class ListenedInvoice
|
class ListenedInvoice
|
||||||
{
|
{
|
||||||
|
@ -28,7 +28,7 @@ namespace BTCPayServer.Payments.Lightning
|
||||||
EventAggregator _Aggregator;
|
EventAggregator _Aggregator;
|
||||||
InvoiceRepository _InvoiceRepository;
|
InvoiceRepository _InvoiceRepository;
|
||||||
BTCPayNetworkProvider _NetworkProvider;
|
BTCPayNetworkProvider _NetworkProvider;
|
||||||
public ChargeListener(EventAggregator aggregator,
|
public LightningListener(EventAggregator aggregator,
|
||||||
InvoiceRepository invoiceRepository,
|
InvoiceRepository invoiceRepository,
|
||||||
BTCPayNetworkProvider networkProvider)
|
BTCPayNetworkProvider networkProvider)
|
||||||
{
|
{
|
||||||
|
@ -128,13 +128,13 @@ namespace BTCPayServer.Payments.Lightning
|
||||||
var session = await charge.Listen(_Cts.Token);
|
var session = await charge.Listen(_Cts.Token);
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
var notification = await session.NextEvent(_Cts.Token);
|
var notification = await session.WaitInvoice(_Cts.Token);
|
||||||
ListenedInvoice listenedInvoice = GetListenedInvoice(notification.Id);
|
ListenedInvoice listenedInvoice = GetListenedInvoice(notification.Id);
|
||||||
if (listenedInvoice == null)
|
if (listenedInvoice == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (notification.Id == listenedInvoice.PaymentMethodDetails.InvoiceId &&
|
if (notification.Id == listenedInvoice.PaymentMethodDetails.InvoiceId &&
|
||||||
notification.PaymentRequest == listenedInvoice.PaymentMethodDetails.BOLT11)
|
notification.BOLT11 == listenedInvoice.PaymentMethodDetails.BOLT11)
|
||||||
{
|
{
|
||||||
if (notification.Status == "paid" && notification.PaidAt.HasValue)
|
if (notification.Status == "paid" && notification.PaidAt.HasValue)
|
||||||
{
|
{
|
||||||
|
@ -161,18 +161,18 @@ namespace BTCPayServer.Payments.Lightning
|
||||||
Logs.PayServer.LogInformation($"{supportedPaymentMethod.CryptoCode} (Lightning): Stop listening {supportedPaymentMethod.GetLightningChargeUrl(false)}");
|
Logs.PayServer.LogInformation($"{supportedPaymentMethod.CryptoCode} (Lightning): Stop listening {supportedPaymentMethod.GetLightningChargeUrl(false)}");
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task AddPayment(BTCPayNetwork network, ChargeInvoice notification, ListenedInvoice listenedInvoice)
|
private async Task AddPayment(BTCPayNetwork network, LightningInvoice notification, ListenedInvoice listenedInvoice)
|
||||||
{
|
{
|
||||||
var payment = await _InvoiceRepository.AddPayment(listenedInvoice.InvoiceId, notification.PaidAt.Value, new LightningLikePaymentData()
|
var payment = await _InvoiceRepository.AddPayment(listenedInvoice.InvoiceId, notification.PaidAt.Value, new LightningLikePaymentData()
|
||||||
{
|
{
|
||||||
BOLT11 = notification.PaymentRequest,
|
BOLT11 = notification.BOLT11,
|
||||||
Amount = notification.MilliSatoshi
|
Amount = notification.Amount
|
||||||
}, network.CryptoCode, accounted: true);
|
}, network.CryptoCode, accounted: true);
|
||||||
if(payment != null)
|
if(payment != null)
|
||||||
_Aggregator.Publish(new InvoiceEvent(listenedInvoice.InvoiceId, 1002, "invoice_receivedPayment"));
|
_Aggregator.Publish(new InvoiceEvent(listenedInvoice.InvoiceId, 1002, "invoice_receivedPayment"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ChargeClient GetChargeClient(LightningSupportedPaymentMethod supportedPaymentMethod, BTCPayNetwork network)
|
private static ILightningInvoiceClient GetChargeClient(LightningSupportedPaymentMethod supportedPaymentMethod, BTCPayNetwork network)
|
||||||
{
|
{
|
||||||
return new ChargeClient(supportedPaymentMethod.GetLightningChargeUrl(true), network.NBitcoinNetwork);
|
return new ChargeClient(supportedPaymentMethod.GetLightningChargeUrl(true), network.NBitcoinNetwork);
|
||||||
}
|
}
|
Loading…
Add table
Reference in a new issue