From 69050f7a5624165750e017d007cc44aef0fa9f75 Mon Sep 17 00:00:00 2001 From: lepipele Date: Sat, 28 Apr 2018 12:49:56 -0500 Subject: [PATCH] Lnd sends some integers as strings, testing invoice creation --- BTCPayServer.Tests/UnitTestPeusa.cs | 12 ++++++ .../Payments/Lightning/Lnd/LndClient.cs | 41 +++++++++++++++---- .../Lightning/Lnd/LndSwaggerClient.cs | 20 ++++----- 3 files changed, 56 insertions(+), 17 deletions(-) diff --git a/BTCPayServer.Tests/UnitTestPeusa.cs b/BTCPayServer.Tests/UnitTestPeusa.cs index 48ed0f5d6..d53566fcb 100644 --- a/BTCPayServer.Tests/UnitTestPeusa.cs +++ b/BTCPayServer.Tests/UnitTestPeusa.cs @@ -67,5 +67,17 @@ namespace BTCPayServer.Tests Console.WriteLine("Address: " + res.Address); } + + [Fact] + public async Task LndCreateInvoice() + { + var tls = File.ReadAllBytes(@"c:\Users\newdawn\AppData\Local\Lnd\tls.cert"); + var macroon = File.ReadAllBytes(@"c:\Users\newdawn\AppData\Local\Lnd\admin.macaroon"); + + var lnd = new LndClient(new Uri("https://127.0.0.1:8080"), Network.RegTest, tls, macroon); + var res = await lnd.CreateInvoice(10000, "Hello world", TimeSpan.FromSeconds(3600)); + + Console.WriteLine("Result: "+ res.ToJson()); + } } } diff --git a/BTCPayServer/Payments/Lightning/Lnd/LndClient.cs b/BTCPayServer/Payments/Lightning/Lnd/LndClient.cs index 522e01225..342f1bd73 100644 --- a/BTCPayServer/Payments/Lightning/Lnd/LndClient.cs +++ b/BTCPayServer/Payments/Lightning/Lnd/LndClient.cs @@ -26,13 +26,17 @@ namespace BTCPayServer.Payments.Lightning.Lnd private HttpClient _HttpClient; private LndSwaggerClient _Decorator; - public async Task CreateInvoice(LightMoney amount, string description, TimeSpan expiry, CancellationToken cancellation = default(CancellationToken)) + public async Task CreateInvoice(LightMoney amount, string description, TimeSpan expiry, + CancellationToken cancellation = default(CancellationToken)) { + var strAmount = ConvertInv.ToString(amount.ToUnit(LightMoneyUnit.Satoshi)); + var strExpiry = ConvertInv.ToString(expiry.TotalSeconds); + // lnd requires numbers sent as strings. don't ask var resp = await _Decorator.AddInvoiceAsync(new LnrpcInvoice { - Value = (long)amount.ToDecimal(LightMoneyUnit.Satoshi), + Value = strAmount, Memo = description, - Expiry = (long)expiry.TotalSeconds + Expiry = strExpiry }); var invoice = new LightningInvoice @@ -101,17 +105,40 @@ namespace BTCPayServer.Payments.Lightning.Lnd Status = "unpaid" }; - if (resp.Settle_date.HasValue) + if (resp.Settle_date != null) { - invoice.PaidAt = DateTimeOffset.FromUnixTimeSeconds(resp.Settle_date.Value); + invoice.PaidAt = DateTimeOffset.FromUnixTimeSeconds(ConvertInv.ToInt64(resp.Settle_date)); invoice.Status = "paid"; } - else if (DateTimeOffset.FromUnixTimeSeconds(resp.Creation_date.Value + resp.Expiry.Value) > DateTimeOffset.UtcNow) + else { - invoice.Status = "expired"; + var invoiceExpiry = ConvertInv.ToInt64(resp.Creation_date) + ConvertInv.ToInt64(resp.Expiry); + if (DateTimeOffset.FromUnixTimeSeconds(invoiceExpiry) > DateTimeOffset.UtcNow) + { + invoice.Status = "expired"; + } } return invoice; } + + // Invariant culture conversion + public static class ConvertInv + { + public static long ToInt64(string str) + { + return Convert.ToInt64(str, CultureInfo.InvariantCulture.NumberFormat); + } + + public static string ToString(decimal d) + { + return d.ToString(CultureInfo.InvariantCulture); + } + + public static string ToString(double d) + { + return d.ToString(CultureInfo.InvariantCulture); + } + } } internal class HttpClientFactoryForLnd diff --git a/BTCPayServer/Payments/Lightning/Lnd/LndSwaggerClient.cs b/BTCPayServer/Payments/Lightning/Lnd/LndSwaggerClient.cs index 75246c8d8..91c3fe157 100644 --- a/BTCPayServer/Payments/Lightning/Lnd/LndSwaggerClient.cs +++ b/BTCPayServer/Payments/Lightning/Lnd/LndSwaggerClient.cs @@ -5573,15 +5573,15 @@ namespace BTCPayServer.Payments.Lightning.Lnd private byte[] _receipt; private byte[] _r_preimage; private byte[] _r_hash; - private long? _value; + private string _value; private bool? _settled; - private long? _creation_date; - private long? _settle_date; + private string _creation_date; + private string _settle_date; private string _payment_request; private byte[] _description_hash; - private long? _expiry; + private string _expiry; private string _fallback_addr; - private int? _cltv_expiry; + private string _cltv_expiry; private System.Collections.ObjectModel.ObservableCollection _route_hints; private bool? _private; @@ -5647,7 +5647,7 @@ namespace BTCPayServer.Payments.Lightning.Lnd } [Newtonsoft.Json.JsonProperty("value", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] - public long? Value + public string Value { get { return _value; } set @@ -5675,7 +5675,7 @@ namespace BTCPayServer.Payments.Lightning.Lnd } [Newtonsoft.Json.JsonProperty("creation_date", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] - public long? Creation_date + public string Creation_date { get { return _creation_date; } set @@ -5689,7 +5689,7 @@ namespace BTCPayServer.Payments.Lightning.Lnd } [Newtonsoft.Json.JsonProperty("settle_date", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] - public long? Settle_date + public string Settle_date { get { return _settle_date; } set @@ -5740,7 +5740,7 @@ namespace BTCPayServer.Payments.Lightning.Lnd /// / Payment request expiry time in seconds. Default is 3600 (1 hour). [Newtonsoft.Json.JsonProperty("expiry", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] - public long? Expiry + public string Expiry { get { return _expiry; } set @@ -5770,7 +5770,7 @@ namespace BTCPayServer.Payments.Lightning.Lnd /// / Delta to use for the time-lock of the CLTV extended to the final hop. [Newtonsoft.Json.JsonProperty("cltv_expiry", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] - public int? Cltv_expiry + public string Cltv_expiry { get { return _cltv_expiry; } set