mirror of
https://github.com/aljazceru/btcpayserver.git
synced 2025-12-19 06:54:19 +01:00
Simplify LND implementation
This commit is contained in:
@@ -15,12 +15,12 @@ namespace BTCPayServer.Tests.Lnd
|
||||
this._Parent = serverTester;
|
||||
var url = serverTester.GetEnvironment(environmentName, defaultValue);
|
||||
|
||||
Swagger = LndSwaggerClientCustomHttp.Create(new Uri(url), network);
|
||||
Swagger = new LndSwaggerClient(new LndRestSettings(new Uri(url)));
|
||||
Client = new LndInvoiceClient(Swagger);
|
||||
P2PHost = _Parent.GetEnvironment(environmentName + "_HOST", defaultHost);
|
||||
}
|
||||
|
||||
public LndSwaggerClientCustomHttp Swagger { get; set; }
|
||||
public LndSwaggerClient Swagger { get; set; }
|
||||
public LndInvoiceClient Client { get; set; }
|
||||
public string P2PHost { get; }
|
||||
}
|
||||
|
||||
@@ -25,16 +25,16 @@ namespace BTCPayServer.Tests.Lnd
|
||||
this.output = output;
|
||||
initializeEnvironment();
|
||||
|
||||
MerchantLnd = LndSwaggerClientCustomHttp.Create(new Uri("http://127.0.0.1:53280"), Network.RegTest);
|
||||
MerchantLnd = new LndSwaggerClient(new LndRestSettings(new Uri("http://127.0.0.1:53280")));
|
||||
InvoiceClient = new LndInvoiceClient(MerchantLnd);
|
||||
|
||||
CustomerLnd = LndSwaggerClientCustomHttp.Create(new Uri("http://127.0.0.1:53281"), Network.RegTest);
|
||||
CustomerLnd = new LndSwaggerClient(new LndRestSettings(new Uri("http://127.0.0.1:53281")));
|
||||
}
|
||||
|
||||
private LndSwaggerClientCustomHttp MerchantLnd { get; set; }
|
||||
private LndSwaggerClient MerchantLnd { get; set; }
|
||||
private LndInvoiceClient InvoiceClient { get; set; }
|
||||
|
||||
private LndSwaggerClientCustomHttp CustomerLnd { get; set; }
|
||||
private LndSwaggerClient CustomerLnd { get; set; }
|
||||
|
||||
[Fact]
|
||||
public async Task GetInfo()
|
||||
|
||||
@@ -521,7 +521,7 @@ namespace BTCPayServer.Tests
|
||||
Assert.Equal(lndUri, conn.ToString());
|
||||
Assert.Equal(LightningConnectionType.LndREST, conn.ConnectionType);
|
||||
Assert.Equal(macaroon, Encoders.Hex.EncodeData(conn.Macaroon));
|
||||
Assert.Equal(tls, Encoders.Hex.EncodeData(conn.Tls));
|
||||
Assert.Equal(tls, Encoders.Hex.EncodeData(conn.Tls.RawData));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
@@ -30,8 +30,11 @@ namespace BTCPayServer.Payments.Lightning
|
||||
}
|
||||
else if (connString.ConnectionType == LightningConnectionType.LndREST)
|
||||
{
|
||||
var swagger = LndSwaggerClientCustomHttp.Create(connString.BaseUri, network, connString.Tls, connString.Macaroon);
|
||||
return new LndInvoiceClient(swagger);
|
||||
return new LndInvoiceClient(new LndSwaggerClient(new LndRestSettings(connString.BaseUri)
|
||||
{
|
||||
Macaroon = connString.Macaroon,
|
||||
TLS = connString.Tls
|
||||
}));
|
||||
}
|
||||
else
|
||||
throw new NotSupportedException($"Unsupported connection string for lightning server ({connString.ConnectionType})");
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
@@ -197,11 +198,11 @@ namespace BTCPayServer.Payments.Lightning
|
||||
{
|
||||
var tls = Take(keyValues, "tls");
|
||||
if (tls != null)
|
||||
result.Tls = Encoder.DecodeData(tls);
|
||||
result.Tls = new X509Certificate2(Encoder.DecodeData(tls));
|
||||
}
|
||||
catch
|
||||
{
|
||||
error = $"The key 'tls' format should be in hex";
|
||||
error = $"The key 'tls' should be the X509 certificate in hex";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -301,7 +302,7 @@ namespace BTCPayServer.Payments.Lightning
|
||||
private set;
|
||||
}
|
||||
public byte[] Macaroon { get; set; }
|
||||
public byte[] Tls { get; set; }
|
||||
public X509Certificate2 Tls { get; set; }
|
||||
|
||||
public Uri ToUri(bool withCredentials)
|
||||
{
|
||||
@@ -350,7 +351,7 @@ namespace BTCPayServer.Payments.Lightning
|
||||
}
|
||||
if (Tls != null)
|
||||
{
|
||||
builder.Append($";tls={Encoder.EncodeData(Tls)}");
|
||||
builder.Append($";tls={Encoder.EncodeData(Tls.RawData)}");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -19,9 +19,11 @@ namespace BTCPayServer.Payments.Lightning.Lnd
|
||||
{
|
||||
public LndSwaggerClient _rpcClient;
|
||||
|
||||
public LndInvoiceClient(LndSwaggerClient rpcClient)
|
||||
public LndInvoiceClient(LndSwaggerClient swaggerClient)
|
||||
{
|
||||
_rpcClient = rpcClient;
|
||||
if (swaggerClient == null)
|
||||
throw new ArgumentNullException(nameof(swaggerClient));
|
||||
_rpcClient = swaggerClient;
|
||||
}
|
||||
|
||||
public async Task<LightningInvoice> CreateInvoice(LightMoney amount, string description, TimeSpan expiry,
|
||||
|
||||
@@ -16,102 +16,53 @@ using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace BTCPayServer.Payments.Lightning.Lnd
|
||||
{
|
||||
public class LndSwaggerClientCustomHttp : LndSwaggerClient, IDisposable
|
||||
public class LndRestSettings
|
||||
{
|
||||
protected LndSwaggerClientCustomHttp(string baseUrl, HttpClient httpClient)
|
||||
: base(baseUrl, httpClient)
|
||||
public LndRestSettings()
|
||||
{
|
||||
_HttpClient = httpClient;
|
||||
|
||||
}
|
||||
public LndRestSettings(Uri uri)
|
||||
{
|
||||
Uri = uri;
|
||||
}
|
||||
public Uri Uri { get; set; }
|
||||
public X509Certificate2 TLS { get; set; }
|
||||
public byte[] Macaroon { get; set; }
|
||||
}
|
||||
|
||||
private HttpClient _HttpClient;
|
||||
|
||||
public void Dispose()
|
||||
public partial class LndSwaggerClient
|
||||
{
|
||||
_HttpClient.Dispose();
|
||||
}
|
||||
|
||||
//
|
||||
public static LndSwaggerClientCustomHttp Create(Uri uri, Network network, byte[] tlsCertificate = null, byte[] grpcMacaroon = null)
|
||||
public LndSwaggerClient(LndRestSettings settings)
|
||||
: this(settings.Uri.AbsoluteUri.TrimEnd('/'), CreateHttpClient(settings))
|
||||
{
|
||||
var factory = new HttpClientFactoryForLnd(tlsCertificate, grpcMacaroon);
|
||||
var httpClient = factory.Generate();
|
||||
|
||||
var swagger = new LndSwaggerClientCustomHttp(uri.ToString().TrimEnd('/'), httpClient);
|
||||
swagger.HttpClientFactory = factory;
|
||||
|
||||
return swagger;
|
||||
_Settings = settings;
|
||||
}
|
||||
}
|
||||
|
||||
internal class HttpClientFactoryForLnd
|
||||
{
|
||||
public HttpClientFactoryForLnd(byte[] tlsCertificate = null, byte[] grpcMacaroon = null)
|
||||
{
|
||||
TlsCertificate = tlsCertificate;
|
||||
GrpcMacaroon = grpcMacaroon;
|
||||
}
|
||||
|
||||
public byte[] TlsCertificate { get; set; }
|
||||
public byte[] GrpcMacaroon { get; set; }
|
||||
|
||||
public HttpClient Generate()
|
||||
{
|
||||
var httpClient = new HttpClient(GetCertificate(TlsCertificate));
|
||||
|
||||
if (GrpcMacaroon != null)
|
||||
{
|
||||
var macaroonHex = BitConverter.ToString(GrpcMacaroon).Replace("-", "", StringComparison.InvariantCulture);
|
||||
httpClient.DefaultRequestHeaders.Add("Grpc-Metadata-macaroon", macaroonHex);
|
||||
}
|
||||
|
||||
return httpClient;
|
||||
}
|
||||
|
||||
private static HttpClientHandler GetCertificate(byte[] certFile)
|
||||
LndRestSettings _Settings;
|
||||
private static HttpClient CreateHttpClient(LndRestSettings settings)
|
||||
{
|
||||
var handler = new HttpClientHandler
|
||||
{
|
||||
SslProtocols = SslProtocols.Tls12
|
||||
};
|
||||
if (certFile == null)
|
||||
|
||||
var expectedCertificate = settings.TLS;
|
||||
if (expectedCertificate != null)
|
||||
{
|
||||
handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
|
||||
return handler;
|
||||
}
|
||||
|
||||
// if certificate is not null, try with custom accepting logic
|
||||
X509Certificate2 clientCertificate = null;
|
||||
if (certFile != null)
|
||||
clientCertificate = new X509Certificate2(certFile);
|
||||
|
||||
handler.ServerCertificateCustomValidationCallback = (request, cert, chain, errors) =>
|
||||
{
|
||||
const SslPolicyErrors unforgivableErrors =
|
||||
SslPolicyErrors.RemoteCertificateNotAvailable |
|
||||
SslPolicyErrors.RemoteCertificateNameMismatch;
|
||||
|
||||
if ((errors & unforgivableErrors) != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (clientCertificate == null)
|
||||
return true;
|
||||
|
||||
X509Certificate2 remoteRoot = chain.ChainElements[chain.ChainElements.Count - 1].Certificate;
|
||||
var res = clientCertificate.RawData.SequenceEqual(remoteRoot.RawData);
|
||||
|
||||
return res;
|
||||
return expectedCertificate.RawData.SequenceEqual(remoteRoot.RawData);
|
||||
};
|
||||
|
||||
return handler;
|
||||
}
|
||||
}
|
||||
|
||||
public partial class LndSwaggerClient
|
||||
var httpClient = new HttpClient(handler);
|
||||
if (settings.Macaroon != null)
|
||||
{
|
||||
internal HttpClientFactoryForLnd HttpClientFactory { get; set; }
|
||||
var macaroonHex = BitConverter.ToString(settings.Macaroon).Replace("-", "", StringComparison.InvariantCulture);
|
||||
httpClient.DefaultRequestHeaders.Add("Grpc-Metadata-macaroon", macaroonHex);
|
||||
}
|
||||
return httpClient;
|
||||
}
|
||||
|
||||
public TaskCompletionSource<LnrpcInvoice> InvoiceResponse = new TaskCompletionSource<LnrpcInvoice>();
|
||||
public TaskCompletionSource<LndSwaggerClient> SubscribeLost = new TaskCompletionSource<LndSwaggerClient>();
|
||||
@@ -122,7 +73,7 @@ namespace BTCPayServer.Payments.Lightning.Lnd
|
||||
var urlBuilder = new StringBuilder();
|
||||
urlBuilder.Append(BaseUrl).Append("/v1/invoices/subscribe");
|
||||
|
||||
using (var client = HttpClientFactory.Generate())
|
||||
using (var client = CreateHttpClient(_Settings))
|
||||
{
|
||||
client.Timeout = TimeSpan.FromMilliseconds(Timeout.Infinite);
|
||||
|
||||
Reference in New Issue
Block a user